Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. [SOLVED] ds18b20 vs si7021 loss of granularity in measurement

[SOLVED] ds18b20 vs si7021 loss of granularity in measurement

Scheduled Pinned Locked Moved Troubleshooting
9 Posts 3 Posters 1.1k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    waspie
    wrote on last edited by Yveaux
    #1

    I've got two nodes sitting right next to each other taking measurements every 3-4 minutes and I'm finding the si7021 doesn't present a very fine-grained measurement like the dallas:
    0_1549547462197_be6690c5-3636-4f25-9439-d74bfcb99d1b-image.png
    The green line is the dallas sensor and the red line is the si7021. How do I get the si7021 to behave more like the dallas?
    as you can see I'm getting temperatures in steps greater than .5 degrees fahrenheit.

    The si7021 is using @NeverDie round board with this code:

    // SUMMARY: This demo sketch runs on MultiSensor Version 7 board with an I2C Si7021 module to transmit temperature, humidity, and battery voltage to a MySensors gateway using MySensors protocols.
    
    // Note: because this is a passive node, node ID must be set manually to a unique sensor node ID:
    #define MY_NODE_ID 128  // Passive mode requires static node ID
    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2017 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - tekka
     *
     * DESCRIPTION
     * Passive node example: This is a passive & independent reporting node
     *
     */
    
    // This demo sketch uses the LowPowerLab SI7021 library and also some of its sample code:  https://github.com/LowPowerLab/SI7021
    
    // This demo sketch also draws from the MySensor's example MockMySensors sketch.
    
    // This demo sketch also draws from some of the code posted by smilvert here: https://forum.mysensors.org/topic/7961/why-do-passive-nodes-need-to-set-their-node-id-manually/14
    
    
    #define SHORT_WAIT 50
    
    #include <Wire.h>
    #include <SI7021.h>  //from LowPowerLab:  https://github.com/LowPowerLab/SI7021
    
    
    SI7021 sensor;
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable passive mode
    #define MY_PASSIVE_NODE
    
    
    
    
    // Enable and select radio type attached
    //#define MY_RADIO_NRF24
    #define MY_RADIO_NRF5_ESB
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    
    #include <MySensors.h>
    
    #define CHILD_ID_TEMP 0  //definitions contributed by smilvert (see above credit)
    #define CHILD_ID_HUM 1
    
    // Initialize general message
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    
    #define ID_S_MULTIMETER        28
    MyMessage msg_S_MULTIMETER_V_VOLTAGE(ID_S_MULTIMETER,V_VOLTAGE);
    
    float batteryVoltage=0;  
    float temperature=0;
    int humidity=0;
    
    void blinkityBlink(uint8_t repetitions) {
      for (int x=0;x<repetitions;x++) {
        digitalWrite(LED_BUILTIN,HIGH);
        wait(20);
        digitalWrite(LED_BUILTIN,LOW);
        wait(100);
        digitalWrite(LED_BUILTIN,HIGH);
        wait(20);
        digitalWrite(LED_BUILTIN,LOW);    
        if (x<(repetitions-1)) {  //skip waiting at the end of the final repetition
          wait(500);
        }
      }
    }
    
    
    
    void setup()
    {
      hwPinMode(LED_BUILTIN,OUTPUT_D0H1);
      blinkityBlink(5);  //signify power-up and start of operations
    
      sensor.begin();
      
      NRF_CLOCK->INTENSET=B11;  //enable interrupts for EVENTS_HFCLKSTARTED and  EVENTS_LFCLKSTARTED
      NRF_CLOCK->TASKS_HFCLKSTART=1;  //start the high frequency crystal oscillator clock
      while (!(NRF_CLOCK->EVENTS_HFCLKSTARTED)) {} //wait until high frequency crystal oscillator clock is up to speed and working
    
    }
    
    void presentation()
    {
    	// Send the sketch version information to the gateway and controller
    	sendSketchInfo("Passive node", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_TEMP, S_TEMP);
      wait(SHORT_WAIT);
      present(CHILD_ID_HUM, S_HUM);
      wait(SHORT_WAIT);
      present(ID_S_MULTIMETER,S_MULTIMETER,"Electric Station");
      wait(SHORT_WAIT);
    }
    
    
    void loop() {
    
        // get humidity and temperature in one shot, saves power because sensor takes temperature when doing humidity anyway
        si7021_env data = sensor.getHumidityAndTemperature();
        temperature = data.celsiusHundredths/100;
        // humidity is an integer representing percent
        humidity = data.humidityBasisPoints/100;
    
        sleep(60000);  //sleep for one minute to recover voltage after temperature and humidity measurements.
        
        send(msgTemp.set(temperature,2));
        sleep(60000);  //sleep for 60 seconds
        
        send(msgHum.set(humidity,0));
        batteryVoltage=((float)hwCPUVoltage())/1000.0;  //take voltage measurement after transmission to hopefully measure lowest voltage that occurs.
        sleep(60000);  //sleep for one minute
        
        send(msg_S_MULTIMETER_V_VOLTAGE.set(batteryVoltage,3));  //send battery voltage with 3 decimal places
        sleep(60000);  //sleep for 60 seconds
    }
    
    
    
    B 1 Reply Last reply
    0
    • W waspie

      I've got two nodes sitting right next to each other taking measurements every 3-4 minutes and I'm finding the si7021 doesn't present a very fine-grained measurement like the dallas:
      0_1549547462197_be6690c5-3636-4f25-9439-d74bfcb99d1b-image.png
      The green line is the dallas sensor and the red line is the si7021. How do I get the si7021 to behave more like the dallas?
      as you can see I'm getting temperatures in steps greater than .5 degrees fahrenheit.

      The si7021 is using @NeverDie round board with this code:

      // SUMMARY: This demo sketch runs on MultiSensor Version 7 board with an I2C Si7021 module to transmit temperature, humidity, and battery voltage to a MySensors gateway using MySensors protocols.
      
      // Note: because this is a passive node, node ID must be set manually to a unique sensor node ID:
      #define MY_NODE_ID 128  // Passive mode requires static node ID
      
      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2017 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * Version 1.0 - tekka
       *
       * DESCRIPTION
       * Passive node example: This is a passive & independent reporting node
       *
       */
      
      // This demo sketch uses the LowPowerLab SI7021 library and also some of its sample code:  https://github.com/LowPowerLab/SI7021
      
      // This demo sketch also draws from the MySensor's example MockMySensors sketch.
      
      // This demo sketch also draws from some of the code posted by smilvert here: https://forum.mysensors.org/topic/7961/why-do-passive-nodes-need-to-set-their-node-id-manually/14
      
      
      #define SHORT_WAIT 50
      
      #include <Wire.h>
      #include <SI7021.h>  //from LowPowerLab:  https://github.com/LowPowerLab/SI7021
      
      
      SI7021 sensor;
      
      // Enable debug prints
      #define MY_DEBUG
      
      // Enable passive mode
      #define MY_PASSIVE_NODE
      
      
      
      
      // Enable and select radio type attached
      //#define MY_RADIO_NRF24
      #define MY_RADIO_NRF5_ESB
      //#define MY_RADIO_RFM69
      //#define MY_RADIO_RFM95
      
      #include <MySensors.h>
      
      #define CHILD_ID_TEMP 0  //definitions contributed by smilvert (see above credit)
      #define CHILD_ID_HUM 1
      
      // Initialize general message
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
      
      #define ID_S_MULTIMETER        28
      MyMessage msg_S_MULTIMETER_V_VOLTAGE(ID_S_MULTIMETER,V_VOLTAGE);
      
      float batteryVoltage=0;  
      float temperature=0;
      int humidity=0;
      
      void blinkityBlink(uint8_t repetitions) {
        for (int x=0;x<repetitions;x++) {
          digitalWrite(LED_BUILTIN,HIGH);
          wait(20);
          digitalWrite(LED_BUILTIN,LOW);
          wait(100);
          digitalWrite(LED_BUILTIN,HIGH);
          wait(20);
          digitalWrite(LED_BUILTIN,LOW);    
          if (x<(repetitions-1)) {  //skip waiting at the end of the final repetition
            wait(500);
          }
        }
      }
      
      
      
      void setup()
      {
        hwPinMode(LED_BUILTIN,OUTPUT_D0H1);
        blinkityBlink(5);  //signify power-up and start of operations
      
        sensor.begin();
        
        NRF_CLOCK->INTENSET=B11;  //enable interrupts for EVENTS_HFCLKSTARTED and  EVENTS_LFCLKSTARTED
        NRF_CLOCK->TASKS_HFCLKSTART=1;  //start the high frequency crystal oscillator clock
        while (!(NRF_CLOCK->EVENTS_HFCLKSTARTED)) {} //wait until high frequency crystal oscillator clock is up to speed and working
      
      }
      
      void presentation()
      {
      	// Send the sketch version information to the gateway and controller
      	sendSketchInfo("Passive node", "1.0");
      
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID_TEMP, S_TEMP);
        wait(SHORT_WAIT);
        present(CHILD_ID_HUM, S_HUM);
        wait(SHORT_WAIT);
        present(ID_S_MULTIMETER,S_MULTIMETER,"Electric Station");
        wait(SHORT_WAIT);
      }
      
      
      void loop() {
      
          // get humidity and temperature in one shot, saves power because sensor takes temperature when doing humidity anyway
          si7021_env data = sensor.getHumidityAndTemperature();
          temperature = data.celsiusHundredths/100;
          // humidity is an integer representing percent
          humidity = data.humidityBasisPoints/100;
      
          sleep(60000);  //sleep for one minute to recover voltage after temperature and humidity measurements.
          
          send(msgTemp.set(temperature,2));
          sleep(60000);  //sleep for 60 seconds
          
          send(msgHum.set(humidity,0));
          batteryVoltage=((float)hwCPUVoltage())/1000.0;  //take voltage measurement after transmission to hopefully measure lowest voltage that occurs.
          sleep(60000);  //sleep for one minute
          
          send(msg_S_MULTIMETER_V_VOLTAGE.set(batteryVoltage,3));  //send battery voltage with 3 decimal places
          sleep(60000);  //sleep for 60 seconds
      }
      
      
      
      B Offline
      B Offline
      boozz
      wrote on last edited by
      #2

      @waspie said in ds18b20 vs si7021 loss of granularity in measurement:

      temperature = data.celsiusHundredths/100;

      In my opinion does the above line not cohere with the statement that the steps are greater than .5 degrees fahrenheit.

      Have you tried using:

      temperature = data.getFahrenheitHundredths/100;

      and what was the result.

      Could it be you've been playing with the examples as provided with the library from LowPowerLab and you accidentally forgot to "turn the heater off"? I'm guessing at the moment, but you could end up with the device being heated up in the range of 70ºC (which is 158 degrees fahrenheit...:grimacing: )

      BR,

      Boozz

      W 1 Reply Last reply
      0
      • B boozz

        @waspie said in ds18b20 vs si7021 loss of granularity in measurement:

        temperature = data.celsiusHundredths/100;

        In my opinion does the above line not cohere with the statement that the steps are greater than .5 degrees fahrenheit.

        Have you tried using:

        temperature = data.getFahrenheitHundredths/100;

        and what was the result.

        Could it be you've been playing with the examples as provided with the library from LowPowerLab and you accidentally forgot to "turn the heater off"? I'm guessing at the moment, but you could end up with the device being heated up in the range of 70ºC (which is 158 degrees fahrenheit...:grimacing: )

        BR,

        Boozz

        W Offline
        W Offline
        waspie
        wrote on last edited by
        #3

        @boozz
        That isn't 100% the exact code. I convert the celcius manually so that temp graphed is farhenheit.

        The first 2-3 nodes i put together I didn't know about the ismetric thing going on and I didn't want to go back and reflash those modules so I just make sure to calculate before sending to the GW. Definitely not a heater issue.

        YveauxY 1 Reply Last reply
        0
        • W waspie

          @boozz
          That isn't 100% the exact code. I convert the celcius manually so that temp graphed is farhenheit.

          The first 2-3 nodes i put together I didn't know about the ismetric thing going on and I didn't want to go back and reflash those modules so I just make sure to calculate before sending to the GW. Definitely not a heater issue.

          YveauxY Offline
          YveauxY Offline
          Yveaux
          Mod
          wrote on last edited by Yveaux
          #4

          @waspie Seems like you're rounding to full degrees in the line

          temperature = data.celsiusHundredths/100;
          

          In the si7021 library the si7021_env type is defined as:

          typedef struct si7021_env {
              int celsiusHundredths;
              int fahrenheitHundredths;
              unsigned int humidityBasisPoints;
          } si7021_env;
          

          so temperature is an integer in 1/100th increments.

          Try converting this integer to float before dividing, like:

          temperature = float(data.celsiusHundredths)/100.0;
          

          http://yveaux.blogspot.nl

          W 1 Reply Last reply
          3
          • YveauxY Yveaux

            @waspie Seems like you're rounding to full degrees in the line

            temperature = data.celsiusHundredths/100;
            

            In the si7021 library the si7021_env type is defined as:

            typedef struct si7021_env {
                int celsiusHundredths;
                int fahrenheitHundredths;
                unsigned int humidityBasisPoints;
            } si7021_env;
            

            so temperature is an integer in 1/100th increments.

            Try converting this integer to float before dividing, like:

            temperature = float(data.celsiusHundredths)/100.0;
            
            W Offline
            W Offline
            waspie
            wrote on last edited by
            #5

            @yveaux
            thank you, this sounds very promising! I will try it this evening

            1 Reply Last reply
            0
            • W Offline
              W Offline
              waspie
              wrote on last edited by
              #6

              @Yveaux this has resolved it, thank you

              B 1 Reply Last reply
              2
              • W waspie

                @Yveaux this has resolved it, thank you

                B Offline
                B Offline
                boozz
                wrote on last edited by
                #7

                @Yveaux
                Good to see it solved for @waspie

                Conversion from int (or byte) to float and vise versa is something that often brings me a headache.
                I literaly spend many hours searching for a good guide in via google, but never really found one.

                Are you maybe aware of a good guide how to properly do the conversions between different types (byte from floats etc. without getting involved in memory hungry libraries).

                BR,

                Boozz

                YveauxY 1 Reply Last reply
                0
                • B boozz

                  @Yveaux
                  Good to see it solved for @waspie

                  Conversion from int (or byte) to float and vise versa is something that often brings me a headache.
                  I literaly spend many hours searching for a good guide in via google, but never really found one.

                  Are you maybe aware of a good guide how to properly do the conversions between different types (byte from floats etc. without getting involved in memory hungry libraries).

                  BR,

                  Boozz

                  YveauxY Offline
                  YveauxY Offline
                  Yveaux
                  Mod
                  wrote on last edited by
                  #8

                  @boozz this is standard c / c++.
                  Any good book on the topic should explain how it works.
                  Basically it comes down to when you cast from float to integer that the value will be rounded down and that you will loose any decimals.
                  From integer to float will introduce decimals, set to 0.

                  http://yveaux.blogspot.nl

                  B 1 Reply Last reply
                  0
                  • YveauxY Yveaux

                    @boozz this is standard c / c++.
                    Any good book on the topic should explain how it works.
                    Basically it comes down to when you cast from float to integer that the value will be rounded down and that you will loose any decimals.
                    From integer to float will introduce decimals, set to 0.

                    B Offline
                    B Offline
                    boozz
                    wrote on last edited by boozz
                    #9

                    @yveaux
                    Thanks for the hint and explanation. I appreciate that!

                    I always used the search term: "conversion" (English is not my native language). I tried "casting" in combination with "c#" and I was almost immediately directed to my favorit c++ internet source (cplusplus.com)

                    http://www.cplusplus.com/doc/tutorial/typecasting/

                    Many thanks! :+1:

                    Boozz

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    19

                    Online

                    11.7k

                    Users

                    11.2k

                    Topics

                    113.1k

                    Posts


                    Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • MySensors
                    • OpenHardware.io
                    • Categories
                    • Recent
                    • Tags
                    • Popular