Temperature and Humidity with SI7021 on Slim 2AA Battery Node 1Mhz
-
This is my take on a battery node for temperature and humidity
I have used the slim 2AA battery node board from https://www.openhardware.io/view/10/My-Slim-2AA-Battery-Node
For the boot loader I used Gert Sanders bootloaders from https://www.openhardware.io/view/33/Various-bootloader-files-based-on-Optiboot-62
I used the 1Mhz internal clock with brown out detection disabled. In the arduino IDE these options were used:-
Board: "atmega328p based -28 pin DIL"
CPU Frequency, upload speed, LED: 1Mhz -9k6 -D13
Clock source: "1Mhz - internal 8Mhz CDIV 8"
Brown Out Detection: "Disabled"I burned the boot loader using a Arduino Uno with my own hat based on the minimal arduino on a breadboard circuit https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard. The UNO is loaded with the "Arduino as an ISP" sketch.
The image below is the top of the hat, the LED's are utilising the standard status indicators in the sketch. Green: Ready
Blue (middle): Programing
Red: Error.
Orange: linked to D13 for basic testing of chip, some bootloaders also load a basic blink program that also blinks this LED
The 6 pin header accepts a standard ftdi usb-serial programmer to load the code on the arduino chip
Bottom shows more of the wiring
The enclosure I used is a really handy little box with a builtin 2xAA or 1x9V battery holder available from my local (Australian) electronics supplier Jaycar
https://www.jaycar.com.au/black-hand-held-electronic-enclosure/p/HB5610For battery monitoring I chose to use a voltage devider because I could not get any stabilty or accuracy with the internal vcc library when running the arduino at 1Mhz (or 8Mhz) internal occilator.
Here is my current code, it is based on https://forum.mysensors.org/topic/3049/slim-node-si7021-sensor-example/2
// Enable debug prints #define MY_DEBUG #define MY_BAUD_RATE 9600 // Enable and select radio type attached #define MY_RADIO_NRF24 #include <Wire.h> #include <Adafruit_Si7021.h> #include <SPI.h> #include <MySensors.h> #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 //#define SLEEP_TIME 15000 // 15s for DEBUG #define SLEEP_TIME 300000 // 5 min #define FORCE_TRANSMIT_CYCLE 12 // 5min*12=1 hour #define BATTERY_REPORT_CYCLE 12 // 5min*12=1 hour #define VMIN 2000 #define VMAX 3200 #define HUMI_TRANSMIT_THRESHOLD 3.0 // THRESHOLD tells how much the value should have changed since last time it was transmitted. #define TEMP_TRANSMIT_THRESHOLD 0.5 // to make it report the first time. int measureCount = 0; float lastTemperature = -100; int lastHumidity = -100; int batteryReportCounter = BATTERY_REPORT_CYCLE; Adafruit_Si7021 sensor = Adafruit_Si7021(); int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); void presentation() { // Send the sketch version information to the gateway sendSketchInfo("TemperatureAndHumidity", "2.1"); // Register all sensors to gw (they will be created as child devices) present(CHILD_ID_HUM, S_HUM); present(CHILD_ID_TEMP, S_TEMP); } void setup() { analogReference(INTERNAL); if (!sensor.begin()) { Serial.println("Did not find Si7021 sensor!"); while (true); } } void loop() { measureCount ++; batteryReportCounter ++; bool forceTransmit = false; #ifdef MY_DEBUG Serial.print("Measure Count: "); Serial.println(measureCount); Serial.print("Battery Report Count: "); Serial.println(batteryReportCounter); #endif if (measureCount > FORCE_TRANSMIT_CYCLE) { forceTransmit = true; #ifdef MY_DEBUG Serial.println("Force Transmit"); #endif } sendTempHumidityMeasurements(forceTransmit); // get the battery Voltage int BatterysensorValue = analogRead(BATTERY_SENSE_PIN); //float batteryVolt = BatterysensorValue * 0.003363075; float batteryVolt = BatterysensorValue * 3.363075; uint8_t batteryPcnt = constrain(map(batteryVolt,VMIN,VMAX,0,100),0,255); #ifdef MY_DEBUG Serial.print("Battery voltage: "); Serial.print(batteryVolt); Serial.println(" mV"); Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); #endif if (batteryReportCounter >= BATTERY_REPORT_CYCLE) { #ifdef MY_DEBUG Serial.println("Sending Battery Voltage"); #endif sendBatteryLevel(batteryPcnt); batteryReportCounter = 0; } sleep(SLEEP_TIME); } void sendTempHumidityMeasurements(bool force) { #ifdef MY_DEBUG Serial.println("Read Temp Sensor"); #endif bool tx = force; float temperature = sensor.readTemperature(); float diffTemp = abs(lastTemperature - temperature); #ifdef MY_DEBUG Serial.print("T: ");Serial.println(temperature); Serial.print("TempDiff :");Serial.println(diffTemp); #endif if (diffTemp > TEMP_TRANSMIT_THRESHOLD || tx) { //send(msgTemp.set(temperature,1)); resend((msgTemp.set(temperature, 1)), 5); lastTemperature = temperature; measureCount = 0; #ifdef MY_DEBUG Serial.println("T sent"); #endif } int humidity = sensor.readHumidity(); // raHum.addValue(humidity); // humidity = raHum.getAverage(); // MA sample imply reasonable fast sample frequency float diffHum = abs(lastHumidity - humidity); #ifdef MY_DEBUG Serial.print("H: ");Serial.println(humidity); Serial.print("HumDiff :");Serial.println(diffHum); #endif if (diffHum > HUMI_TRANSMIT_THRESHOLD || tx) { //send(msgHum.set(humidity)); resend((msgHum.set(humidity, 1)), 5); lastHumidity = humidity; measureCount = 0; #ifdef MY_DEBUG Serial.println("H sent"); #endif } } // function to resend to gateway on failure void resend(MyMessage & msg, int repeats) { int repeat = 0; int repeatdelay = 0; boolean sendOK = false; while ((sendOK == false) and(repeat < repeats)) { if (send(msg)) { sendOK = true; } else { sendOK = false; Serial.print("Error "); Serial.println(repeat); repeatdelay += 250; repeat++; sleep(repeatdelay); } } }
Here are a few more pictures of the sensor.
Looks a bit different here because this is my first build already in the case