Binary sensor for production counting transmits false values



  • Hey guys,

    I am currently working on a project in our company where I would like to use NodeMCU to count produced parts and send the data via MQTT. The NodeMCU is attached to one of the pulse generators (e.g. a cutter or welder) and the NodeMCU receives that signal but it seems like it is counting too many signals (like doubling the real value) and I cannot figure out why.

    The highes frequency of pulses (produced parts) I have to deal with are about 2 - 3 per second.

    This is my simple binary sketch:

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
    #define MY_BAUD_RATE 9600
    
    #define MY_GATEWAY_MQTT_CLIENT
    #define MY_GATEWAY_ESP8266
    
    #define MCU_ID redacted
    
    // Set MQTT client id
    #define MY_MQTT_CLIENT_ID MCU_ID
    
    // Set this node's subscribe and publish topic prefix
    #define MY_MQTT_PUBLISH_TOPIC_PREFIX redacted
    #define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX redacted
    
    // Enable these if your MQTT broker requires username/password
    #define MY_MQTT_USER redacted
    #define MY_MQTT_PASSWORD redacted
    
    // Set WIFI SSID and password
    #define MY_ESP8266_SSID redacted
    #define MY_ESP8266_PASSWORD redacted
    
    // MQTT broker ip address.
    #define MY_CONTROLLER_URL_ADDRESS redacted
    
    // The MQTT broker port to to open
    #define MY_PORT 1883
    
    #include <ESP8266WiFi.h>
    #include <MySensors.h>
    #include <Bounce2.h>
    
    #define CHILD_ID 1
    #define BUTTON_PIN  3
    
    #define LEDRED 16
    #define LEDGREEN 0
    
    Bounce debouncer = Bounce(); 
    int oldValue=-1;
    
    MyMessage msg(CHILD_ID,V_STATUS);
    MyMessage msgCount(CHILD_ID,I_LOG_MESSAGE);
    MyMessage msgHeartbeat(CHILD_ID,I_HEARTBEAT_RESPONSE);
    
    int countHeartbeat = 0;
    
    void setup()   
    {
    
      // Setup the button
      pinMode(BUTTON_PIN,INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN,HIGH);
    
      // After setting up the button, setup debouncer
      debouncer.attach(BUTTON_PIN);
      debouncer.interval(5);
    
      countHeartbeat = 0;
    
      //Setup the Pulse LED
      pinMode(LEDRED, OUTPUT);
    
      //Setup the Status LED
      pinMode(LEDGREEN, OUTPUT);
      digitalWrite(LEDGREEN, HIGH);
    }
    
    void presentation() {
    
      sendSketchInfo(MCU_ID, "1.0");
      present(CHILD_ID, S_BINARY);
      //present(HEARTBEAT_ID, S_BINARY); 
    }
    
    
    //  Check if digital input has changed and send in new value
    void loop() 
    {
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
      countHeartbeat ++;
      if(countHeartbeat >= 1155000){
        //Serial.println("Heartbeat");
        send(msgHeartbeat.set(1));
        countHeartbeat = 0;
      }
      
      if (value != oldValue) {
         // Send in the new value
         send(msg.set(value==HIGH ? 0 : 1)); 
         oldValue = value;
         if ( value == 1) {
            //Serial.println("Off");
            digitalWrite(LEDRED, LOW);
            delay(30);
         } else {
            //Serial.println("On");
            digitalWrite(LEDRED, HIGH);
         }
         
      }
      //send(heartbeat.set(value==1));
    }
    

    I appreciate any hint or comment!



  • Am I missing something, or is there no real counting code on the node?

    If it's really like doubleing the real values, you may also count the "off" messages at the controller/receiver side.

    Additionally: If it's really something like 2-3 parts per second, it's 4-6 changes. So you may better choose a somehow longer interval for debouncing (15 or 20ms).



  • Thanks for your response. You are perfectly right. The counting happens on the server (counting the transmitted '1's coming via MQTT).



  • So you may first have a look how the message processing really is done at your server.

    In general I'd avoid that kind of signaliszing in an industrial environment. The ESP8266 isn't the most reliable kind of mcu to use and wifi for transmitting simple counter data causes a lot of unnecessary overlay. Use at least wires instead...
    You may also add some kind of plausibility check like adding a counter value to the node also and send count values to your server after longer periods (e.g. every 5 minutes). So you can compare what was sent from node and what had been received.



  • @rejoe2 Thanks, I actually have a counter but removed it from the code to keep it simple. It counts the pulses and sends the number for comparison and it matches actually. So the problem is at the beginning with the node "getting false pulses" from the machine. Any idea how that can be explained? 😞



  • @makin Ok if you're really sure the problem is located on the node, you may extend debouncing time as already proposed.
    I also saw other examples of debounced PINs issuing a "pinMode(buttonPin, INPUT_PULLUP);" in setup() instead of digital.write(HIGH). Could also be worth a try (in case this is valid for an ESP).



  • Can you describe the physical interface? Could you be receiving spurious signals or as suggested bouncing contacts?

    In my experience with industrial automation, the environment is very electrically noisy. One must include hardware components to protect the MCU from errors and electrical damage.

    Not sure where in the world you are located but in the Northern Hemisphere its winter and ESD is rampant.

    Can you add an LED blink to the MCU board so you can watch the "action" for a sanity check?



  • Mysensors is nice, but for your task with ESP2866 I can recommend ESPeasy.
    30 min and you are done.


Log in to reply
 

Suggested Topics

  • 3
  • 6
  • 6
  • 5
  • 2

36
Online

11.4k
Users

11.1k
Topics

112.6k
Posts