IoT low-cost home automation wireless system

Introduction

Hello everyone. My name is Bruno Pedro and a I have a master degree in eletrical engineering.
This is the project I created to obtain my master degree.
Any questions you have, you may comment on this post. Thanks to @shramik_salgaonkar and @adam that helped me with Cayenne platform. Thank you!

IoT low-cost home automation wireless system (Experimental prototype)

This is a IoT low-cost home automation wireless system I created using Cayenne MyDevices online platform. It uses MQTT and Wi-Fi wireless protocols to estabilish communication between all equipments (Actuators, sensor, interfaces) and the online platform. It is widely compatible with all low voltage eletrical instalations (because of it’s low size and wireless capabilities) and uses low cost and widely available equipments. The system is widely configurable, manageable and usable by any user. The inteligent management implemented by this home automation system, may improve the energy efficiency of the eletric instalation where this system is implemented.

The system has:

  • A “Smart socket” that controls ON/OFF and dimming (regulation of luminous flux emitted by lamps) of 230V AC 50Hz lamps and measures eletric power and calculates eletric energy consumed by the eletric equipment connected. All this is configurable, managed and used by the user trough the online platform. This “Smart socket” is also usable to control ON/OFF and velocity control of eletric motors 230V AC 50Hz.
  • A “Smart power plug” that controls ON/OFF 230V AC 50Hz eletric loads (in this prototype a SCHUKO power plug) and measures eletric power and calculates eletric energy consumed by the lamp. All this is configurable, managed and used by the user trough the online platform.
  • Motion/presence, temperature and humidity, luminosity sensors. All that information is constantly monitored trough the online platform dashboards.
  • Interface, of a raspberry pi with a touchscreen. You can also use a smartphone, laptop, tablet, computer to implement triggers, events, dashboards, etc, configure and use the the home automation system.

What’s Connected

This system uses:

  • Raspberry pi with TFT touchscreen (Interface of the system)
  • Wi-Fi microcontrollers
  • Digital relay
  • Dimmer (TRIAC)
  • Current sensors (Hall effect)
  • Presence/motion sensor (Passive infrared sensor)
  • Temperature and humidity sensor (DHT11)
  • Luminosity sensor (Light dependent resistor)
  • Eletrical equipment (Circuit breaker, derivation equipment, breadboards, etc).

Triggers & Alerts

I implement several triggers and alerts sucessfuly:

  • Sending of sms/email to the user when the motion/presence detects movement/presence;
  • Controling a lamp depending on the natural luminosity on the area, by dimming (regulating the luminous flux emitted by the lamp) or ON/OFF control;
  • Controling a eletric load (in this case, a fan) to turn ON/OFF a climatization equipment depending on the temperature and presence of people on the are;
  • Many others.

Dashboard Screenshots

“Smart socket” dashboard:

“Smart power plug” dashboard

“Temperature and humidity sensor” dashboard

Motion/presence sensor dashboard

Luminosity sensor dashboard

Photos of the Project

image

Video

Pratical implementation and codes

Motion/presence sensor pratical implementation:

Code (using ArduinoIDE to implement the programing code in the Wi-Fi microcontroler ESP-01):

