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
Suggested Topics
-
Welcome
Announcements • • hek