Low power temperature/humidity node with sonoff si7021
-
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+ radioI 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 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:
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