/*
Bruno Pedro
“Home automation system for energetic efficiency improvement”
Master degree dissertation - ISEL - Lisboa - 2021
Motion sensor (PIR)
Equipments utilized:
ESP8266 (ESP-01); VCC and CH_PD 3,3V DC VCC
PIR sensor, digital output, 5V DC VCC. 100 ohms resistance betwen GPIO2 of ESP-01 and OUT in of PIR sensor
Online platform:
https://mydevices.com/ (Cayenne IoT platform)
ESP8266 board package (arduino IDE)
I do not own any library used in this code. All rights belong to owners.
*/
#include <CayenneMQTTESP8266.h> //Cayenne library for ESP8266 communication method
#define CAYENNE_PRINT Serial //Serial monitor for cayenne communications
#define CAYENNE_DEBUG //Serial monitor for cayenne communications for debug
char ssid = “…”; // Name of Wi-Fi acess point used
char wifiPassword = “…”; // Password of Wi-Fi acess point used
char username = “…”; //Username of device connected (Cayenne MQTT)
char password = “…”; //Password of device connected (Cayenne MQTT)
char clientID = “…”; //ClientId of device connected (Cayenne MQTT)
#define SENSOR_PIN 2 // Do not use digital pins 0 or 1 since those conflict with the use of Serial.
#define VIRTUAL_CHANNEL 1 // Cayenne MQTT virtual channel number 1 is used for this device
void setup()
{
pinMode(SENSOR_PIN, INPUT); // ESP-01 digital pin used for receiving sensor information, INPUT mode
Serial.begin(74880); // Baud rate suitable for ESP-01
Cayenne.begin(username, password, clientID, ssid, wifiPassword); //Initialization of MQTT connection of device with MQTT, with required information

}
void loop()
{
Cayenne.loop(); // Cayenne code loop
checkSensor(); // Sensor status check
}
int previousState = -1;
int currentState = -1;
unsigned long previousMillis = 0;
void checkSensor()
{
unsigned long currentMillis = millis();
// Check sensor data every 250 milliseconds
if (currentMillis - previousMillis >= 100) {
// Check the sensor state and send data when it changes.
currentState = digitalRead(SENSOR_PIN);
if (currentState != previousState) {
Cayenne.virtualWrite(1 , currentState, “digital_sensor”, “d”); // Cayenne MQTT virtual channel number 1 is used for this device
Cayenne.virtualWrite(2 , currentState, “digital_sensor”, “d”); // Cayenne MQTT virtual channel number 2 is used for this device, for the secondary graph
previousState = currentState;
}
previousMillis = currentMillis;
}
}

Temperature and humidity sensor pratical implementation:

Code (using ArduinoIDE to implement the programing code in the Wi-Fi microcontroler ESP-01):

/*
Bruno Pedro
“Home automation system for energetic efficiency improvement”
Master degree dissertation - ISEL - Lisboa - 2021
Temperature and relative humidity sensor (DHT11)
Equipments utilized:
ESP8266 (ESP-01); VCC and CH_PD 3,3V DC VCC
DHT11 sensor, digital output, 3,3V DC VCC. GPIO2 of ESP-01 connected to OUT of sensor
Online platform:
https://mydevices.com/ (Cayenne IoT platform)
ESP8266 board package (arduino IDE)
I do not own any library used in this code. All rights belong to owners.
*/
#include “DHT.h” // Library of DHT11 temperature and humidity sensor
#define DHTTYPE DHT11 // Definition of DHT sensor used: DHT11
#define dht_dpin 2 // OUT pin used for output digital information
DHT dht(dht_dpin, DHTTYPE); // DHT11 parameterization
#include <CayenneMQTTESP8266.h> //Cayenne library for ESP8266 communication method
#define CAYENNE_PRINT Serial //Serial monitor for cayenne communications
#define CAYENNE_DEBUG //Serial monitor for cayenne communications for debug
// WiFi network info.
char ssid = “…”; //Serial monitor for cayenne communications
char wifiPassword = “…”; //Serial monitor for cayenne communications for debug
char username = “…”; //Username of device connected (Cayenne MQTT)
char password = “…”; //Password of device connected (Cayenne MQTT)
char clientID = “…”; //ClientId of device connected (Cayenne MQTT)
#define SENSOR_PIN 2 // Do not use digital pins 0 or 1 since those conflict with the use of Serial.
void setup()

{
dht.begin(); // Initialization of DHT11 sensor
pinMode(SENSOR_PIN, INPUT); // ESP-01 digital pin used for receiving sensor information, INPUT mode
Serial.begin(9600); // Baud rate suitable for ESP-01
Cayenne.begin(username, password, clientID, ssid, wifiPassword); //Initialization of MQTT connection of device with MQTT, with required information
}
void loop()
{
Cayenne.loop(); // Cayenne code loop
delay(1000);
}
int previousState = -1;
int currentState = -1;
unsigned long previousMillis = 0;
CAYENNE_OUT(1) //MQTT channel responsible for sending temperature constant information
{
float t = dht.readTemperature();
Cayenne.virtualWrite(1,t,“temp”,“c”); //virtual pin
}
CAYENNE_OUT(2) //MQTT channel responsible for sending temperature information for graph
{
float t = dht.readTemperature();
Cayenne.virtualWrite(2,t,“temp”,“c”); //virtual pin
}
CAYENNE_OUT(3) //MQTT channel responsible for sending humidity constant information
{
float h = dht.readHumidity();
Cayenne.virtualWrite(3,h,“rel_hum”,“p”); //virtual pin
}
CAYENNE_OUT(4) //MQTT channel responsible for sending relative humidity for graph
{
float h = dht.readHumidity();
Cayenne.virtualWrite(4,h,“rel_hum”,“p”); //virtual pin
}

