Forced transmit by threshold is not working



  • Hello,

    So I combined 2 sketches and I'm having some problems.
    The temperature and Humidity thresholds works great.
    But my Lux threshold does not work as it should.
    I really can't pin point what I am doing wrong!

    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    #define MY_SIGNING_SOFT
    #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
    #define MY_SIGNING_REQUEST_SIGNATURES
    // Define a static node address, remove if you want auto address assignment
    #define MY_NODE_ID 4
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    // Enable to support OTA for this node (needs DualOptiBoot boot-loader to fully work)
    //#define MY_OTA_FIRMWARE_FEATURE
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <Wire.h>
    #include <SI7021.h>
    #include <BH1750.h>
    #ifndef MY_OTA_FIRMWARE_FEATURE
    #include "drivers/SPIFlash/SPIFlash.cpp"
    #endif
    #include <EEPROM.h>  
    #include <RunningAverage.h>
    //#include <avr/power.h>
    
    // Uncomment the line below, to transmit battery voltage as a normal sensor value
    //#define BATT_SENSOR    199
    
    #define RELEASE "1.4"
    
    #define AVERAGES 2
    
    // Child sensor ID's
    #define CHILD_ID_TEMP  1
    #define CHILD_ID_HUM   0
    #define CHILD_ID_LIGHT 2
    // How many milli seconds between each measurement
    #define MEASURE_INTERVAL 3000
    
    // How many milli seconds should we wait for OTA?
    #define OTA_WAIT_PERIOD 300
    
    // FORCE_TRANSMIT_INTERVAL, this number of times of wakeup, the sensor is forced to report all values to the controller
    #define FORCE_TRANSMIT_INTERVAL 30 
    
    // When MEASURE_INTERVAL is 60000 and FORCE_TRANSMIT_INTERVAL is 30, we force a transmission every 30 minutes.
    // Between the forced transmissions a tranmission will only occur if the measured value differs from the previous measurement
    
    // HUMI_TRANSMIT_THRESHOLD tells how much the humidity should have changed since last time it was transmitted. Likewise with
    // TEMP_TRANSMIT_THRESHOLD for temperature threshold.
    #define HUMI_TRANSMIT_THRESHOLD 10.5
    #define TEMP_TRANSMIT_THRESHOLD 10.1
    #define LUX_TRANSMIT_THRESHOLD 200.0
    
    // Pin definitions
    #define TEST_PIN       A0
    #define LED_PIN        A2
    
    
    BH1750 lightSensor;
    SI7021 humiditySensor;
    SPIFlash flash(8, 0x1F65);
    
    // Sensor messages
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgLightLevel(CHILD_ID_LIGHT, V_LEVEL);
    
    // Global settings
    int measureCount = 0;
    boolean isMetric = true;
    boolean highfreq = true;
    boolean transmission_occured = false;
    
    // Storage of old measurements
    float lastTemperature = -100;
    int lastHumidity = -100;
    uint16_t lastLux = -100;
    RunningAverage raHum(AVERAGES);
    
    /****************************************************
     *
     * Setup code 
     *
     ****************************************************/
    void setup() {
    
      pinMode(LED_PIN, OUTPUT);
      digitalWrite(LED_PIN, LOW);
    
      Serial.begin(115200);
      Serial.print(F("Sensebender Micro FW "));
      Serial.print(RELEASE);
      Serial.flush();
    
      // First check if we should boot into test mode
    
      pinMode(TEST_PIN,INPUT);
      digitalWrite(TEST_PIN, HIGH); // Enable pullup
      if (!digitalRead(TEST_PIN)) testMode();
    
      digitalWrite(TEST_PIN,LOW);
    
      digitalWrite(LED_PIN, HIGH); 
    
      humiditySensor.begin();
    
      digitalWrite(LED_PIN, LOW);
    
      Serial.flush();
      Serial.println(F(" - Online!"));
    
      isMetric = getConfig().isMetric;
      Serial.print(F("isMetric: ")); Serial.println(isMetric);
      raHum.clear();
      sendTempHumidityMeasurements(false);
    
      lightSensor.begin();
      
    
    }
    
    void presentation()  {
      sendSketchInfo("Sensebender Micro", RELEASE);
    
      present(CHILD_ID_TEMP,S_TEMP);
      present(CHILD_ID_HUM,S_HUM);
      present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
    }
    
    
    /***********************************************
     *
     *  Main loop function
     *
     ***********************************************/
    void loop() {
    
      measureCount ++;
      bool forceTransmit = false;
      transmission_occured = false;
    
    
      if (measureCount > FORCE_TRANSMIT_INTERVAL) { // force a transmission
        forceTransmit = true; 
        measureCount = 0;
      }
      
      sendTempHumidityMeasurements(forceTransmit);
    /*  if (sendBattery > 60) 
      {
         sendBattLevel(forceTransmit); // Not needed to send battery info that often
         sendBattery = 0;
      }*/
    
      sleep(MEASURE_INTERVAL);  
    }
    
    
    /*********************************************
     *
     * Sends temperature and humidity from Si7021 sensor
     *
     * Parameters
     * - force : Forces transmission of a value (even if it's the same as previous measurement)
     *
     *********************************************/
    void sendTempHumidityMeasurements(bool force)
    {
      bool tx = force;
    
      // Read light level
      uint16_t lux = lightSensor.readLightLevel();
      uint16_t diffLux = abs(lastLux - lux);
      Serial.print(F("TempLux :"));
      Serial.println(diffLux);
      
      si7021_env data = humiditySensor.getHumidityAndTemperature();
    
      raHum.addValue(data.humidityPercent);
    
      float diffTemp = abs(lastTemperature - (isMetric ? data.celsiusHundredths : data.fahrenheitHundredths)/100.0);
      float diffHum = abs(lastHumidity - raHum.getAverage());
    
      Serial.print(F("TempDiff :"));Serial.println(diffTemp);
      Serial.print(F("HumDiff  :"));Serial.println(diffHum); 
    
      if (isnan(diffHum)) tx = true; 
      if (diffTemp > TEMP_TRANSMIT_THRESHOLD) tx = true;
      if (diffHum > HUMI_TRANSMIT_THRESHOLD) tx = true;
      if (diffLux < LUX_TRANSMIT_THRESHOLD) tx = true;
      
      if (tx) {
        measureCount = 0;
        float temperature = (isMetric ? data.celsiusHundredths : data.fahrenheitHundredths) / 100.0;
    
        int humidity = data.humidityPercent;
        Serial.print("T: ");Serial.println(temperature);
        Serial.print("H: ");Serial.println(humidity);
        Serial.print(F("TempLux :"));
        Serial.println(diffLux);
        send(msgTemp.set(temperature,1));
        send(msgHum.set(humidity));
        lastTemperature = temperature;
        lastHumidity = humidity;
        send(msgLightLevel.set(lux));  // Send tripped value to gw
        lastLux = lux;
        transmission_occured = true;
       
      }
    }
    
    /********************************************
     *
     * Sends battery information (battery percentage)
     *
     * Parameters
     * - force : Forces transmission of a value
     *
     *******************************************/
    
    
    /*******************************************
     *
     * Internal battery ADC measuring 
     *
     *******************************************/
    
    
    /****************************************************
     *
     * Verify all peripherals, and signal via the LED if any problems.
     *
     ****************************************************/
    void testMode()
    {
      uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
      uint8_t ret_code;
      byte tests = 0;
    
      digitalWrite(LED_PIN, HIGH); // Turn on LED.
      Serial.println(F(" - TestMode"));
      Serial.println(F("Testing peripherals!"));
      Serial.flush();
      Serial.print(F("-> SI7021 : ")); 
      Serial.flush();
    
      if (humiditySensor.begin()) 
      {
        Serial.println(F("ok!"));
        tests ++;
      }
      else
      {
        Serial.println(F("failed!"));
      }
      Serial.flush();
    
      Serial.print(F("-> Flash : "));
      Serial.flush();
      if (flash.initialize())
      {
        Serial.println(F("ok!"));
        tests ++;
      }
      else
      {
        Serial.println(F("failed!"));
      }
      Serial.flush();
    
    
      
    
      }
    

    The sketch itself is working alright and reads/sends the information.
    The humidity/Temp waits until the threshold is reached before sending the message.
    But my Lyx sends it really random and not accompanied by the threshold I've set.
    Are the tags wrong?

    Also, since I am a newb, in the sketch there is this row:
    SPIFlash flash(8, 0x1F65);
    What does it do?
    I figured it sets the I2C adress for the SI7021 chip?
    However, since I have not set any I2C adress for the BH1750, is this done within the library "#include <BH1750.h>"?


  • Mod

    @Nicklas-Starkel I think all you need to change is the < to > in

    if (diffLux < LUX_TRANSMIT_THRESHOLD) tx = true;
    

    According to the SI7021 datasheet the i2c address is 0x40.

    According to the BH1750 datasheet, the i2c address is either 0x5C or 0x23 depending on whether the ADDR pin is set high or low.

    The libraries know the address, so there is no need to specify the address in your code.
    Here is the address for SI7021 https://github.com/LowPowerLab/SI7021/blob/c5ce0922ef16df0a41fc231ce19b6cf80efba4fc/SI7021.cpp#L15
    Here is the address that the BH1750 library uses: https://github.com/claws/BH1750/blob/d314b43d49d29ffabb9e6259c4f9462832575746/BH1750.h#L28

    SPIFlash flash(8, 0x1F65); has nothing to do with any of them 🙂 It initializes the flash for OTA.

    For next time, please include the serial debug output if you can. The debug output is usually very helpful when troubleshooting and including it can save a lot of time.



  • @mfalkvidd thanks!

    I actually found the problem while messing around with different settings.
    I changed 'uint16_t' to regular 'int' and it started working!
    Now, both should have worked (I guess by doing a quick google on uint16_t).
    So as to why how what.. im perplexed.
    Thanks for looking at the code 🙂


Log in to reply
 

Suggested Topics

18
Online

11.2k
Users

11.1k
Topics

112.5k
Posts