SensebenderMicro with two additional DS18b20



  • Dear experts, i have a problem with my sensebender micro with two additional DS18B20 Sensors. Since i upgraded the sketch from Version 1.5 to 2.1.1 the DS18b20 Sensors sends their temperature Values for about one hour or something like that and after this they did not send anymore. But the internal Temperature and Humidity Sensors (from Sensebender) does send the whole time... Can anybody helb me with this strange behavior? Here is my Sketch:

    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Define a static node address, remove if you want auto address assignment
    #define MY_NODE_ID 15
    
    // 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 <DallasTemperature.h>
    #include <OneWire.h>
    #include <Wire.h>
    #include <SI7021.h>
    #ifndef MY_OTA_FIRMWARE_FEATURE
    #include "drivers/SPIFlash/SPIFlash.cpp"
    #endif
    #include <EEPROM.h>  
    #include <sha204_lib_return_codes.h>
    #include <sha204_library.h>
    #include <RunningAverage.h>
    
    #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
    #define ONE_WIRE_BUS 7 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 16
    
    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
    float lastTemperatureDA[MAX_ATTACHED_DS18B20];
    int numSensors=0;
    boolean receivedConfig = false;
    boolean metric = true; 
    // Initialize temperature message
    MyMessage msg(0,V_TEMP);
    
    // Uncomment the line below, to transmit battery voltage as a normal sensor value
    //#define BATT_SENSOR    199
    
    #define RELEASE "2.1.1"
    
    #define AVERAGES 2
    
    // Child sensor ID's
    #define CHILD_ID_TEMP  3
    #define CHILD_ID_HUM   4
    
    // How many milli seconds between each measurement
    #define MEASURE_INTERVAL 60000
    
    // 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 0.5
    #define TEMP_TRANSMIT_THRESHOLD 0.5
    
    // Pin definitions
    #define TEST_PIN       A0
    #define LED_PIN        A2
    #define ATSHA204_PIN   17 // A3
    
    const int sha204Pin = ATSHA204_PIN;
    atsha204Class sha204(sha204Pin);
    
    SI7021 humiditySensor;
    SPIFlash flash(8, 0x1F65);
    
    // Sensor messages
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    
    #ifdef BATT_SENSOR
    MyMessage msgBatt(BATT_SENSOR, V_VOLTAGE);
    #endif
    
    // Global settings
    int measureCount = 0;
    int sendBattery = 0;
    boolean isMetric = true;
    boolean highfreq = true;
    boolean transmission_occured = false;
    
    // Storage of old measurements
    float lastTemperatureSB = -100;
    int lastHumidity = -100;
    long lastBattery = -100;
    
    RunningAverage raHum(AVERAGES);
    
    void before()
    {
      // Startup up the OneWire library
      sensors.begin();
    }
    
    /****************************************************
     *
     * 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();
    
      // Make sure that ATSHA204 is not floating
      pinMode(ATSHA204_PIN, INPUT);
      digitalWrite(ATSHA204_PIN, HIGH);
      
      digitalWrite(TEST_PIN,LOW);
      
      digitalWrite(LED_PIN, HIGH); 
    
      humiditySensor.begin();
    
      digitalWrite(LED_PIN, LOW);
    
      Serial.flush();
      Serial.println(F(" - Online!"));
      
      isMetric = getControllerConfig().isMetric;
      Serial.print(F("isMetric: ")); Serial.println(isMetric);
      raHum.clear();
      sendTempHumidityMeasurements(false);
      sendBattLevel(false);
      
    #ifdef MY_OTA_FIRMWARE_FEATURE  
      Serial.println("OTA FW update enabled");
    #endif
    
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    }
    
    void presentation()  {
      sendSketchInfo("Sensebender Micro", RELEASE);
    
      present(CHILD_ID_TEMP,S_TEMP);
      present(CHILD_ID_HUM,S_HUM);
        
    #ifdef BATT_SENSOR
      present(BATT_SENSOR, S_POWER);
    #endif
    
      // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
      }
    }
    /***********************************************
     *
     *  Main loop function
     *
     ***********************************************/
    void loop() {
      
      measureCount ++;
      sendBattery ++;
      bool forceTransmit = false;
      transmission_occured = false;
    #ifndef MY_OTA_FIRMWARE_FEATURE
      if ((measureCount == 5) && highfreq) 
      {
        clock_prescale_set(clock_div_8); // Switch to 1Mhz for the reminder of the sketch, save power.
        highfreq = false;
      } 
    #endif
      
      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;
      }*/
    #ifdef MY_OTA_FIRMWARE_FEATURE
      if (transmission_occured) {
          wait(OTA_WAIT_PERIOD);
      }
    #endif
    
      // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
      // query conversion time and sleep until conversion completed
      int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
      //NEW* int16_t conversionTime = millisToWaitForConversion(sensors.getResolution());
      // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
      sleep(conversionTime);
    
      // Read temperatures and send them to controller 
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
     
        // Fetch and round temperature to one decimal
        float temperatureDA = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
     
        // Only send data if temperature has changed and no error
        #if COMPARE_TEMP == 1
        if (lastTemperatureDA[i] != temperatureDA && temperatureDA != -127.00 && temperatureDA != 85.00) {
        #else
        if (temperatureDA != -127.00 && temperatureDA != 85.00) {
        #endif
    
        Serial.print("T.DA: ");Serial.println(sensors.getTempCByIndex(i));
     
          // Send in the new temperature
          send(msg.setSensor(i).set(temperatureDA,1));
          // Save new temperatures for next compare
          lastTemperatureDA[i]=temperatureDA;
        }
      }
    
      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;
    
      si7021_env data = humiditySensor.getHumidityAndTemperature();
      
      raHum.addValue(data.humidityPercent);
      
      float diffTemp = abs(lastTemperatureSB - (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 (tx) {
        measureCount = 0;
        float temperatureSB = (isMetric ? data.celsiusHundredths : data.fahrenheitHundredths) / 100.0;
         
        int humidity = data.humidityPercent;
        Serial.print("T: ");Serial.println(temperatureSB);
        Serial.print("H: ");Serial.println(humidity);
        
        send(msgTemp.set(temperatureSB,1));
        send(msgHum.set(humidity));
        lastTemperatureSB = temperatureSB;
        lastHumidity = humidity;
        transmission_occured = true;
        if (sendBattery > 60) {
         sendBattLevel(true); // Not needed to send battery info that often
         sendBattery = 0;
        }
      }
    }
    
    /********************************************
     *
     * Sends battery information (battery percentage)
     *
     * Parameters
     * - force : Forces transmission of a value
     *
     *******************************************/
    void sendBattLevel(bool force)
    {
      if (force) lastBattery = -1;
      long vcc = readVcc();
      if (vcc != lastBattery) {
        lastBattery = vcc;
    
    #ifdef BATT_SENSOR
        float send_voltage = float(vcc)/1000.0f;
        send(msgBatt.set(send_voltage,3));
    #endif
    
        // Calculate percentage
    
        vcc = vcc - 1900; // subtract 1.9V from vcc, as this is the lowest voltage we will operate at
        
        long percent = vcc / 14.0;
        sendBatteryLevel(percent);
        transmission_occured = true;
      }
    }
    
    /*******************************************
     *
     * Internal battery ADC measuring 
     *
     *******************************************/
    long readVcc() {
      // Read 1.1V reference against AVcc
      // set the reference to Vcc and the measurement to the internal 1.1V reference
      #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
        ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
        ADMUX = _BV(MUX5) | _BV(MUX0);
      #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
        ADcdMUX = _BV(MUX3) | _BV(MUX2);
      #else
        ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      #endif  
     
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Start conversion
      while (bit_is_set(ADCSRA,ADSC)); // measuring
     
      uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
      uint8_t high = ADCH; // unlocks both
     
      long result = (high<<8) | low;
     
      result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
      return result; // Vcc in millivolts
     
    }
    
    /****************************************************
     *
     * 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();
    
      
      Serial.print(F("-> SHA204 : "));
      ret_code = sha204.sha204c_wakeup(rx_buffer);
      Serial.flush();
      if (ret_code != SHA204_SUCCESS)
      {
        Serial.print(F("Failed to wake device. Response: ")); Serial.println(ret_code, HEX);
      }
      Serial.flush();
      if (ret_code == SHA204_SUCCESS)
      {
        ret_code = sha204.getSerialNumber(rx_buffer);
        if (ret_code != SHA204_SUCCESS)
        {
          Serial.print(F("Failed to obtain device serial number. Response: ")); Serial.println(ret_code, HEX);
        }
        else
        {
          Serial.print(F("Ok (serial : "));
          for (int i=0; i<9; i++)
          {
            if (rx_buffer[i] < 0x10)
            {
              Serial.print('0'); // Because Serial.print does not 0-pad HEX
            }
            Serial.print(rx_buffer[i], HEX);
          }
          Serial.println(")");
          tests ++;
        }
    
      }
      Serial.flush();
    
      Serial.println(F("Test finished"));
      
      if (tests == 3) 
      {
        Serial.println(F("Selftest ok!"));
        while (1) // Blink OK pattern!
        {
          digitalWrite(LED_PIN, HIGH);
          delay(200);
          digitalWrite(LED_PIN, LOW);
          delay(200);
        }
      }
      else 
      {
        Serial.println(F("----> Selftest failed!"));
        while (1) // Blink FAILED pattern! Rappidly blinking..
        {
        }
      }  
    }
    
    

    Thank you very much in advance.
    Steff



  • It is so strange... today i did some more tests... connected to serialmonitor... at the beginning all seems running correct but after a Little while i only see squares in my serial monitor output... BUT... again temperature and humidity from internal Sensors of sensebender are transmitted, only the two ds18b20 sensors did Not send anymore... i don't know what i can do now :-( Hope anybody can help me.... thanks again



  • I did some more tests, this is what i get in serial monitor:

    15017 TSF:MSG:SEND,15-15-0-0,s=3,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:27.0
    15026 TSF:MSG:SEND,15-15-0-0,s=4,c=1,t=1,pt=2,l=2,sg=0,ft=0,st=OK:45
    15034 MCO:SLP:MS=750,SMS=0,I1=255,M1=255,I2=255,M2=255
    15039 MCO:SLP:TPD
    15041 MCO:SLP:WUP=-1
    15112 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    15117 MCO:SLP:TPD
    15118 MCO:SLP:WUP=-1
    TempDiff :0.01
    HumDiff  :0.00
    15133 MCO:SLP:MS=750,SMS=0,I1=255,M1=255,I2=255,M2=255
    15138 MCO:SLP:TPD
    15139 MCO:SLP:WUP=-1
    T.DA: 26.19
    15253 TSF:MSG:SEND,15-15-0-0,s=1,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:26.1
    15259 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    15264 MCO:SLP:TPD
    15266 MCO:SLP:WUP=-1
    TempDiff :0.05
    HumDiff  :0.50
    15281 MCO:SLP:MS=750,SMS=0,I1=255,M1=255,I2=255,M2=255
    15286 MCO:SLP:TPD
    15288 MCO:SLP:WUP=-1
    15358 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    15364 MCO:SLP:TPD
    15366 MCO:SLP:WUP=-1
    TempDiff :0.02
    HumDiff  :0.50
    15380 MCO:SLP:MS=750,SMS=0,I1=255,M1=255,I2=255,M2=255
    15385 MCO:SLP:TPD
    15386 MCO:SLP:WUP=-1
    T.DA: 25.94
    15444 TSF:MSG:SEND,15-15-0-0,s=0,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:25.9
    15492 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    15497 MCO:SLP:TPD
    15499 MCO:SLP:WUP=-1
    TempDiff :0.11
    HumDiff  :0.50
    15514 MCO:SLP:MS=750,SMS=0,I1=255,M1=255,I2=255,M2=255
    15518 MCO:SLP:TPD
    15520 MCO:SLP:WUP=-1
    15591 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    15596 MCO:SLP:TPD
    15598 MCO:SLP:WUP=-1
    ⸮⸮⸮⸮⸮
    

    After this i only get those little squares... and no more data are send... I have no more idea what to do... :-(


  • Admin

    @HarrySteff said in SensebenderMicro with two additional DS18b20:

    Try and remove the following lines from your sketch:

     #ifndef MY_OTA_FIRMWARE_FEATURE
       if ((measureCount == 5) && highfreq) 
       {
         clock_prescale_set(clock_div_8); // Switch to 1Mhz for the reminder of the sketch, save power.
         highfreq = false;
       } 
     #endif
    

    This switches to a lower frequency after approximately 5 minutes, this messes up the timing, which I normally don't care about with the Si7021 temperature sensor, but the DS1820 needs "precise" timing, to communicate, as it uses bit banging..



  • @tbowmo WOW you are my hero... after a couple of test it seems working now... THANK YOU SO MUCH... I will try it now for a longer time THANKS again!



  • Again, that was it! @tbowmo Thank you again so much! Everything is running smoothly :-)


Log in to reply
 

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