“Smart socket” pratical implementation:

Code (using ArduinoIDE to implement the programing code in the Wi-Fi microcontroler ESP8266 NodeMCU):

/*
Bruno Pedro
“Home automation system for energetic efficiency improvement”
Master degree dissertation - ISEL - Lisboa - 2021

Smart lamp socket, with lamp dimming (230V AC, 50Hz) with eletrical power and energy consumption measurement.
Compatible with any type of single phase, low voltage AC lamp (LED, halogen, incandescent, etc) and single phase, low voltage AC eletrical motors (fans, ventilators, heaters, etc)

Equipments utilized:
ESP8266 (CP2102 NodeMCU V3 Lua);
ACS712 (5A range) of Robotdyn, AC and DC current meausurements, 5V DC (VCC);
AC dimmer (TRIAC module) of Robotdyn, 3,3V (VCC);
Online platform:
https://mydevices.com/ (Cayenne IoT platform)
ESP8266 board package (arduino IDE, NodeMCU 0.9 (ESP-12 Module))

I do not own any library used in this code. All rights belong to owners.
*/

#include <RBDdimmer.h> // Supplier official dimmer library
#include <CayenneMQTTESP8266.h> //Cayenne library for ESP8266 communication method
#define CAYENNE_PRINT Serial //Serial monitor for cayenne communications
#define outputPin 12 //Output pin for ESP8266, Input pin of AC dimmer, responsible for eletrical wave modulation
#define zerocross 5 // Input pin for ESP8266, Output pin of AC dimmer, responsible for sending the temporal information of eletrical wave null value

dimmerLamp dimmer(outputPin, zerocross); //Initialization of ports for ESP8266

int outVal = 100; //variable for AC dimmer
float outVal2 = 0;
int preVal = 0; //variable for AC dimmer
float power; //variable for power meausurement
double power2; //variable for power meausurement
double powerK; //variable for power meausurement
double sum = 0; //variable for energy meausurement
double energy; //variable for energy meausurement
int button = 1; //variable for ON/OFF lamp control by AC dimmer

char ssid = “…”; // Name of Wi-Fi acess point used
char wifiPassword = “…”; // Password of Wi-Fi acess point used

char username = “…”; //Username of device connected (Cayenne MQTT)
char password = “…”; //Password of device connected (Cayenne MQTT)
char clientID = “…”; //ClientId of device connected (Cayenne MQTT)

void setup() {
Serial.begin(115200); //Initialization of arduino IDE serial monitor
dimmer.begin(NORMAL_MODE, ON); //Initialization of AC dimmer: (“name of device”.begin(mode selection, device state selection)
dimmer.setPower(50); //First value of AC dimmer output power
pinMode(13, INPUT); //Virtual pin, used for ON/OFF control of lamp
Cayenne.begin(username, password, clientID, ssid, wifiPassword); //Initialization of MQTT connection of device with MQTT, with required information
}

void loop() {
float output = 0; //Analog output of ACS712
int max1 = 0; //variable for current measurement
int max2 = 0; //variable for current measurement
int max3 = 0; //variable for current measurement
int sumcurrent = 0; //variable for current measurement
int nullvalue = 0; //variable for current measurement
int correctmax = 0; //variable for current measurement
float mediumvalue = 0; //variable for current measurement
int average; //variable for current measurement

//The following eletronic/computing setup reads and processes 1500 values of eletrical current each second
for (int i = 0; i < 500; i++)
{
output = analogRead(A0); // A0 is ESP8266 NodeMCU only analog pin (with ADC)
// “output” variable is ESP8266 reading of analog value of ACS712 out pin (DC eletric voltage).
//The integrated ADC of ESP8266 has 10-bit resolution. The converted decimal values of DC voltage (by ESP8266 adc of A0 pin) from ACS712 will be outputed to “output” variable
//with values of 0 to 1023, being 0=0V and 1023=Max DC voltage of ACS712 out pin.
//ESP8266 NodeMCU pin A0 supports up to 0-3,3V DC max.
sumcurrent = sumcurrent + output; // summation of current values
nullvalue = sumcurrent / 500; // Null value of eletrical current (average value of eletrical wave)
Serial.print(output);
Serial.println();
if (output > max1) {
max1 = output; // Max current calculation
}
}
for (int i = 0; i < 60; i++)
{
output = analogRead(A0);
Serial.print(output);
Serial.println();
if (output > max2) {
max2 = output;
}
}
for (int i = 0; i < 940; i++)
{
output = analogRead(A0);
Serial.print(output);
Serial.println();
if (output > max3) {
max3 = output;
}
}
if ((max1 < max2) && (max1 < max3))
{
correctmax = max1;
Serial.println();

}
if ((max2 < max1) && (max2 < max3))
{
correctmax = max2;

}
if ((max1 < max3) && (max1 < max3))
{
correctmax = max3;
}
Serial.print(“max1=”);
Serial.print(max1);
Serial.print(“max2=”);
Serial.print(max2);
Serial.println();
Serial.print(“max3=”);
Serial.print(max3);
Serial.print(“Corrected max value=”); // correctmax value will be the filtered max current value (due to ACS712 and ESP8266 error in meausurement)
Serial.print(correctmax);
Serial.println();
Serial.print(“Nullvalue=”);
Serial.print(nullvalue);
Serial.println();
power = (((correctmax - nullvalue) * 0.0194) / (sqrt(2))) * 230;
//Conversion of analog output signal from ACS712 to ESP8266, to current (Amperes) and to effective/rms power(W).
// The proportionality constant (0.0194) was calculated per precise laboratory experiments and results
if (power < 0)
{
power = 0 ;
}
Serial.print(“outVal=”);
Serial.print(outVal); // dimming value of load (%)
Serial.println();
outVal2 = outVal;
power2 = power * (((0.0314 * outVal) - (0.5) * sin((2 * ((0.0314 * outVal))))) / 3.14159); //Calculation of eletrical power consumpted, with % dimming of load (equation explained in dissertation)
Serial.println();
Serial.print(“Power1(W):”);
Serial.print(power);
Serial.print(“Power2(W):”);
Serial.print(power2);
Serial.println();
powerK = power2 / 1446000 ; //Conversion of power in Watts (W), to power in kilowatts (kW), to energy in 1 second. Every 2,48s a value is sent, consequently 1800 readings per hour
Serial.print(“Power(kW) 1sec:”);
Serial.print(powerK, 7);
Serial.println();
sum = (sum + powerK); // Summation of eletrical energy (kW/h) value
energy = sum; // Total eletrical energy (kW/h) value
Serial.print(“Energy):”);
Serial.print(sum, 7);
Serial.println();
delay(10);

// The following conditons are implemented to enable an ON/OFF button on cayenne online dashboard to control the ON/OFF lamp.
if (button == 1)
{
delay(10);
dimmer.setState(ON); //name.setState(ON/OFF);
}
if (button == 0)
{
delay(10);
dimmer.setState(OFF); //name.setState(ON/OFF);
}
delay(10);
Cayenne.loop(); // Cayenne code loop
}

CAYENNE_IN(1) //MQTT channel for dimming value (%)
{
outVal = getValue.asInt(); // Dimming value (%) sent from cayenne online dashboard
if (preVal != outVal)
{
dimmer.setPower(outVal);
Serial.print(“Dimming value (%)”);
Serial.println(outVal);
}
}
CAYENNE_OUT(2) //MQTT channel for eletrical energy consumption (values in kW/h) for latest value
{
Cayenne.virtualWrite(2, energy, “energy”, “kwh”);
}
CAYENNE_OUT(3) //MQTT channel for eletrical energy consumption (values in kW/h) for graph
{
Cayenne.virtualWrite(3, energy, “energy”, “kwh”);
}
CAYENNE_OUT(4) //MQTT channel for eletrical power consumption (values in W) for latest value
{
Cayenne.virtualWrite(4, power2, “pow”, “w”);
}
CAYENNE_IN(5) //MQTT channel for ON/OFF control of lamp by AC dimmer
{
int currentValue = getValue.asInt();
button = currentValue;
}

