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. My Project
  3. Low power temperature/humidity node with sonoff si7021

Low power temperature/humidity node with sonoff si7021

Scheduled Pinned Locked Moved My Project
1 Posts 1 Posters 1.5k Views 1 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.
  • Y Offline
    Y Offline
    yelti_be
    wrote on last edited by
    #1

    My little project:
    Temperature/humidity sensor with a sonoff si7021.

    You can find the sonoff si7021 sensors quite cheap on aliexpress (about 4,5€/piece).
    Pro's: has sensor and housing
    Con's: needs some tinkering to use it in low power application.

    The build:
    Arduino mini pro 8mhz 3.3v
    Sonoff si7021 sensor
    Lipo 3.7v battery
    nrf24l01+ radio

    I modded the arduino nano clone for low low power.

    First I tried with the one-wire protocol of the sonoff, but no luck in there.
    Next I soldered sda/scl lines directy and the sensor worked, but sleeping current was 1ma and way out of specs for the si7021 + mini pro.

    Next I modded the si7021sonoff si7021

    • I removed the transistor Q1
    • I remove capacitor C4
    • I cut all traces from the mcu

    After this the sleeping current is about 15 uA.

    The sketch sends temperature, humidity, batterylevel and batteryvoltage.

    My code:

    
    // Enable debug prints to serial monitor
    //#define MY_DEBUG 
     
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
     
    // Set LOW transmit power level as default, if you have an amplified NRF-module and
    // power your radio separately with a good regulator you can turn up PA level.
    // #define MY_RF24_PA_LEVEL RF24_PA_LOW
     
    #define MY_RF24_PA_LEVEL RF24_PA_HIGH
    //#define MY_DEBUG_VERBOSE_RF24
     
    // RF channel for the sensor net, 0-127
    #define RF24_CHANNEL     125
    //PiHome Node ID
    #define MY_NODE_ID 23
     
    //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
    #define RF24_DATARATE      RF24_250KBPS
     
    #include <MySensors.h>  
    #include "Adafruit_Si7021.h"
    
    Adafruit_Si7021 sensor = Adafruit_Si7021();
     
    // Define sensor node childs
    
    #define CHILD_ID_TEMP 0
    #define CHILD_ID_HUM 1
    #define CHILD_ID_BATT 2
    #define CHILD_ID_BATT_VOLTAGE 3
     
    #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
    #define COMPARE_BVOLT 1 // Send battery voltage only if changed? 1 = Yes 0 = No
    #define         READ_SAMPLE_INTERVAL         (10)    //define how many samples you are going to take in normal operation
    #define         READ_SAMPLE_TIMES            (5)     //define the time interal(in milisecond) between each samples in 
    
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    static const uint64_t UPDATE_INTERVAL = 10000;
     
    unsigned long SLEEP_TIME = 56000; // Sleep time between reads (in milliseconds)
     
    // Battery related init
    int BATTERY_SENSE_PIN = A6;  // select the input pin for the battery sense point
    float oldBatteryV = 0;
    
     
    #define SKETCH_NAME "Temp_Humid_Bat_Uterum"      // Change to a fancy name you like
    #define SKETCH_VERSION "2.1"                    // Your version
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    //Definition messages
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgBattVolt(CHILD_ID_BATT_VOLTAGE, V_VOLTAGE);
    MyMessage msgBatt(CHILD_ID_BATT, V_VOLTAGE);
    
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    
    //Variables
    int chk;
    float hum;  //Stores humidity value
    float temp; //Stores temperature value
     
     
    void setup()  
    { 
      if (!sensor.begin()) {
        Serial.println("Did not find Si7021 sensor!");
        while (true);
      }
      
      // needed for battery soc
      // use the 1.1 V internal reference
      #if defined(__AVR_ATmega2560__)
          analogReference(INTERNAL1V1);
      #else
          analogReference(INTERNAL);
      #endif
      delay(2000);
      #ifdef MY_DEBUG 
        Serial.println("***Debug Activated***");
        Serial.print("Sleep_Time: ");
        Serial.print((SLEEP_TIME / 1000)/60);
        Serial.println(" min");    
      #else 
        Serial.println("***Debug Deactivated***");
        Serial.print("Sleep_Time: ");
        Serial.print((SLEEP_TIME / 1000)/60);
        Serial.println(" min");  
      #endif
    }
     
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Temperature Sensor", "1.34");
     
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_BATT, S_POWER);
      present(CHILD_ID_BATT_VOLTAGE, S_MULTIMETER , "Battery ");
    
    }
     
    void loop()     
    {
      // disable ADC
      
      // get the battery Voltage
      int battSensorValue = analogRead(BATTERY_SENSE_PIN);
      float batteryV  = battSensorValue * 0.011828;
        // 1M, 100K divider across battery and using internal ADC ref of 1.1V
        // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
        // ((1e6+100e3)/100e3)*1.1 = Vmax = 12.1 Volts
        // 12.1/1023 = Volts per bit = 0.011828 
      int batteryPcnt = (batteryV / 4.2) * 100;
      
      #ifdef MY_DEBUG
        Serial.print("Pin Reading: ");
        Serial.println(battSensorValue);
        Serial.print("Battery Voltage: ");
        Serial.print(batteryV);
        Serial.println(" v");
        //Print Battery Percentage
        Serial.print("Battery percent: ");
        Serial.print(batteryPcnt);
        Serial.println(" %");
      #endif
      #if COMPARE_BVOLT == 1
        send(msgBatt.set(batteryV, 2));
        send(msgBattVolt.set(batteryV,2));
        sendBatteryLevel(batteryPcnt);
      #else 
        if (oldBatteryV != batteryV) {
          send(msgBatt.set(batteryV, 2));
          sendBatteryLevel(batteryPcnt);
          send(msgBattVolt.set(batteryV,2));
          oldBatteryV = batteryV;
        }
      #endif
    
      delay(500);
        //Read data and store it to variables hum and temp
        hum = sensor.readHumidity();
        temp= sensor.readTemperature();
        #ifdef MY_DEBUG
        //Print temp and humidity values to serial monitor
        Serial.print("Humidity: ");
        Serial.print(hum);
        Serial.print(" %, Temp: ");
        Serial.print(temp);
        Serial.println(" Celsius");
        #endif
      if (isnan(temp)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temp != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temp;
     
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        temp += SENSOR_TEMP_OFFSET;
        send(msgTemp.set(temp, 1));
    
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temp);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      
      if (isnan(hum)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (hum != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = hum;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(hum, 1));
    
        #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(hum);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
      
      sleep(SLEEP_TIME);
    }
    

    My inspirations:

    • low power arduino
    • pi home battery ds18b20 sensor
    • many others :relaxed:
    1 Reply Last reply
    1

    Hello! It looks like you're interested in this conversation, but you don't have an account yet.

    Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

    With your input, this post could be even better 💗

    Register Login
    Reply
    • Reply as topic
    Log in to reply
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes


    16

    Online

    12.0k

    Users

    11.2k

    Topics

    113.4k

    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