Temperature / humidity node with OLED display
-
I've just built this temperature / humidity node, with a 1.3" OLED display:
The OLED is a 128x64 I2C version, driven by an SSD1306 chip, and will display 8 lines of text - but as I'm short-sighted , I've used double-height text, showing time (from Domoticz), temperature, humidity and battery voltage.
The node uses a Ceech board, and is powered by a Samsung phone battery with a micro-USB connector (top left) to charge it. There is an HTU21D temperature / humidity sensor bottom left. Connectors have been judiciously bent (!), so that the base will fit on the box.
The sketch is based on Ceech's example sketch for the board, with the inclusion of a cut-down, text-only library for the SSD1306 (to save space).
-
@MikeF Is the display on all the time?
-
@Dwalt Currently, yes. I haven't done any measurements yet on current / discharge rate, but I can power it from USB and charge the battery at the same time. I may add a push button to turn on the display.
-
Great project
what script and stuff have you used?
i am very interested to make a temprature switch for my living room with that kind of display
great work
-
I've used the following:
-
Ceech ATmega328p board w/ ESP8266 and NRF24l01+ socket LTC4067 lithium battery charger - here
-
HTU21D temperature and humidity sensor
-
SSD1306 1.3" I2C 128x64 display - here
-
micro USB breakout board
The sketch is included below (I've referenced the source of this in the comments at the beginning):
// Temp + humidity sensor // Using Ceech board // and SSD1306 128 x 64 OLED display. // This example is designed to fit Arduino Nano/Pro Mini // // SSD1306 text-only library taken from this thread: // https://forum.arduino.cc/index.php?topic=274880.0 #include <MySensor.h> #include <SPI.h> #include <Wire.h> // I2C #include <HTU21D.h> // temperature / humidity (i2c, HTU21D, SHT21) #include <SSD1306_text.h> // SSD1306 OLED display #include <Time.h> #define SKETCH_NAME "Temp + hum w. display" #define SKETCH_MAJOR_VER "1" #define SKETCH_MINOR_VER "1" #define TEMP_CHILD_ID 5 #define HUM_CHILD_ID 6 #define BATT_CHILD_ID 10 #define batteryVoltage_PIN A0 //analog input A0 on ATmega328 is battery voltage ( /2) #define LTC4067_CHRG_PIN A1 //analog input A1 on ATmega 328 is /CHRG signal from LTC4067 #define OLED_RST 4 SSD1306_text oled(OLED_RST); const float VccMin = 1.0*3.5; // Minimum expected Vcc level, in Volts. Example for 1 rechargeable lithium-ion. const float VccMax = 1.0*4.2; // Maximum expected Vcc level, in Volts. HTU21D SHT21; // Hum/Temp (SHT12) MySensor sensor_node(7,8); float lastTempSHT; // SHT temp/hum float lastHumSHT; float lastBattVoltage; int lastBattPct = 0; float VccReference = 3.3; boolean charge = false; boolean timeReceived = false; unsigned long lastUpdate=0, lastRequest=0; unsigned long SLEEP_TIME = 60000; // 60 sec sleep time between reads (seconds * 1000 milliseconds) MyMessage temperatureMsg(TEMP_CHILD_ID, V_TEMP); // SHT temp (deg C) MyMessage humidityMsg(HUM_CHILD_ID, V_HUM); // SHT hum (% rh) MyMessage batteryVoltageMsg(BATT_CHILD_ID, V_VOLTAGE); void setup() { analogReference(DEFAULT); // default external reference = 3.3v for Ceech board VccReference = 3.323 ; // measured Vcc input (on board LDO) sensor_node.begin(NULL, 21); // fixed node 21 Wire.begin(); // init I2C SHT21.begin(); // initialize temp/hum // Send the sketch version information to the gateway and Controller sensor_node.sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER"."SKETCH_MINOR_VER); sensor_node.present(TEMP_CHILD_ID, S_TEMP); // SHT temp sensor_node.present(HUM_CHILD_ID, S_HUM); // SHT humidity sensor_node.present(BATT_CHILD_ID, S_POWER); // Battery parameters sensor_node.requestTime(receiveTime); // Initialize, optionally clear the screen oled.init(); oled.clear(); // clear screen oled.setTextSize(1,1); oled.setCursor(0); oled.print("NODE_2"); } void receiveTime(unsigned long controllerTime) { setTime(controllerTime); timeReceived = true; } void loop() { unsigned long now = millis(); sensor_node.process(); sensor_node.requestTime(receiveTime); lastRequest = now; Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.println(); oled.setTextSize(2,1); oled.setCursor(0,66); //oled.print(" "); if (hour() < 10) { oled.print("0"); } oled.print(hour()); oled.print(":"); if (minute() < 10) { oled.print("0"); } oled.print(minute()); sendTempHum(); Serial.println(); sendVoltage(); // Sleep until something happens with the sensor sensor_node.sleep(SLEEP_TIME); } void sendTempHum(void) { // SHT2x sensor // Temperature and Humidity float humidity = SHT21.readHumidity(); // send to MySensor network / only if change if (humidity != lastHumSHT && humidity != 0.00) { lastHumSHT = humidity; sensor_node.send(humidityMsg.set(humidity, 2)); // Send } float temperatureSHT = SHT21.readTemperature(); // send to MySensor network / only if change if (temperatureSHT != lastTempSHT && temperatureSHT != 0.00) { lastTempSHT = temperatureSHT; sensor_node.send(temperatureMsg.set(temperatureSHT, 2)); // Send } Serial.print("SHT21 temp: "); Serial.print(temperatureSHT); Serial.print(" SHT21 hum: "); Serial.print(humidity); oled.setCursor(2); oled.print("Temp: "); oled.print(temperatureSHT,1); oled.print("C"); oled.setCursor(4); oled.print("Hum : "); oled.print(humidity,0); oled.print("%"); } void sendVoltage(void) // battery values { // get Battery Voltage float batteryVoltage = ((float)analogRead(batteryVoltage_PIN)* VccReference/1024) * 2; // actual voltage is double Serial.print("Batt: "); Serial.print(batteryVoltage); Serial.print("V ; "); // send battery percentage for node int battPct = 1 ; if (batteryVoltage > VccMin){ battPct = 100.0*(batteryVoltage - VccMin)/(VccMax - VccMin); } charge = digitalRead(LTC4067_CHRG_PIN); sensor_node.send(batteryVoltageMsg.set(batteryVoltage, 3)); // Send (V) sensor_node.sendBatteryLevel(battPct); Serial.print("BattPct: "); Serial.print(battPct); Serial.println("% "); oled.setCursor(6); oled.print("Batt: "); oled.print(batteryVoltage,1); oled.print("V"); if (charge) oled.print("*"); else oled.print(" "); } void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0 Serial.print(":"); if(digits < 10) Serial.print('0'); Serial.print(digits); }
It requires the attached libraries.
WRT the display: I've found that there are different drivers for different size displays, which require corresponding different libraries. There is a 0.96" version, which I originally used, which used the SSD1306 driver and library, whereas many of the 1.3" versions use the SH1106. All I know is that the 1.3" display I use worked straight away, with the original library - YMMV.
-
-
@MikeF Maybe an idea about turning on the display.. how about adding a PIR, and turn on the display if movement is detected..? My guess is that it'll lower the power consumption, and still show info when someone is nearby.
-
Very nice! And I love @Stric's idea to use a PIR. The display only uses 5-13mA (source) but a pir uses even less.
-
I've since added a simple on/off switch, connected to D2, and changed the sketch to read the state of this pin and send a sleep/wake command to the SSD1306.
-
I experienced some burn in effect on this SSD1306 displays after a few months of running, so turning the display off is a good idea!