“Smart power plug” pratical implementation (with luminosity sensor):


Code (using ArduinoIDE to implement the programing code in the Wi-Fi microcontroler ESP-32 NodeMCU):

/*
Bruno Pedro
“Home automation system for energetic efficiency improvement”
Master degree dissertation - ISEL - Lisboa - 2021

Smart power plug, with eletric load ON/OFF control (230V AC, 50Hz) and with eletrical power and energy consumption measurement.
Compatible with any type of single phase, low voltage eletric load that are connectable to SCHUKO power plug tipology.

Equipments utilized:
ESP-32 (NodeMCU-32S Lua);
ACS712 (20A range) of Robotdyn, AC and DC current meausurements, 5V DC (VCC);
Digital relay (30A / 250V AC)
Robotdyn light sensor, LDR with analog and digital outputs (3,3V DC VCC);
Online platform:
https://mydevices.com/ (Cayenne IoT platform)

I do not own any library used in this code. All rights belong to owners.
*/

#include <CayenneMQTTESP32.h> //Cayenne library for ESP8266 communication method
#define CAYENNE_PRINT Serial //Serial monitor for cayenne communications

double sum = 0; //variable for energy meausurement
float power; //variable for power meausurement
double powerK; //variable for power meausurement
double energy; //variable for energy meausurement
float lux = 0; //variable for luminosity meausurement
float luxs = 0; //variable for luminosity meausurement

char ssid = “…”; // Name of Wi-Fi acess point used
char wifiPassword = “…”; // Password of Wi-Fi acess point used

char username = “…”; //Username of device connected (Cayenne MQTT)
char password = “…”; //Password of device connected (Cayenne MQTT)
char clientID = “…”; //ClientId of device connected (Cayenne MQTT)

void setup() {
Serial.begin(115200); //Initialization of arduino IDE serial monitor
pinMode(26, OUTPUT); // Output pin of ESP-32, Input pin of digital relay, responsible for the ON/OFF control off relay.
Cayenne.begin(username, password, clientID, ssid, wifiPassword); //Initialization of MQTT connection of device with cayenne, with required information
}

void loop() {
float output = 0; //Analog output of ACS712
float output2 = 0; //Analog output of light sensor
int sumcurrent = 0; //variable for current measurement
int sum2 = 0; //variable for luminusity measurement
int max1 = 0; //variable for current measurement
int max2 = 0; //variable for current measurement
int max3 = 0; //variable for current measurement
int nullvalue = 0; //variable for current measurement
int correctmax = 0; //variable for current measurement
float average2 = 0; //variable for luminusity measurement

//The following eletronic/computing setup reads and processes 1500 values of eletrical current each second

for (int i = 0; i < 500; i++)
{
output = analogRead(A0); // A0 is ESP-32 NodeMCU analog pin of GPIO36 (with ADC)
// “output” variable is ESP32 reading of analog value of ACS712 out pin (DC eletric voltage).
//The integrated ADC of ESP-32 has 12-bit resolution. The converted decimal values of DC voltage (by ESP-32 adc of A0 pin) from ACS712 will be outputed to “output” variable
//with values of 0 to 4096, being 0=0V and 4096=Max DC voltage of ACS712 out pin.
//ESP8266 NodeMCU analog pins supports up to 0-3,3V DC max.
sumcurrent = sumcurrent + output; // summation of current values
nullvalue = sumcurrent / 500; // Null value of eletrical current (average value of eletrical wave)
Serial.print(output);
Serial.println();
if (output > max1) {
max1 = output; // Max current calculation
}
}
for (int i = 0; i < 60; i++)
{
output = analogRead(A0);
Serial.print(output);
Serial.println();
if (output > max2) {
max2 = output;
}
}
for (int i = 0; i < 940; i++)
{
output = analogRead(A0);
Serial.print(output);
Serial.println();
if (output > max3) {
max3 = output;
}
}
if ((max1 < max2) && (max1 < max3))
{
correctmax = max1;
Serial.println();

}
if ((max2 < max1) && (max2 < max3))
{
correctmax = max2;

}
if ((max1 < max3) && (max1 < max3))
{
correctmax = max3;
}

Serial.println();
Serial.print(“max1”);
Serial.print(max1);
Serial.println();
Serial.print(“max2”);
Serial.print(max2);
Serial.println();
Serial.print(“max3”);
Serial.print(max3);
Serial.println();
Serial.print(“Corrected max=”); // correctmax value will be the filtered max current value (due to ACS712 and ESP8266 error in meausurement)
Serial.print(correctmax);
Serial.println();
Serial.print(“Nullvalue=”);
Serial.print(nullvalue);
Serial.println();
power = (((correctmax - nullvalue) * 0.00692) / (sqrt(2))) * 230; //conversion of output signal from ACS712, to current (Amperes), to power (W)
//Conversion of analog output signal from ACS712 to ESP-32, to current (Amperes) and to effective/rms power(W).
// The proportionality constant (0.00692) was calculated per precise laboratory experiments and results (explained in dissertation)
if (power < 30 )
{
power = 0;
}
Serial.println();
Serial.print(“Power(W):”);
Serial.print(power);
Serial.println();

powerK = power / 1895000 ; //Conversion of power in Watts (W), to power in kilowatts (kW), to energy in 1 second. Every 1,90s a value is sent, consequently 1607 readings per hour
Serial.print(“Power(kW) 1sec:”);
Serial.print(powerK, 7);
Serial.println();
sum = (sum + powerK); // Summation of eletrical energy (kW/h) value
energy = sum;
Serial.print(“Energy):”); // Total eletrical energy (kW/h) value
Serial.print(sum, 7);
Serial.println();
delay(10);

