ESP8266 Gateway with local sensors stuck in loop



  • Hi Guys,

    I previously had this sketch working fine with a local sensor on Arduino Uno. I want to move to NodeMCU for the sake of simplicity.

    I have loaded the sketch that worked previosuly on the Ardunio onto the NodeMCU and it is stuck in the infinite loop. I suspect this has something to do with sleep not working?

    Here is the code:

    //Set NODE ID
    #define MY_NODE_ID 0
    
    // 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
    
    // Enables and select radio type (if attached)
    //#define MY_RADIO_RF24
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    
    #define MY_GATEWAY_MQTT_CLIENT
    #define MY_GATEWAY_ESP8266
    
    // Set this node's subscribe and publish topic prefix
    #define MY_MQTT_PUBLISH_TOPIC_PREFIX "homeassistant-out"
    #define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "homeassistant-in"
    
    // Set MQTT client id
    #define MY_MQTT_CLIENT_ID "mysensors-1"
    
    // Enable these if your MQTT broker requires username/password
    #define MY_MQTT_USER "####"
    #define MY_MQTT_PASSWORD "#####"
    
    // Set WIFI SSID and password
    #define MY_WIFI_SSID "######"
    #define MY_WIFI_PASSWORD "######!"
    
    // Set the hostname for the WiFi Client. This is the hostname
    // passed to the DHCP server if not static.
    #define MY_HOSTNAME "KITCHEN_MQTT_GW"
    
    // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
    //#define MY_IP_ADDRESS 192,168,178,87
    
    // If using static ip you can define Gateway and Subnet address as well
    //#define MY_IP_GATEWAY_ADDRESS 192,168,178,1
    //#define MY_IP_SUBNET_ADDRESS 255,255,255,0
    
    // MQTT broker ip address.
    #define MY_CONTROLLER_IP_ADDRESS 192, 168, 87, 179
    
    //MQTT broker if using URL instead of ip address.
    // #define MY_CONTROLLER_URL_ADDRESS "test.mosquitto.org"
    
    // The MQTT broker port to to open
    #define MY_PORT 1883
    
    // Enable inclusion mode
    //#define MY_INCLUSION_MODE_FEATURE
    // Enable Inclusion mode button on gateway
    //#define MY_INCLUSION_BUTTON_FEATURE
    // Set inclusion mode duration (in seconds)
    //#define MY_INCLUSION_MODE_DURATION 60
    // Digital pin used for inclusion mode button
    //#define MY_INCLUSION_MODE_BUTTON_PIN D1
    
    // Set blinking period
    //#define MY_DEFAULT_LED_BLINK_PERIOD 300
    
    // Flash leds on rx/tx/err
    //#define MY_DEFAULT_ERR_LED_PIN 16  // Error led pin
    //#define MY_DEFAULT_RX_LED_PIN  16  // Receive led pin
    //#define MY_DEFAULT_TX_LED_PIN  16  // the PCB, on board LED
    
    #include <MySensors.h>
    
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID_PH_LOCAL 1   // Id of the sensor child
    
    // Initialize motion message
    MyMessage msg(CHILD_ID_PH_LOCAL, V_TRIPPED);
    
    void setup()
    {
      pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Kitchen Motion Sensor", "2.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_PH_LOCAL, S_MOTION);
    }
    
    void loop()
    {
      // Read digital motion value
      boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
            
      Serial.println(tripped);
      send(msg.set(tripped?"1":"0"));  // Send tripped value to gw 
    
      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
      sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    }
    

    Any help you anyone can provide would be greatly appreciated.

    Thank You!


  • Mod

    @ShadeX12 yyes you are correct. Esp8266 only supports sleeping by resetting the mcu, which means it would start fresh after every sleep (instead of continuing on he next line after sleep).



  • Thanks for the reply.

    I removed sleep and added wait instead. Now it just seems to output a sensor as tripped regardless of what is going on. It seems like it is not reading the state from the pin.

    void loop()
    {
    
      // Read digital motion value
      boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
            
      Serial.println(tripped);
      send(msg.set(tripped?"1":"0"));  // Send tripped value to gw 
    
      wait(5000);
    
    }
    

    Here is the serial output:

    143021 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    148086 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    153151 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    158216 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    163281 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    168346 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    173411 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    178476 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    183541 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    188606 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    193671 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    1
    198736 GWT:TPS:TOPIC=homeassistant-out/0/1/1/0/16,MSG SENT
    
    

    Any ideas?



  • After surfing around the web a bit I eventually came up with this:

    
    void loop() {
    
      long state = digitalRead(DIGITAL_INPUT_SENSOR);
        if(state == HIGH) {
          Serial.println("Motion detected!");
          send(msg.set("1"));
          delay(1000);
        }
        else {
          Serial.println("Motion absent!");
          send(msg.set("0"));
          delay(1000);
          }
    }
    

    This seems to be working fine.



  • Now you are sending the message every second, even if the state didn't change.
    If you check to the previous state, and then send when the state changed it would be more efficient



  • @ShadeX12
    Hello,

    maybe these links will provide the necessary background information to solve your problem:

    Basics about ESP8266 sleep modes:

    https://www.losant.com/blog/making-the-esp8266-low-powered-with-deep-sleep

    Extensive discussion of this topic:

    https://github.com/esp8266/Arduino/issues/1488

    Especially this citation might be interesting:

    "GPIO16 is connected to CH_DP for deepSleep.
    and pulled low during deepSleep.
    if CH_DP goes high the chip wakes up.
    for what reason the high signal comes from does not mater.
    can be the RTC timer or any other electrical stuff connected to CH_DP.
    so adding a pullup to CH_DP and a switch that is normally close to GPIO16 will work fine."

    Excellent summary, how to work with interrupts in general on the ESP8266:

    https://techtutorialsx.com/2016/12/11/esp8266-external-interrupts/

    Good luck with your project.

    Karl-Heinz


Log in to reply
 

Suggested Topics

  • 3
  • 6
  • 1
  • 5
  • 1
  • 2

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts