Weather Station with
Nokia 5110 Display
ESP8266 Weather Station with Display and DHT22 Temperature - Humidity Sensor (Video)
Source Code for NodeMCU (Arduino Compiler):
/******************************************************************
Written by Sayemul Islam [Temple University]
Device used: NodeMCU 1.0 (ESP-12 Module) + DHT22 + Nokia 3110/PCD8544 display with Blynk Library
Wifi Chip ESP8266; FTDI Chip: CH340G (New Model)
Wifi Connection Security: Auto (WPA or WPA2) - PSK
Serial Communication Baud Rate 115200
Version 5.0.0 - Single Home Screen with AC Control.
Circuit Connection:
NodeMCU Nokia 5110 Description
ESP8266 PCD8544
D3 (1) RST /Or connect to Vcc via 1K ohm.
D6 (2) CE/CS Output from ESP to chip select/enable display / SCK
D5 (3) DC Output from display data/command to ESP / SPIWP
D2 (4) DIN Output from ESP SPI MOSI to display data input
D1 (5) CLK Output from ESP SPI clock / SCLK
3V (6) VCC 3.3V from Huzzah to display / HIGH
GND (7) LIGHT Through resistance to ground to turn the backlight on / GND
GND (8) GND Ground
DHT22(AM2302) Pin (1) --> +3.3 Vcc (NodeMCU)
Pin (2) --> Data (DHTPIN D3/ANY)
Pin (3) --> N/C
Pin (4) --> Gnd (NodeMCU)
// Connect a 10K pull-up resistor from pin 2 (data) to pin 1 (Vdd) of the DHT22 sensor.
// Connect a 10nF (104) capacitor between +ve and -ve leads.
Connect AC Fan Relay to D0 or LED via 1K ohm.
Connect AC Compressor Relay to D8 or LED via 1K ohm.
******************************************************************/
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <SPI.h> // for PCD8544
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h> // 48 × 84 pixels matrix LCD controller/driver. PCD8544
#include <DHT.h>
// You should get the Auth Token from the Blynk App. Go to the Project Settings (nut icon).
char auth[] = "XXXXXX2e3b594fbb88156682cXXXXXXX";
// Your WiFi credentials. Set password to "" for open networks.
char ssid[] = "WiFi Network";
char pass[] = "PaSSw0rd";
#define CompSwc D8 // Connected to Compressor Relay
#define FanSwc D0 // Connected to Manual Fan Control
#define DHTPIN D7 // DHT22 Data Pin
#define DHTTYPE DHT22 // DHT 22, AM2302, AM2321
DHT dht(DHTPIN, DHTTYPE);
SimpleTimer timer;
unsigned long previousMillis = 0; // Temp variable to store milliseconds
const long interval = 2000; // interval at which to send disp info (milliseconds)
int TempPreset=66;
Adafruit_PCD8544 display = Adafruit_PCD8544(D1, D2, D5, D6, D3); // For NodeMCU // Minimizing Pin uses.
void setup() {
Serial.begin(115200);
Blynk.begin(auth, ssid, pass);
//Blinking program while connecting
Blynk.virtualWrite(V11, 255); delay(300); Blynk.virtualWrite(V11, 0); delay(300);
Blynk.virtualWrite(V11, 255); delay(300); Blynk.virtualWrite(V11, 0); delay(300);
Serial.println("Connection Established.");
Serial.print("Signal Strength : "); Serial.print(WiFi.RSSI()); Serial.println(" dBm ");
pinMode(D0, OUTPUT); // Fan Relay Switch Control
pinMode(D4, OUTPUT); // PWM Brightness Control for LCD
pinMode(D8, OUTPUT); // AC Compressor Relay Control
dht.begin();
display.begin();
display.setContrast(50); // Set LCD contrast from here.
analogWrite(D4, 255); // PWM brightness should vary from 255 to 0.
display.clearDisplay(); introdisplay();
display.clearDisplay(); wifiinfodisplay();
timer.setInterval(30000, sendSensor); // 30 Sec Delay
}
void loop() {
Blynk.run();
timer.run();
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
display.clearDisplay();
weatherdisplay();
previousMillis = currentMillis;
}
Control();
}
void ResetSwitch(int rest)
{
if(rest == 1) {
//digitalWrite(D3, HIGH); // Need to set GPIO#0 to HIGH to solve restart error problem.
ESP.restart();
} // Restart command from Blynk App
}
//-------------------------------------------------------------------------------------------------
void FanSwitch(int fswc) // Eliminate / Minimize this function.
{
if(fswc == 1) {
//digitalWrite(CompSwc, HIGH);
} // AC Compressor ON
else {
//digitalWrite(CompSwc, LOW);
} // AC Compressor OFF
}
//-------------------------------------------------------------------------------------------------
void sendSensor()
{
Serial.println();
//----------------------------------AM2303/DHT22---------------------------------------
float h = dht.readHumidity();
float t = dht.readTemperature();
float f = dht.readTemperature(true);
float hif = dht.computeHeatIndex(f, h); // Compute heat index in Fahrenheit (the default)
float hic = dht.computeHeatIndex(t, h, false); // Compute heat index in Celsius (isFahreheit = false)
String ID1 = "DHT22 -> "; String HUM = "Humidity: "; String TEM = "Temp: ";
String INDX = " Feels Like: "; String PER = "% "; String SLS = " / ";
String Tex1 = ID1 + HUM + h + PER + TEM + t + (char)176 + "C" + SLS + f + (char)176 + "F" + INDX + hic + (char)176 + "C" + SLS + hif + (char)176 + "F";
Serial.println(Tex1);
if (!isnan(h))
{
// Sending data for DHT22
Blynk.virtualWrite(V1, h); // Writing Humidity on V1
Blynk.virtualWrite(V2, t); // Writing Temp DegC (DHT22) on V2
Blynk.virtualWrite(V3, f); // Writing Temp DegF (DHT22) on V3
Blynk.virtualWrite(V4, hif); // Writing Real Feel DegF (DHT22) on V4
Blynk.virtualWrite(V5, hic); // Writing Real Feel DegC (DHT22) on V5
Blynk.virtualWrite(V6, TempPreset); // Writing Temperature Preset on V6
Blynk.virtualWrite(V11, 255); delay(300); Blynk.virtualWrite(V11, 0); // Activity LED
}
if (isnan(h)) {
Serial.println("Data read error from DHT22 sensor !");
Blynk.virtualWrite(V12, 255); // Turn on Error LED bit
return;
}
Blynk.virtualWrite(V12, 0); // Turn off Error LED bit
}
//-----------------------------Virtual Switches-------------------------------------
// Reset function
int BlynkRSTSwitch = 0; // default = off state for virtual button
BLYNK_WRITE(V20) // Using V20 for reset command from the App;
{
BlynkRSTSwitch = param.asInt();
ResetSwitch(BlynkRSTSwitch);
}
// ------------------------------Control Function ------------------------------------
int BlynkFANswitch = 0; // default = off for Virtual Button
BLYNK_WRITE(V10) // Using V10 for Controlling ON/OFF for Air Conditioner
{
BlynkFANswitch = param.asInt();
FanSwitch(BlynkFANswitch);
Serial.println(""); Serial.print("AC Fan Status:"); Serial.println(BlynkFANswitch);
display.clearDisplay(); display.setTextSize(1); display.setCursor(0,0);
display.setTextColor(BLACK);
display.print(" AC Fan ");
display.setTextColor(WHITE, BLACK);
display.println("Switch");
display.setCursor(23,23); display.setTextSize(2); display.setTextColor(BLACK);
if(BlynkFANswitch==0) {display.println("AUTO");}
else {display.println(" ON ");}
FanSymbol();
display.display();
Control();
delay(500); return;
}
// Temperature Control Function ----------------------------------------
BLYNK_WRITE(V0) // Using V0 for temp data from the App Slider;
{
int TempVariable = param.asInt();
TempPreset = TempVariable;
Serial.println(""); Serial.print("Temperature Sent:"); Serial.println(TempPreset);
Blynk.virtualWrite(V6, TempPreset); // Writing Preset Temp on V6
display.clearDisplay(); display.setTextSize(1); display.setCursor(0,0);
display.setTextColor(BLACK);
display.println("Set Temp:");
ThermoSymbol();
display.setCursor(28,21); display.setTextSize(2); display.setTextColor(BLACK);
display.print(TempPreset);
display.drawCircle(55, 23, 2, BLACK);
display.setCursor(61,21);
display.println("F");
display.display();
Control();
if(TempPreset < dht.readTemperature(true)) {Blynk.virtualWrite(V7, 255);}
else {Blynk.virtualWrite(V7, 0);}
delay(500);
return;
}
//---------------------------------------Intro Displays-------------------------------------
void introdisplay(void) {
display.setTextSize(1);
display.setCursor(0,0);
display.setTextColor(BLACK);
display.println("ESP8266");
display.setCursor(0,13);
display.println("WeatherStation");
display.fillRect(0,23,84,24, BLACK);
display.setTextSize(2);
display.setCursor(0,28);
display.setTextColor(WHITE, BLACK);
display.println("TEMSENS");
display.display();
delay(2000);
}
void wifiinfodisplay(void) {
display.setTextSize(1);
display.setCursor(0,0);
display.setTextColor(WHITE, BLACK); // 'inverted' text
display.println("WiFi Connected");
display.setCursor(0,16);
display.setTextColor(BLACK);
display.print(""); display.println(ssid);
display.print(""); display.println(WiFi.localIP());
display.print(""); display.print("RSSI:"); display.print(WiFi.RSSI()); display.println(" dBm");
display.display();
delay(2000);
}
//---------------------------------------Home Displays-------------------------------------
void weatherdisplay(void) // Program inside is a sample display!
{
if(isnan(dht.readTemperature(true))) {
return;
}
else
{
// text display tests
display.setTextSize(1);
display.fillRect(0,0,84,8, BLACK); // Black Background
display.setTextColor(WHITE, BLACK);
display.setCursor(3,0);
display.println("Weather Today");
display.drawLine(0,9,84,9, BLACK); //(x1,y1,x2,y2)
display.setTextColor(BLACK);
display.setCursor(24,13);
display.print(dht.readTemperature(true)); // F display
display.fillCircle(57, 14, 1, BLACK);
display.setCursor(60,13);
display.println("F ");
display.drawLine(24,23,64,23, BLACK); //(x1,y1,x2,y2)
display.setCursor(24,26);
display.print(dht.readTemperature()); // C display
display.fillCircle(57, 27, 1, BLACK);
display.setCursor(60,26);
display.println("C");
display.drawLine(24,36,64,36, BLACK); //(x1,y1,x2,y2)
display.setCursor(20,39);
display.print(dht.readHumidity()); // %RH display
display.setCursor(53,39);
display.println("%");
display.setCursor(61,39);
display.println("RH");
ThermoSymbol(); // Thermometer Symbol drawn manually!
display.display();
}
}
//---------------------------------------Functional Displays-------------------------------------
void Control(void) {
// Serial.print(TempPreset); Serial.print(" <? "); Serial.println(dht.readTemperature(true));
if(TempPreset < dht.readTemperature(true)) {
digitalWrite(D0, HIGH); // AC Fan ON
digitalWrite(D8, HIGH);} // AC Compressor
else if((TempPreset >= dht.readTemperature(true)) && (BlynkFANswitch==1)) {
digitalWrite(D0, HIGH); // AC Fan ON
digitalWrite(D8, LOW);} // AC Compressor
else {
digitalWrite(D0, LOW);
digitalWrite(D8, LOW);
}
return;
}
void ThermoSymbol(void)
{
display.drawLine(4,16,4,34, BLACK); // internal vertical white line
display.drawLine(8,16,8,34, BLACK); // internal vertical white line
display.drawCircle(6, 14, 2, BLACK); // Top Circle
display.drawCircle(6, 40, 5, BLACK); // Bottom Circle
display.fillCircle(6, 40, 2, BLACK); // Bottom Fill circle
display.drawLine(5,16,5,35, WHITE); // internal vertical white line
display.drawLine(6,15,6,35, WHITE); // internal vertical white line
display.drawLine(6,16,6,38, BLACK); // overlaping vertical black line
display.drawLine(7,16,7,35, WHITE); // internal vertical white line
display.drawLine(9,18,11,18, BLACK); // Scale mark
display.drawLine(9,23,10,23, BLACK); // Scale mark
display.drawLine(9,28,10,28, BLACK); // Scale mark
display.drawLine(9,33,11,33, BLACK); // Scale mark
}
void FanSymbol(void)
{
display.drawCircle(9, 30, 9, BLACK); // Outer Circle
display.fillCircle(9, 30, 2, BLACK); // Inner Circle
display.drawLine(2,28,16,32, BLACK); // Fan Blade
display.drawLine(2,32,16,28, BLACK); // Fan Blade
display.drawLine(7,21,11,39, BLACK); // Fan Blade
display.drawLine(11,21,7,39, BLACK); // Fan Blade
}