// The following code regards to the light sensor output values.
for (int i = 0; i < 50; i++)
{
output2 = analogRead(32); //GPIO32 is the analog pin of ESP-32 connected to analog output of light sensor.
//The ESP-32 will convert, trough ADC, the voltage output of LDR and convert it to a range of 0 to 4096.
Serial.print(output2);
Serial.println();
sum2 = sum2 + output2;
}
average2 = sum2 / 50; //Average value obtained, to improve value reading precision
lux = pow((average2 / 12117), (1 / (-0.71))); // Calculation of luxs detected by light sensor.
// The formula used takes the digital value of voltage from LDR and calculates the luxs in the area. This formula and constants were obtained from precise laboratoty experiments.
Serial.print(“Average signal=”);
Serial.print(average2);
Serial.println();
Serial.print(“luxs=”);
Serial.print(lux);
Serial.println();
luxs = lux;
Cayenne.loop();
delay(10);
}

CAYENNE_OUT(1)
{
Cayenne.virtualWrite(1, energy, “energy”, “kwh”); //MQTT channel for eletrical energy consumption (values in kW/h) for latest value
}
CAYENNE_OUT(2)
{
Cayenne.virtualWrite(2, energy, “energy”, “kwh”); //MQTT channel for eletrical energy consumption (values in kW/h) for graph
}
CAYENNE_OUT(3)
{
Cayenne.virtualWrite(3, power, “pow”, “w”); //MQTT channel for eletrical power consumption (values in W) for latest value
}
CAYENNE_OUT(5)
{
Cayenne.virtualWrite(5, luxs, “lum”, “lux”); //MQTT channel for luxs detected by light sensor
}
CAYENNE_OUT(6)
{
Cayenne.virtualWrite(6, luxs, “lum”, “lux”); //MQTT channel for luxs detected by light sensor
}
CAYENNE_IN(9) //MQTT channel for ON/OFF control of digital relay
{
int currentValue = getValue.asInt();
if (currentValue == 1) {
digitalWrite(26, HIGH); // GPIO PIN 26 ON
}
else
{
digitalWrite(26, LOW); // GPIO PIN 26 OFF
}
}

2 Likes

Awesome project @Bruno_Pedro

1 Like

Thank you @shramik_salgaonkar and thanks for the support you gave me!

Você também pode acrescentar controles ir para controlar TV, Ar-condicionado,aparelhos de som e qualquer que use ir com o protocolo irremote
Se precisar de ajuda estou aqui

@Bruno_Pedro thanks for sharing!

1 Like