#include <WiFi.h>
#include <DHTesp.h>
#include <WiFiUdp.h>
#include <LiquidCrystal.h>
#include "PubSubClient.h"
#include "ThingSpeak.h"
// Define pins
#define DHTPIN 15
#define buzzer 2
#define relay 4
// Define some common notification
char* WATER_LOW = "Water level is low! Please add more water!";
char* HUMID_LOW = "Humidity level is low! Turn on humidifier";
char* HUMID_HIGH = "Humidity level is high! Turn off humidifier";
char* current_noti = nullptr;
// ThingSpeak APIs
unsigned long ChannelNumber = 2240308;
const char* WriteApiKey = "ULYCYQFTU9I2628P";
unsigned long lastMillisInternet = 0;
unsigned long lastMillisFog = 0;
unsigned long lastMillisBuzz = 0;
// Wifi and MQTT server
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "test.mosquitto.org";
const int MQTTport = 1883;
// Global humid level variables
int upperHumidlv = 60;
int lowerHumidlv = 40;
// Trigger an IFTTT notification
const char* IFTTThost = "maker.ifttt.com";
const char* water = "/trigger/LowWater/with/key/e8JvVmWXHQ-dcP6btXIXAjKLdaaZJDt-0I4hOvaFxov";
const int IFTTTport = 80;
DHTesp dhtSensor;
WiFiClient espClient;
PubSubClient mqttClient(espClient);
LiquidCrystal lcd(25, 13, 12, 14, 27, 26);
// Wifi connection function
void wifiConnect() {
Serial.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Serial.println(" Connected!");
}
// Send notification to your phone through IFTTT
void sendNotification(const char* request){
while (!espClient.connect(IFTTThost, IFTTTport))
delay(1000);
espClient.print("GET " + String(request) + " HTTP/1.1\r\n" +
"Host: " + IFTTThost + "\r\n" +
"Connection: Close\r\n\r\n");
delay(500);
}
// Recieve message from node-red
void callback(char* topic, byte* message, unsigned int length) {
String stMessage;
for (int i = 0; i < length; i++) {
stMessage += (char)message[i];
}
String topicName(topic);
if(topicName == "21127243_21127296_21127300/status"){
if(stMessage == "on"){
turnOn();
}
else turnOff();
}
if(topicName == "21127243_21127296_21127300/upper") {
upperHumidlv = stMessage.toInt();
Serial.println(upperHumidlv);
}
if(topicName == "21127243_21127296_21127300/lower") {
lowerHumidlv = stMessage.toInt();
Serial.println(lowerHumidlv);
}
}
// Send notification to node-red
void buzz(char* noti){
//tone(buzzer, 100, 500);
Serial.println(noti);
ledcAttachPin(buzzer, 0);
ledcWriteNote(0, NOTE_D, 4);
delay(200);
ledcWriteNote(0, NOTE_F, 4);
delay(200);
ledcDetachPin(buzzer);
}
void mqttReconnect() {
Serial.print("Attempting MQTT connection... ");
if (mqttClient.connect("21127243_21127296_21127300")) {
Serial.println("Connected!");
mqttClient.subscribe("21127243_21127296_21127300/onoff");
mqttClient.subscribe("21127243_21127296_21127300/upper");
mqttClient.subscribe("21127243_21127296_21127300/lower");
} else {
Serial.println("Failed");
}
}
// Send temperature and humidity data to ThingSpeak
void TSWrite(float t, float h){
ThingSpeak.setField(1, h);
ThingSpeak.setField(2, t);
int returncode = ThingSpeak.writeFields(ChannelNumber, WriteApiKey);
if(returncode == 200)
Serial.println("Uploaded to ThingSpeak");
else Serial.println("Error! HTTP code error " + String(returncode));
}
void turnOn(){
digitalWrite(relay, HIGH);
}
void turnOff(){
lcd.noDisplay();
digitalWrite(relay, LOW);
}
// Basic setup
void setup() {
Serial.begin(9600);
pinMode(buzzer, OUTPUT);
pinMode(relay, OUTPUT);
ledcSetup(0, 200, 14);
lcd.begin(16, 2);
//wifiConnect();
mqttClient.setServer(mqttServer, MQTTport);
mqttClient.setCallback(callback);
dhtSensor.setup(DHTPIN, DHTesp::DHT22);
ThingSpeak.begin(espClient);
}
void loop() {
if (!mqttClient.connected()) {
mqttReconnect();
}
mqttClient.loop();
// Preset water level for testing
int waterlv = 10;
// Read temperature and humidity through DHT22
TempAndHumidity data = dhtSensor.getTempAndHumidity();
float t = data.temperature;
float h = data.humidity;
lcd.setCursor(0, 0);
lcd.print("Temp: " + String(t) + "\xDF" + "C ");
lcd.setCursor(0, 1);
lcd.print("Humid: " + String(h) + "% ");
if (waterlv < 25) {
if (!lastMillisBuzz) {
current_noti = WATER_LOW;
buzz(current_noti);
lastMillisBuzz = 1;
}
else if (millis() - lastMillisBuzz > 2000){
current_noti = WATER_LOW;
buzz(current_noti);
lastMillisBuzz = millis();
sendNotification(water);
}
digitalWrite(relay, LOW);
}
else {
if (millis() - lastMillisFog > 15000) {
if (h > upperHumidlv) {
current_noti = HUMID_HIGH;
buzz(HUMID_HIGH);
digitalWrite(relay, LOW);
//sendNotification(highHumidRequest);
}
else if (h < lowerHumidlv) {
current_noti = HUMID_LOW;
buzz(HUMID_LOW);
digitalWrite(relay, HIGH);
//sendNotification(lowHumidRequest);
}
lastMillisFog = millis();
}
}
if (millis() - lastMillisInternet > 20000) {
// Send temperature and humidty data to web
if (mqttClient.connected()) {
char buffer[100];
sprintf(buffer, "{\"temperature\":%f,\"humidity\":%f,\"waterlv\":%d}", t, h, waterlv);
mqttClient.publish("21127243_21127296_21127300/sensor", buffer);
if(current_noti != nullptr) {
mqttClient.publish("21127243_21127296_21127300/notification", current_noti);
current_noti = nullptr;
}
mqttClient.loop();
Serial.println("Sent data to NODE-RED");
TSWrite(t, h);
lastMillisInternet = millis();
}
delay(500);
}
}