Temperature and humidity tracker
Table Of Content
Ingredients
Hardware
Software
Arduino Libraries
- ESP8266WiFi
- ArduinoJson
- InfluxDbClient
- TM1637Display
- DHT
APIs
Code
#include "secrets.h"
// Include WiFi library
#include <ESP8266WiFi.h>
// WiFi config
char ssid[] = SECRET_SSID; // network SSID
char pass[] = SECRET_PASS; // network password
WiFiClient networkClient;
// Add JSON support
#include <ArduinoJson.h>
// Add weather api (refer to https://openweathermap.org/current)
const char weather_server[] = "api.openweathermap.org";
const char weather_query[] = "GET /data/2.5/weather?lat=%s&lon=%s&units=metric&APPID=%s";
const char weather_message[] = "Outside: %f --- Inside: %f";
static unsigned long weather_api_time = -600000; // Used to time the API calls
static float h_api;
static float t_api;
// MASTER InfluxDB library
#include <InfluxDbClient.h>
// MASTER InfluxDB cfg
InfluxDBClient client_idb(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN);
Point pointDevice("device_status");
#define DB_DELAY 120000 //Write to DB every 2 min
// Include display library
#include <TM1637Display.h>
#define TM1637_CLK D1 // chip clock
#define TM1637_DIO D2 // chip digital I/O
#define DELAY 500 // delay between display updates
TM1637Display display(TM1637_CLK, TM1637_DIO);
// Set button pin
#define BUTTON D5
#define BUTTON_DEBOUNCE_DELAY 20
// Include DHT sensor libraries
#include <DHT.h>
// DHT sensor
#define DHTPIN D3
#define DHTTYPE DHT11
// Initialize DHT sensor
DHT dht = DHT(DHTPIN, DHTTYPE);
// Flag to show temp or humidity
static int show_temp = 0;
// Variables to store temperature and humidity
static float h;
static float t;
void setup() {
Serial.begin(115200);
Serial.println(F("\n\nInit setup.\n"));
dht.begin();
Serial.println(F("DHT setup completed.\n"));
// Set BUTTON pin as input with pull-up
pinMode(BUTTON, INPUT_PULLUP);
Serial.println(F("BUTTON setup completed.\n"));
// Set wifi
WiFi.mode(WIFI_STA);
Serial.println(F("WIFI setup completed.\n"));
// Set insecure connection to skip server certificate validation
client_idb.setInsecure();
Serial.println(F("\nSetup completed.\n"));
}
void loop() {
// Used to time sensor reading
static unsigned long time_temp = 0;
// Save IP address
String IP_local = "No connection";
// Display brightness
static unsigned long display_timer = 0;
if (millis() - display_timer > 5000) {
display.setBrightness(0x00);
}
// Display updates timer
static unsigned long time_monitor = 0;
// DB Initialization flag
int static init_db = 0;
// DB write timing (skip first 120 seconds)
static unsigned long time_db = 120000;
if (isButtonPressed() == true) { // button pressed
// Set display to maximum brightness
display.setBrightness(0x07);
show_temp = !show_temp;
display_timer = millis();
}
if (millis() - time_temp > 2000) {
h = dht.readHumidity(); // humidity percentage, range 20-80% (±5% accuracy)
t = dht.readTemperature(); // temperature Celsius, range 0-50°C (±2°C accuracy)
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F("\n"));
// Set timer
time_temp = millis();
}
if (show_temp == 0) {
if (millis() - time_monitor > DELAY) {
uint8_t data[] = {
SEG_B | SEG_C | SEG_F | SEG_E | SEG_G, // H
0x00, // 0
0x00, // 0
0x00 // 0
};
data[2] = display.encodeDigit(int(int(h / 10) % 10));
data[3] = display.encodeDigit(int(int(h) % 10));
display.setSegments(data);
time_monitor = millis();
}
}
else {
if (millis() - time_monitor > DELAY) {
uint8_t data[] = {
0x00, // 0
0x00, // 0
0x00, // 0
SEG_A | SEG_D | SEG_E | SEG_F // C
};
data[0] = display.encodeDigit(int(int(t / 10) % 10));
data[1] = display.encodeDigit(int(int(t) % 10));
display.setSegments(data);
time_monitor = millis();
}
}
// Connect to wifi if not connected
IP_local = connectionToWiFi();
getCurrentWeather();
// Do TB things
if (millis() - time_db > DB_DELAY && t > 0 && h > 0)
{
// Save data to DB
check_influxdb();
if (init_db == 0)
{ // set tags
pointDevice.addTag("device", "ESP8266");
pointDevice.addTag("SSID", WiFi.SSID());
init_db = 1;
}
WriteMultiToDB(t, h);
time_db = millis();
}
}
String connectionToWiFi() {
String IP;
// connect to WiFi (if not already connected)
if (WiFi.status() != WL_CONNECTED) {
Serial.print(F("Connecting to SSID: "));
Serial.println(SECRET_SSID);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
// Signal something is wrong
display.setBrightness(0x00);
uint8_t data[] = {
SEG_B | SEG_C | SEG_E | SEG_F | SEG_G, // H
SEG_A | SEG_D | SEG_E | SEG_F | SEG_G, // E
SEG_D | SEG_E | SEG_F, // L
SEG_A | SEG_B | SEG_E | SEG_F | SEG_G // P
};
display.setSegments(data);
delay(500);
}
Serial.println(F("\nConnected!"));
printWifiStatus();
IP = WiFi.localIP().toString();
return IP;
}
else {
IP = WiFi.localIP().toString();
return IP;
}
}
void printWifiStatus() {
Serial.println(F("\n=== WiFi connection status ==="));
// SSID
Serial.print(F("SSID: "));
Serial.println(WiFi.SSID());
// signal strength
Serial.print(F("Signal strength (RSSI): "));
Serial.print(WiFi.RSSI());
Serial.println(" dBm");
// current IP
Serial.print(F("IP Address: "));
Serial.println(WiFi.localIP());
// subnet mask
Serial.print(F("Subnet mask: "));
Serial.println(WiFi.subnetMask());
// gateway
Serial.print(F("Gateway IP: "));
Serial.println(WiFi.gatewayIP());
// DNS
Serial.print(F("DNS IP: "));
Serial.println(WiFi.dnsIP());
Serial.println(F("==============================\n"));
}
boolean isButtonPressed() {
static byte lastState = digitalRead(BUTTON); // the previous reading from the input pin
for (byte count = 0; count < BUTTON_DEBOUNCE_DELAY; count++) {
if (digitalRead(BUTTON) == lastState) return false;
delay(1);
}
lastState = !lastState;
return lastState == HIGH ? false : true;
}
void check_influxdb() {
// Check server connection
if (client_idb.validateConnection()) {
Serial.print(F("Connected to InfluxDB: "));
Serial.println(client_idb.getServerUrl());
} else {
Serial.print(F("InfluxDB connection failed: "));
Serial.println(client_idb.getLastErrorMessage());
}
}
void WriteMultiToDB(float temp, float hum) {
// Store measured value into point
pointDevice.clearFields();
pointDevice.addField("temperature", temp);
pointDevice.addField("humidity", hum);
pointDevice.addField("api_temperature", t_api);
pointDevice.addField("api_humidity", h_api);
pointDevice.addField("temperature_delta", temp - t_api);
pointDevice.addField("humidity_delta", hum - h_api);
Serial.print(F("Writing: "));
Serial.println(pointDevice.toLineProtocol());
if (!client_idb.writePoint(pointDevice)) {
Serial.print(F("InfluxDB write failed: "));
Serial.println(client_idb.getLastErrorMessage());
}
}
void getCurrentWeather() {
if (millis() - weather_api_time > 600000) {
// call API for current weather
if (networkClient.connect(weather_server, 80)) {
char request[128];
sprintf(request, weather_query, WEATHER_LATITUDE, WEATHER_LONGITUDE, WEATHER_API_KEY);
networkClient.println(request);
networkClient.println(F("Host: api.openweathermap.org"));
networkClient.println(F("User-Agent: ArduinoWiFi/1.1"));
networkClient.println(F("Connection: close"));
networkClient.println();
} else {
Serial.println(F("Connection to api.openweathermap.org failed!\n"));
}
while (networkClient.connected() && !networkClient.available()) delay(1); // wait for data
String result;
while (networkClient.connected() || networkClient.available()) { // read data
char c = networkClient.read();
result = result + c;
}
networkClient.stop(); // end communication
char jsonArray[result.length() + 1];
result.toCharArray(jsonArray, sizeof(jsonArray));
jsonArray[result.length() + 1] = '\0';
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, jsonArray);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
Serial.print(F("Location: "));
Serial.println(doc["name"].as<String>());
Serial.print(F("Country: "));
Serial.println(doc["sys"]["country"].as<String>());
Serial.print(F("Temperature (°C): "));
Serial.println((float)doc["main"]["temp"]);
t_api = (float)doc["main"]["temp"];
Serial.print(F("Humidity (%): "));
Serial.println((float)doc["main"]["humidity"]);
h_api = (float)doc["main"]["humidity"];
// Set timer
weather_api_time = millis();
}
}
Results

