/* ESP-32 Airconditioning system control */ //SYSTEM PARAMETERS
//Input Pins
#include <WiFi.h> const uint8_t powerPin = 36;
#include <EasyButton.h> const uint8_t modePin = 39;
#include <DHTesp.h> const uint8_t tempDownPin = 34;
#include <AsyncMqttClient.h> const uint8_t tempUpPin = 35;
#include <U8g2lib.h> const uint8_t DHTPin = 32;
#include <WiFiClient.h>
#include <WebServer.h> //Output Pins
#include <ESPmDNS.h> const uint8_t buzzerPin=26;
#include <Update.h> const uint8_t compressorPin = 33;
const uint8_t fanPin = 25;
//Network Parameters
#define WIFI_SSID "IoTnet" //DHT Sensor
#define WIFI_PASSWORD "1l4E1g0R9@2n9D" DHTesp dht;
#define MQTT_HOST IPAddress(10, 26, 178, 10) int dhtPin = 32;
#define MQTT_PORT 1883 //const uint8_t tempSensor = A4;
String mqttTopic = "ac_GuestRoom";
const char* host = "esp32"; //System Variables
WebServer server(80); float sensorTemperature;
String sensorTempOld;
//OLED Display Driver float setTemperature = 21.00;
U8G2_SH1106_128X64_NONAME_1_HW_I2C float setTempOld = 0;
u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); long readTempTimer = 0;
int acPower = 0;
//External Timers int acMode = 1;
extern "C" { char ip[32];
#include "freertos/FreeRTOS.h" char acPowerChar[15];
#include "freertos/timers.h" char acModeChar[15];
} char acSetTempChar[15];
TimerHandle_t mqttReconnectTimer; char acTempSensor[15];
TimerHandle_t wifiReconnectTimer; String IPaddress;
//Local Button Parameters void connectToWifi() {
#define btnPower_PIN 36 [Link]("Connecting to Wi-Fi...");
#define btnMode_PIN 39 [Link](WIFI_SSID, WIFI_PASSWORD);
#define btnTempUp_PIN 35 }
#define btnTempDn_PIN 34
void connectToMqtt() {
//Declare EasyButtons [Link]("Connecting to MQTT...");
EasyButton btnPower(btnPower_PIN); [Link]();
EasyButton btnMode(btnMode_PIN, 35, true, false); }
EasyButton btnTempUp(btnTempUp_PIN, 35, true,
false); void WiFiEvent(WiFiEvent_t event) {
EasyButton btnTempDn(btnTempDn_PIN, 35, true, [Link]("[WiFi-event] event: %d\n", event);
false); switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
//Define Async MQTT Client [Link]("WiFi connected");
AsyncMqttClient mqttClient; [Link]("IP address: ");
[Link]([Link]());
//MQTT Variables connectToMqtt();
char mqttCmndPower[30]; IPaddress = "NETWORK: " +
char mqttCmndMode[30]; [Link]().toString();
char mqttCmndTemp[30]; [Link](ip,32);
char mqttStatPower[30]; break;
char mqttStatMode[30]; case SYSTEM_EVENT_STA_DISCONNECTED:
char mqttStatTemp[30]; [Link]("WiFi lost connection");
char mqttStatSensor[30];
xTimerStop(mqttReconnectTimer, 0); // ensure }
we don't reconnect to MQTT while reconnecting to
Wi-Fi void onMqttUnsubscribe(uint16_t packetId) {
xTimerStart(wifiReconnectTimer, 0); [Link]("Unsubscribe acknowledged.");
IPaddress = "NETWORK OFFLINE"; [Link](" packetId: ");
[Link](ip,32); [Link](packetId);
break; }
}
} void onMqttMessage(char* topic, char* payload,
AsyncMqttClientMessageProperties properties, size_t
void onMqttConnect(bool sessionPresent) { len, size_t index, size_t total) {
[Link]("Connected to MQTT."); [Link](topic);
[Link]("Session present: "); [Link](":");
[Link](sessionPresent); [Link](payload);
uint16_t packetIdSub1 = String strMqttCmndPower = "cmnd/" + mqttTopic +
[Link](mqttCmndPower, 0); "/POWER";
[Link]("Subscribing to Topic: ~/POWER, String strMqttCmndMode = "cmnd/" + mqttTopic +
packetId: "); "/MODE";
[Link](packetIdSub1); String strMqttCmndTemp = "cmnd/" + mqttTopic +
uint16_t packetIdSub2 = "/TEMP";
[Link](mqttCmndMode, 0); String mqttSubTopic=String (topic);
[Link]("Subscribing to Topic: ~/MODE, packetId: String mqttSubPayload=String(payload);
"); if (mqttSubTopic==strMqttCmndPower) {
[Link](packetIdSub2); if (mqttSubPayload=="1"){
uint16_t packetIdSub3 = acPower=1;
[Link](mqttCmndTemp, 0); } else {
[Link]("Subscribing to Topic: ~/TEMP, packetId: acPower=0;
"); }
[Link](packetIdSub3); }
/*[Link]("test/lol", 0, true, "test 1"); if (mqttSubTopic==strMqttCmndMode) {
[Link]("Publishing at QoS 0"); if (mqttSubPayload=="1"){
uint16_t packetIdPub1 = acMode=1;
[Link]("test/lol", 1, false, "test 2"); } else {
[Link]("Publishing at QoS 1, packetId: "); acMode=0;
[Link](packetIdPub1); }
uint16_t packetIdPub2 = }
[Link]("test/lol", 2, false, "test 3"); if (mqttSubTopic==strMqttCmndTemp) {
[Link]("Publishing at QoS 2, packetId: "); setTemperature=[Link]();
[Link](packetIdPub2);*/ [Link](setTemperature);
pubMqtt(); }
} }
void void onMqttPublish(uint16_t packetId) {
onMqttDisconnect(AsyncMqttClientDisconnectReason [Link]("Publish acknowledged.");
reason) { [Link](" packetId: ");
[Link]("Disconnected from MQTT."); [Link](packetId);
}
if ([Link]()) {
xTimerStart(mqttReconnectTimer, 0); void btnPowerPressed() {
} [Link]("POWER Button has been pressed!");
} if (acPower==0) {
acPower=1;
void onMqttSubscribe(uint16_t packetId, uint8_t qos) } else {
{ acPower=0;
[Link]("Subscribe acknowledged."); }
[Link](" packetId: "); pubMqtt();
[Link](packetId); beep();
[Link](" qos: "); }
[Link](qos);
void btnModePressed() { }
[Link]("MODE Button has been pressed!");
if (acPower==1){ /*
if (acMode==1){ * Login page
acMode=0; */
} else {
acMode=1; const char* loginIndex =
} "<form name='loginForm'>"
//powerState=false; "<table width='20%' bgcolor='A09F9F'
pubMqtt(); align='center'>"
beep(); "<tr>"
} "<td colspan=2>"
} "<center><font size=4><b>ESP32 Login
Page</b></font></center>"
void btnTempUpPressed() { "<br>"
[Link]("TEMP UP Button has been pressed!"); "</td>"
if (acPower==1){ "<br>"
if (setTemperature < 26) { "<br>"
setTemperature++; "</tr>"
} "<td>Username:</td>"
beep(); "<td><input type='text' size=25
} name='userid'><br></td>"
} "</tr>"
"<br>"
void btnTempDnPressed() { "<br>"
[Link]("TEMP DOWN Button has been "<tr>"
pressed!"); "<td>Password:</td>"
if (acPower==1){ "<td><input type='Password' size=25
if (setTemperature > 16) { name='pwd'><br></td>"
setTemperature--; "<br>"
} "<br>"
beep(); "</tr>"
} "<tr>"
} "<td><input type='submit'
onclick='check([Link])' value='Login'></td>"
void beep() { "</tr>"
digitalWrite(buzzerPin, HIGH); "</table>"
delay(100); "</form>"
digitalWrite(buzzerPin, LOW); "<script>"
} "function check(form)"
"{"
void pubMqtt(){ "if([Link]=='admin' &&
if (acPower==0) { [Link]=='admin')"
uint16_t packetIdPub1 = "{"
[Link](mqttStatPower, 1, false, "0"); "[Link]('/serverIndex')"
} else { "}"
uint16_t packetIdPub1 = "else"
[Link](mqttStatPower, 1, false, "1"); "{"
} " alert('Error Password or Username')/*displays
if (acMode==0){ error message*/"
uint16_t packetIdPub2 = "}"
[Link](mqttStatMode, 1, false, "0"); "}"
} else { "</script>";
uint16_t packetIdPub2 =
[Link](mqttStatMode, 1, false, "1"); /*
} * Server Index Page
uint16_t packetIdPub3 = */
[Link](mqttStatTemp, 1, false,
acSetTempChar); const char* serverIndex =
"<script digitalWrite(fanPin, LOW);
src='[Link]
1/[Link]'></script>" [Link](dhtPin, DHTesp::DHT22);
"<form method='POST' action='#'
enctype='multipart/form-data' id='upload_form'>" //Initialize Buttons
"<input type='file' name='update'>" [Link]();
"<input type='submit' value='Update'>" [Link]();
"</form>" [Link]();
"<div id='prg'>progress: 0%</div>" [Link]();
"<script>"
"$('form').submit(function(e){" [Link](btnPowerPressed);
"[Link]();" [Link](btnModePressed);
"var form = $('#upload_form')[0];" [Link](btnTempUpPressed);
"var data = new FormData(form);" [Link](btnTempDnPressed);
" $.ajax({"
"url: '/update'," //Initialize MQTT params
"type: 'POST'," String strMqttCmndPower = "cmnd/" + mqttTopic +
"data: data," "/POWER";
"contentType: false," String strMqttCmndMode = "cmnd/" + mqttTopic +
"processData:false," "/MODE";
"xhr: function() {" String strMqttCmndTemp = "cmnd/" + mqttTopic +
"var xhr = new [Link]();" "/TEMP";
"[Link]('progress', String strMqttStatPower = "stat/" + mqttTopic +
function(evt) {" "/POWER";
"if ([Link]) {" String strMqttStatMode = "stat/" + mqttTopic +
"var per = [Link] / [Link];" "/MODE";
"$('#prg').html('progress: ' + [Link](per*100) + String strMqttStatTemp = "stat/" + mqttTopic +
'%');" "/TEMP";
"}" String strMqttSensorTemp = "stat/" + mqttTopic +
"}, false);" "/SENSOR";
"return xhr;"
"}," [Link](mqttCmndPower,30
"success:function(d, s) {" );
"[Link]('success!')"
"}," [Link](mqttCmndMode,30);
"error: function (a, b, c) {"
"}" [Link](mqttCmndTemp,30);
"});" [Link](mqttStatPower,30);
"});" [Link](mqttStatMode,30);
"</script>"; [Link](mqttStatTemp,30);
void setup() { [Link](mqttStatSensor,30);
[Link](115200);
[Link](); // Add the callback function to be called when the
/*Initial display*/ button1 is pressed.
[Link](); //[Link](onButton1Pressed);
do { //[Link](2000,
[Link](u8g2_font_8x13B_tf); onPressedForDuration);
[Link](2,20,"INITIALIZING..."); // Add the callback function to be called when the
} while ( [Link]() ); button2 is pressed.
//[Link](onButton2Pressed);
//Set IO pin mode beep();
//pinMode(boardLED, OUTPUT); pubMqtt();
//pinMode(dhtPin, INPUT);
pinMode(buzzerPin, OUTPUT); mqttReconnectTimer = xTimerCreate("mqttTimer",
pinMode(compressorPin, OUTPUT); pdMS_TO_TICKS(2000), pdFALSE, (void*)0,
pinMode(fanPin, OUTPUT); reinterpret_cast<TimerCallbackFunction_t>(connectT
digitalWrite(buzzerPin, LOW); oMqtt));
digitalWrite(compressorPin, LOW);
wifiReconnectTimer = xTimerCreate("wifiTimer", char acTempMqtt[30];
pdMS_TO_TICKS(2000), pdFALSE, (void*)0, [Link](acTempMqtt,30);
reinterpret_cast<TimerCallbackFunction_t>(connectT uint16_t packetIdPub3 =
oWifi)); [Link](mqttStatSensor, 1, false,
acTempMqtt);
[Link](WiFiEvent); [Link](2,10);
[Link](acTempSensor,30);
[Link](onMqttConnect); }
[Link](onMqttDisconnect); readTempTimer=now;
[Link](onMqttSubscribe); }
[Link](onMqttUnsubscribe); motorControl();
[Link](onMqttMessage); [Link]();
[Link](onMqttPublish); updateDisplay();
[Link](MQTT_HOST, MQTT_PORT); }
IPaddress = "Connecting..."; void motorControl(){
[Link](ip,18); if (acPower==1) { //Sysyem power is ON
digitalWrite(fanPin, HIGH);
connectToWifi(); if (acMode==1){ //Cooling mode selected
ota(); if (sensorTemperature >= setTemperature + 1) {
} digitalWrite(compressorPin, HIGH);
} else if (sensorTemperature <= setTemperature) {
void loop() { digitalWrite(compressorPin, LOW);
[Link](); }
[Link](); } else if (acMode==0) {
[Link](); digitalWrite(compressorPin, LOW);
[Link](); }
} else if (acPower==0) {
String strSetTemperature = String(setTemperature); digitalWrite(compressorPin, LOW);
[Link](2,10); //delay(5000);
[Link](acSetTempChar,15); digitalWrite(fanPin, LOW);
if (setTemperature != setTempOld) { }
uint16_t packetIdPub1 = }
[Link]("stat/ac_GuestRoom/TEMP", 1, void updateDisplay() {
false, acSetTempChar); if (acPower==0){
setTempOld=setTemperature; [Link]();
} do {
[Link](u8g2_font_8x13B_tf);
String strACMode; [Link](2,20,"Standby Mode...");
if (acMode==1) { } while ( [Link]() );
strACMode="COOL"; } else {
} else { [Link]();
strACMode="FAN"; do {
} [Link](u8g2_font_fur49_tn);
[Link](acModeChar,15); [Link](0,50,acSetTempChar);
long now = millis(); [Link](u8g2_font_crox5h_tf);
if (now > readTempTimer + 2000) { [Link](92,29,acTempSensor);
sensorTemperature = [Link]();
String strSensor = String(sensorTemperature); [Link](u8g2_font_logisoso18_tf);
[Link](2,10); [Link](82,52,acModeChar);
[Link]("Sensor Temperature: ");
[Link](strSensor); [Link](0,54,128);
[Link]("Sensor Humidity: "); [Link](80,32,48);
[Link]([Link]()); [Link](80,0,54);
if (strSensor != sensorTempOld && strSensor != [Link](u8g2_font_5x7_tr);
"nan"){
sensorTempOld = strSensor; [Link](0,64,ip);
//String strSensor = String(sensorTemperature); [Link](82,8,"ROOM TEMP");
} while ( [Link]() ); }
}
}
void ota(){
/*use mdns for host name resolution*/
if () { //[Link]
[Link]("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
[Link]("mDNS responder started");
/*return index page which is stored in serverIndex */
[Link]("/", HTTP_GET, []() {
[Link]("Connection", "close");
[Link](200, "text/html", loginIndex);
});
[Link]("/serverIndex", HTTP_GET, []() {
[Link]("Connection", "close");
[Link](200, "text/html", serverIndex);
});
/*handling uploading firmware file */
[Link]("/update", HTTP_POST, []() {
[Link]("Connection", "close");
[Link](200, "text/plain", ([Link]()) ?
"FAIL" : "OK");
[Link]();
}, []() {
HTTPUpload& upload = [Link]();
if ([Link] == UPLOAD_FILE_START) {
[Link]("Update: %s\n",
[Link].c_str());
[Link]();
do {
[Link](u8g2_font_8x13B_tf);
[Link](2,20,"Firmware Update...");
} while ( [Link]() );
if () {
//start with max available size
[Link](Serial);
}
} else if ([Link] == UPLOAD_FILE_WRITE) {
/* flashing firmware to ESP*/
if ([Link]([Link], [Link]) !=
[Link]) {
[Link](Serial);
}
} else if ([Link] == UPLOAD_FILE_END) {
if ([Link](true)) { //true to set the size to the
current progress
[Link]("Update Success:
%u\nRebooting...\n", [Link]);
} else {
[Link](Serial);
}
}
});
[Link]();