#include <DHTesp.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <HTTPClient.h>
#include <UrlEncode.h>
#include <WiFi.h>
#include <IRremote.h>
#define DHT_PIN 12
#define LDR_PIN 34
#define LED_SLC 22
#define LED_SDA 21
#define LED 4
#define BUZZER 0
#define RECEIVER 35
Adafruit_SSD1306 display(128, 64, &Wire, LED_SDA, LED_SLC);
IRrecv receiver(RECEIVER);
DHTesp dhtSensor;
/* WiFi */
const char* ssid = "Wokwi-GUEST"; // log in WiFi
const char* password = "";
float temperature = NAN;
float humidity = NAN;
float lightLevel = NAN;
float minTemp = NAN;
float maxTemp = NAN;
float minHum = NAN;
float maxHum = NAN;
float minLight = 400;
float interval;
unsigned int startTime, currentTime;
bool normal;
String abTemp; // abnormal temperature warning
String abHum; // abnormal humidity warning
String abLight; // abnormal light level warning
/* WhatsApp */
String phoneNumber; // receives environmental conditions report
String apiKey; // password used to send the report
/* IR remote */
float value = 0;
int mode = 1;
String val;
bool finished = false;
void setup() {
Serial.begin(9600);
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
Wire.begin(21, 22);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextColor(WHITE);
pinMode(LDR_PIN, INPUT);
pinMode(LED, OUTPUT);
pinMode(BUZZER, OUTPUT);
pinMode(RECEIVER, INPUT);
/* buzzer */
ledcSetup(1, 1000, 8); // set up buzzer
ledcAttachPin(0, 1); // attach buzzer pin
/* WiFi */
WiFi.begin(ssid, password); // connect WiFi
Serial.println("WiFi Connecting...");
while (WiFi.status() != WL_CONNECTED) {} // wait until connected
Serial.println("WiFi Connected.");
}
void loop() {
abTemp = "";
abHum = "";
abLight = "";
normal = true;
TempAndHumidity data = dhtSensor.getTempAndHumidity();
temperature = data.temperature;
humidity = data.humidity;
const float GAMMA = 0.7;
const float RL10 = 50;
float analogValue = analogRead(LDR_PIN) / 4;
float voltage = analogValue / 1024. * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
lightLevel = lux;
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.print("T: ");
display.print(tStr(temperature));
if (temperature < minTemp || temperature > maxTemp) {
display.print("!");
abTemp = "!";
normal = false;
}
display.println();
display.print("H: ");
display.print(hStr(humidity));
if (humidity < minHum || humidity > maxHum) {
display.print("!");
abHum = "!";
normal = false;
}
display.println();
display.print("L: ");
display.print(lStr(lightLevel));
if (lightLevel < minLight) {
display.print("!");
abLight = "!";
normal = false;
}
display.println();
display.display();
Serial.println();
Serial.print("Temperature: ");
Serial.print(tStr(temperature));
if (temperature < minTemp) {
Serial.print(" Too cold.");
}
if (temperature > maxTemp) {
Serial.print(" Too hot.");
}
Serial.println();
Serial.print("Humidity: ");
Serial.print(hStr(humidity));
if (humidity < minHum) {
Serial.print(" Too dry.");
}
if (humidity > maxHum) {
Serial.print(" Too humid.");
}
Serial.println();
Serial.print("Light Level: ");
Serial.print(lStr(lightLevel));
if (lightLevel < minLight) {
Serial.print(" Too dark.");
}
Serial.println();
/* LED and buzzer */
if (normal == false) {
for (int i = 1; i <= 3; i++) {
digitalWrite(LED, HIGH);
ledcWrite(1, 1); // sound the buzzer
delay(200);
digitalWrite(LED, LOW);
ledcWrite(1, 0); // stop the buzzer
delay(200);
}
}
receiver.enableIRIn();
finished = false;
unsigned int IR_begin = millis();
while ((millis()-IR_begin) < 5000 && !Serial.available() && finished == false) {
if (receiver.decode()) {
IR_begin = millis();
translateIR();
receiver.resume();
switch (mode) {
case 0:
displ("Send to = ", val);
break;
case 1:
displ("Api = ", val);
break;
case 2:
displ("min Temp = ", val);
break;
case 3:
displ("max Temp = ", val);
break;
case 4:
displ("min Hum = ", val);
break;
case 5:
displ("max Hum = ", val);
break;
case 6:
displ("min Light = ", val);
break;
case 7:
displ("Send to = ", val);
break;
}
}
}
val = "";
receiver.disableIRIn();
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim();
if (input == "nth") {
Serial.println();
Serial.print("Temperature range: ");
Serial.print(minTemp);
Serial.print(" to ");
Serial.print(maxTemp);
Serial.println("C");
Serial.print("Humidity range: ");
Serial.print(minHum);
Serial.print(" to ");
Serial.print(maxHum);
Serial.println("%");
delay(3000);
/* WhatsApp */
} else if (input == "send") {
Serial.println();
Serial.println("Please enter your phone number:");
while(!Serial.available());
if (Serial.available()) {
phoneNumber = Serial.readStringUntil('\n');
input.trim();
}
Serial.println(phoneNumber);
Serial.println();
Serial.println("Please enter your api key:");
while(!Serial.available());
if (Serial.available()) {
apiKey = Serial.readStringUntil('\n');
input.trim();
}
Serial.println(apiKey);
Serial.println();
Serial.println("How often do you want your report? (minutes)");
while(!Serial.available());
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim();
interval = input.toFloat();
}
Serial.println(interval, 0);
Serial.println();
Serial.println("This is your report: ");
String report = String("T: ") + tStr(temperature) + abTemp + " H: " + hStr(humidity) + abHum +" L: " + lStr(lightLevel) + abLight;
Serial.println(report);
Serial.println();
Serial.println("Press Enter to send the report.");
while(!Serial.available());
if (Serial.available()) {
startTime = millis();
sendReport(report);
}
}
while (Serial.available()) {
Serial.read();
}
}
currentTime = millis();
if (interval != 0 && (currentTime - startTime) >= (interval * 60000)) {
startTime = millis();
String report = String("T: ") + tStr(temperature) + abTemp + " H: " + hStr(humidity) + abHum +" L: " + lStr(lightLevel) + abLight;
sendReport(report);
}
}
String tStr(float temperature) {
return String(temperature, 1) + "C";
}
String hStr(float humidity) {
return String(humidity, 1) + "%";
}
String lStr(float lightLevel) {
return String(lightLevel, 1) + "L";
}
float parseFloatValue(String input) {
int colonIndex = input.indexOf(':');
if (colonIndex != -1) {
String valueStr = input.substring(colonIndex + 1);
valueStr.trim();
return valueStr.toFloat();
}
return NAN;
}
/* WhatsApp */
void sendReport(String report) {
Serial.println("Sending...");
String url = "https://api.callmebot.com/whatsapp.php?phone=852" + phoneNumber + "&text=" + urlEncode(report) + "&apikey=" + apiKey;
// this url tells callmebot to send the report to the phone number
HTTPClient http;
http.begin(url); // send the url to the server
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpResponseCode = http.POST(url); // receive the server's response
if (httpResponseCode == 200) {
startTime = millis();
Serial.println("Report sent.");
}
else {
Serial.println("Unable to send the report.");
}
http.end();
}
void translateIR()
{
switch (receiver.decodedIRData.command) {
case 34:
displ("TEST", "");
break;
case 2:
value = val.toFloat();
value++;
val = String(value);
break;
case 194:
val = "";
finished = true;
break;
case 224:
mode--;
if (mode == -1) {
mode = 7;
}
break;
case 168:
value = val.toFloat();
switch (mode) {
case 0:
phoneNumber = value;
Serial.println(phoneNumber);
break;
case 1:
apiKey = value;
// sendReport(report);
Serial.println(apiKey);
break;
case 2:
minTemp = value;
break;
case 3:
maxTemp = value;
break;
case 4:
minHum = value;
break;
case 5:
maxHum = value;
break;
case 6:
minLight = value;
break;
}
val = "";
finished = true;
break;
case 144:
mode++;
if (mode == 7) {
mode = 0;
}
break;
case 104:
val = val + "0";
break;
case 152:
value = val.toFloat();
value--;
val = String(value);
break;
case 176:
val = "";
break;
case 48:
val = val + "1";
break;
case 24:
val = val + "2";
break;
case 122:
val = val + "3";
break;
case 16:
val = val + "4";
break;
case 56:
val = val + "5";
break;
case 90:
val = val + "6";
break;
case 66:
val = val + "7";
break;
case 74:
val = val + "8";
break;
case 82:
val = val + "9";
break;
}
}
void displ(String str1, String str2) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.print(str1);
display.print(str2);
display.display();
}