Node not sending updates, probably some problem with my sketch



  • Hey there,

    I have a node which is doing strange things. I tested it with a sketch with fixed update time and it works well. I also have an enhanced version which checks for the need of an update and only sends messages as needed. But the new sketch only sends the data once after reboot and goes silent forever... maybe I'm overlooking something in my sketch... I hope someone can help.

    working sketch sending every 2.5 min:

    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <Wire.h>
    #include <SI7021.h>
    #include <MySensors.h>
    #include <SPI.h>
    #include <readVcc.h>
    
    int MIN_V = 1800; // empty voltage (0%)
    int MAX_V = 3200; // full voltage (100%)
    
    SI7021 sensor;
    
    #define CHILD_ID_HUM 2
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_V 3
    
    unsigned long SLEEP_TIME = 2.5*60*1000; // Sleep time between reads (in milliseconds)
    int oldBatteryPcnt = 0;
    float lastTemp;
    float lastHum;
    
    //Messages
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgV(CHILD_ID_V, V_VAR1);
    
    
    void setup() {
        //Serial.begin(9600);
        delay(100);
        sensor.begin();
          
    }
    
    void presentation() {
      // Send the Sketch Version Information to the Gateway
          sendSketchInfo("SI7021", "1.0");
          delay(50);
          present(CHILD_ID_HUM, S_HUM);
          delay(50);
          present(CHILD_ID_TEMP, S_TEMP);
          delay(50);
          present(CHILD_ID_V, S_TEMP);      
    }
    
    void loop() {
    
        // get humidity and temperature in one shot, saves power because sensor takes temperature when doing humidity anyway
        si7021_env data = sensor.getHumidityAndTemperature();
        Serial.print("Temperatur: ");
        Serial.print(data.celsiusHundredths);
        Serial.print(" Luftfeuchtigkeit: ");
        Serial.println(data.humidityPercent);
        float temperature = data.celsiusHundredths/100.0;
        send(msgTemp.set(temperature, 1));
        delay(50);
        send(msgHum.set(data.humidityPercent, 1));
        delay(50);
    
      // Measure battery
      float batteryV = readVcc();
      int batteryPcnt = (((batteryV - MIN_V) / (MAX_V - MIN_V)) * 100 );
      if (batteryPcnt > 100) {
        batteryPcnt = 100;
      }
    
         sendBatteryLevel(batteryPcnt);
         delay(10);
         send(msgV.set(batteryV,1));
         oldBatteryPcnt = batteryPcnt;
        sleep(SLEEP_TIME); //sleep for: sleepTime 
    }
    

    Updated to flexible update intervall, not working anymore:

    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <Wire.h>
    #include <SI7021.h>
    #include <MySensors.h>
    #include <SPI.h>
    #include <readVcc.h>
    
    int MIN_V = 1800; // empty voltage (0%)
    int MAX_V = 3200; // full voltage (100%)
    
    SI7021 sensor;
    
    #define CHILD_ID_HUM 2
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_V 3
    
    unsigned long SLEEP_TIME = 2 * 60 * 1000; // Sleep time between reads (in milliseconds)
    int oldBatteryPcnt = 0;
    float lastTemp;
    float lastHum;
    boolean sendValues = false;
    int Loop = 0;
    
    //Messages
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgV(CHILD_ID_V, V_VAR1);
    
    
    void setup() {
      delay(100);
      sensor.begin();
    }
    
    void presentation() {
      // Send the Sketch Version Information to the Gateway
      sendSketchInfo("Aussensensor", "1.0");
      delay(50);
      present(CHILD_ID_HUM, S_HUM);
      delay(50);
      present(CHILD_ID_TEMP, S_TEMP);
      delay(50);
      present(CHILD_ID_V, S_TEMP);
    }
    
    void loop() {
    
      si7021_env data = sensor.getHumidityAndTemperature();
      float temperature = data.celsiusHundredths / 100.0;
      if ((temperature > lastTemp + 0.2) or (temperature < lastTemp - 0.2)) {
        sendValues = true;
      }
      float humidity = data.humidityPercent;
      if ((humidity > lastHum + 5) or (humidity < lastHum - 5)) {
        sendValues = true;
      }
    
    
      // Measure battery
      float batteryV = readVcc();
      int batteryPcnt = (((batteryV - MIN_V) / (MAX_V - MIN_V)) * 100 );
      if (batteryPcnt > 100) {
        batteryPcnt = 100;
      }
      if ((batteryPcnt < oldBatteryPcnt) or (batteryPcnt > oldBatteryPcnt + 3)) {
        sendValues = true;
      }
    
      Loop++;
    
      if (Loop > 15) {
        sendValues = true;
      }
    
    
      if (sendValues) {
        send(msgTemp.set(temperature, 1));
        lastTemp = temperature;
        delay(50);
        send(msgHum.set(humidity, 1));
        lastHum = humidity;
        delay(50);
        sendBatteryLevel(batteryPcnt);
        delay(50);
        send(msgV.set(batteryV, 1));
        oldBatteryPcnt = batteryPcnt;
        Loop = 0;
        sendValues=false;
      }
    
      sleep(SLEEP_TIME); //sleep for: sleepTime
    }
    


  • Hi,

    • Do you actually want to put it to sleep and what does that imply? Is the nrf24 switched off? I'd try it with delay() and see if that influences anything.
    • Is the serial monitor dead too? Put some debug messages after the sleep() function
    • This code uses sensor.sleep() instead of sleep(), dunno if that makes a difference.

    Good luck,
    pansen



  • well it does not seem logic to me, but I kind of found the problem. It's within this line:

    unsigned long SLEEP_TIME = 2 * 60 * 1000; // Sleep time between reads (in milliseconds)
    

    If I change the 2 to let's say 2.1 it works. Maybe a conversion problem with integer and long? Well for me that's ok and solved, but maybe someone else in future needs this info...


  • Contest Winner

    @Anduril why do you use a variable?
    it is easier to use a define like this, a define is calculated on compile time and does not take any memory space

    // Sleep time between reads (in milliseconds)
    #define SLEEP_TIME (2 * 60 * 1000)
    

  • Hero Member

    @BartE This gets to be C++ purist but:

    const unsigned long SLEEP_TIME = 2 * 60 * 1000 UL ; // Sleep time between reads (in milliseconds)
    

    would be the cleanest way to do it. The compiler will then be aware of the constant type (unsigned long) on the left side of the '='. the 'UL' on the right side indicates that it has to calculate with "long" arithmetic. A good compiler will not allocate extra (RAM) storage for const types.

    In the case of @Anduril the usage of 2.1 instead of 2 instructed the compiler to work in 'float' which is by definition long enough to contain the value of 120,000 (2 * 60 * 1000) but uses a huge overhead (float arithmetic).



  • @AWI: so in this case SLEEP_TIME actually overflows?


  • Hero Member

    @pansen something like that. The value overflows and then gets assigned.


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.