instructables
Arduino Mega + WiFi = Automation
by Fernando Koyanagi
Today, I’ll talk about an assembly that was suggested by many followers: Arduino Mega + ESP. This will include
an automation project with 16 relays, three sensors, and a smartphone. We’ll make a Web Server for the Arduino
Mega using serial communication with the ESP8266, in the ESP-01 version. I will also show a page with the
values of sensors and buttons to modify the state of the relays.
https://youtu.be/u75uASGEvNg
Step 1: Assembly
I placed here the schematic, which shows the DHT22, the Ds18b20, and a third sensor (the light), which are all
connected to the relays by the pins 36 to 51.
Arduino Mega + WiFi = Automation: Page 1
Step 2: Demonstration
See the video demonstration of the project in send them to the cell phone from the Arduino Mega,
operation. In the assembly, you are given a 16-wire through the ESP, which would be the serial bridge (ie
board, which is connected directly to the ports of an the WiFi).
Arduino Uno. This Uno I used was only to power the
3v3 of the ESP-01. I still have an LDR (which is my In the assembly, we have LEDs which, when lit,
light sensor), a Ds18b20 thermometer, and the indicate that the respective relays are switched off.
DHT22, which collects humidity and temperature This process is also controlled by the smartphone.
data. We have an application on the smartphone that
will display the data collected by these sensors and
Arduino Mega + WiFi = Automation: Page 2
Step 3: Libraries
For our project today, we will need certain libs: In the Arduino IDE, go to Sketch-> Include Library->
Manage Libraries ...
WiFiEsp Library
Install DallasTemperature
In the Arduino IDE, go to Sketch-> Include Library->
Manage Libraries ... OneWire Library
Install WiFiEsp In the Arduino IDE, go to Sketch-> Include Library->
Manage Libraries ...
DallasTemperature Library
Install OneWire Manage Libraries ...
DHT sensor library by Adafruit Install DHT sensor library by Adafruit
In the Arduino IDE, go to Sketch-> Include Library->
Step 4: Source Code
MEGAESP_01.ino
We start off by including the libraries and defining the pins attached to the sensors. We also point out the pin
where the first relay will be and how many pins (starting from this first one) will be used.
Arduino Mega + WiFi = Automation: Page 3
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DHT.h>
#include <WiFiEsp.h>
//Pinos onde estão os sensores
#define PIN_DS18B20 7
#define PIN_DHT22 8
#define PIN_LUMINOSITY A0
#define FIRST_PIN 36 //Pino onde está o primeiro relê
#define PINS_COUNT 16 //Quantos pinos a partir do primeiro serão utilizados
We continue with the DS18B20 temperature sensor, and the DHT22 temperature and humidity sensor. We then
set out for definitions involving the WiFi network, such as the SSID and password for the ESP to connect. We
point to the server that will receive the requests on port 80 (standard port http), as well as the variables to store the
values of the sensors.
//Sensor de Temperatura DS18B20
OneWire oneWire(PIN_DS18B20);
DallasTemperature sensors(&oneWire);
DeviceAddress sensor;
//Sensor de temperatura e umidade DHT22
DHT dht(PIN_DHT22, DHT22);
//SSID e senha da rede wifi para o ESP se conectar
char ssid[] = "SSID";
char pass[] = "12345678";
char ip[] = "192.168.0.109";
//Servidor que receberá as requisições na porta 80 (porta padrão http)
WiFiEspServer server(80);
//Variáveis para armazenar os valores dos sensores
float temperatureDS18B20 = 0;
float temperatureDHT22 = 0;
float humidityDHT22 = 0;
int luminosity = 0;
//Mantém o estado atual dos pinos (HIGH ou LOW)
int pinsStatus[PINS_COUNT];
MEGAESP_01.ino - setup
We initialize the serial and serial monitor where the ESP-01 is with AT firmware, in addition to pins, and DS18B20
and DHT22 sensors. For the brightness sensor, we just need to read the analog pin. We also initialize the WiFi
and connect to the network. Finally, we initialize the server.
Arduino Mega + WiFi = Automation: Page 4
void setup()
{
//Serial para o monitor serial
Serial.begin(115200);
//Serial onde está o ESP-01 com firmware AT
Serial1.begin(115200);
//Inicializa os pinos
setupPins();
//Inicializa o sensor DS18B20
setupDS18B20();
//Inicializa o sensor DHT22
dht.begin();
//Para o sensor de luminosidade apenas precisamos ler o pino analógico
pinMode(A0, INPUT);
//Inicializa WiFi e conecta à rede
setupWiFi();
//Inicializa o server
server.begin();
}
MEGAESP_01.ino - setupPins
In this step, we put the pins that are connected to the relays as outputs.
void setupPins()
{
//Coloca os pinos que estão ligados os relês como saída
for(int i=0; i
MEGAESP_01.ino - setupWiFi
Here, we perform a function that initializes the serial where the ESP-01 is with the AT firmware already installed.
We wait to connect to the WiFi network, configure the IP, and verify the same IP.
Arduino Mega + WiFi = Automation: Page 5
void setupWiFi()
{
//Serial onde está o ESP-01 com o firmware AT já instalado
WiFi.init(&Serial1);
Serial.print("Conectando a ");
Serial.println(ssid);
int status = WL_IDLE_STATUS;
//Aguarda conectar à rede WiFi
while (status != WL_CONNECTED)
{
status = WiFi.begin(ssid, pass);
}
Serial.println();
Serial.println("Conectado");
//Configura o IP
IPAddress ipAddress;
ipAddress.fromString(ip);
WiFi.config(ipAddress);
//Veririca o IP
IPAddress localIP = WiFi.localIP();
Serial.print("IP: ");
Serial.println(localIP);
}
MEGAESP_01.ino - setupDS18B20
Initialize the DS18B20 sensor.
//Inicializa o sensor DS18B20
void setupDS18B20()
{
sensors.begin();
if (!sensors.getAddress(sensor, 0))
{
Serial.println("Sensor não encontrado!");
}
}
MEGAESP_01.ino - Loop
In the Loop, we check for a new client. We read the request and, if the request is not for the favicon, we execute
the action with the value passed in the request. We then read the sensors and send the response to the customer.
We determine a time for the browser to receive the data and close the connection with the client.
Arduino Mega + WiFi = Automation: Page 6
void loop()
{
WiFiEspClient client = server.available();
//Verifica se há um novo cliente
if (client)
{
Serial.println("Novo cliente conectou");
//Faz a leitura da requisição
char* request = readRequest(client);
//Se a requisição não for para o favicon
if(strstr(request, "favicon") == NULL)
{
//Executamos a ação com o valor passado na requisição
execute(getAction(request), getValue(request));
//Faz a leitura dos sensores
readSensorDS18B20();
readSensorDHT22();
readSensorLuminosity();
//Envia a resposta ao cliente
sendResponse(client);
//Tempo para o navegador receber os dados
delay(100);
}
//Fecha a conexão com o cliente
client.stop();
}
}
MEGAESP_01.ino - readRequest
Here, we have a very important function. What does it do? When we press a button on the smartphone, the
function sends the command in HTTP to ESP8266, using only the first line, as you see in the example below. I
emphasize that even after reading the first line, it is important to read it until the end, otherwise the WiFiESP lib
gives a timeout.
GET /?on=1 HTTP/1.1\r\n
Host: 192.168.3.154\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Linux; Android 8.0.0; SM-G955F Build/R16N ) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Referer: http://192.168.3.154/\r\n
Accept-Encoding: gzip, deflate\r\n
Arduino Mega + WiFi = Automation: Page 7
Accept-Language: en-US,en;q=0.9\r\n
\r\n
Here, we have the reading of the first line of the request.
//Faz a leitura da primeira linha da requisição
char* readRequest(WiFiEspClient client)
{
bool currentLineIsBlank = true;
char request[50];
int i = 0;
bool firstLine = true;
while (client.connected()){
if(client.available()){
char c = client.read();
Serial.write(c);
//Apenas a primeira linha da requisição nos interessa
if(firstLine){
request[i] = c;
i++;
}
We see that the last line of the request is: \ r \ n alone, \ r \ n. And, after the previous line, it is: \ r \ nso. If we get
here, it is because the request has been read in full. Also, if you read any character other than \ n and \ r, it means
that the line is not blank.
if (c == '\n'){
//A última linha da requisição é um \r\n sozinho, após o \r\n da linha anterior
if(currentLineIsBlank){
//Se chegou aqui é porque a requisição foi lida por completo
break;
}
currentLineIsBlank = true;
firstLine = false;
}
else if (c != '\r'){
//Se leu qualquer caracter que não for \n e \r significa que a linha não está em branco
currentLineIsBlank = false;
}
}
}
return request;
}
MEGAESP_01.ino - sendResponse
This function sends the HTML to the client. It also sends the HTTP header, as well as the HTML header and body.
Arduino Mega + WiFi = Automation: Page 8
//Envia o HTML para o cliente
void sendResponse(WiFiEspClient client)
{
//Envia o cabeçalho HTTP
client.print(
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=UTF-8\r\n"
"Connection: close\r\n"
"Refresh: 10; URL=/\r\n" //Para fazer requisação a raiz do server a cada 10 segundos
"\r\n");
client.println("<!DOCTYPE HTML>");
client.println("<html>");
head(client);//Envia o cabeçalho do HTML
body(client);//Envia o corpo do HTML
client.println("</html>");
MEGAESP_01.ino - head
We sent the CSS to modify the appearance of the page.
//Envia o CSS para modificar a aparência da página
void head(WiFiEspClient client)
{
client.println(F("<head>"
"<style>"
"body{"
"text-align: center;"
"font-family: sans-serif;"
"font-size: 14px;"
"}"
"p{"
"color:#555;"
"font-size: 12px;"
"}"
".button{"
"outline: none;"
"display: block;"
"border: 1px solid #555;"
"border-radius:18px;"
"width: 150px;"
"height: 30px;"
"margin: 10px;"
"margin-left: auto;"
"margin-right: auto;"
"cursor: pointer;"
"}"
".button_off{"
"background-color:#FFF;"
"color: #555;"
"}"
".button_on{"
"background-color:#2C5;"
"color: #fff;"
"}"
"</style>"
"</head>" ));
Arduino Mega + WiFi = Automation: Page 9
MEGAESP_01.ino - body
We then proceed to display the sensor data and create the buttons for each pin that has a relay.
//Exibe os dados dos sensores e cria os botões
void body(WiFiEspClient client)
{
client.println(
"<body>"
"DS18B20 Temperature: " + String(temperatureDS18B20) + " °C"
"
"
"DHT22 Temperature: " + String(temperatureDHT22) + " °C"
"
"
"DHT22 Humidity: " + String(humidityDHT22) + "%"
"
");
String buttons = "";
//Cria um botão para cada pino que possui um relê
for(int i=0; i<PINS_COUNT; i++)
buttons.concat(button(i));
client.println(buttons);
client.println("</body>");
MEGAESP_01.ino - button
We create a button with the appearance and action that corresponds to the current state of the relay.
//Cria um botão com a aparência e ação correspondente ao estado atual do relê
String button(int number)
{
String label = String(number + 1);
String className = "button ";
className += pinsStatus[number] == HIGH ? "button_on" : "button_off";
String action = pinsStatus[number] == HIGH ? "off" : "on";
return "<button class=\"" + className + "\"onclick=\"location.href='?" + action + "=" + label +"'\">" + label + "<button>";
MEGAESP_01.ino - sensors
We read the DS18B20, DHT, and brightness sensors.
Arduino Mega + WiFi = Automation: Page 10
//Faz a leitura do sensor DS18B20
void readSensorDS18B20()
{
sensors.requestTemperatures();
temperatureDS18B20 = sensors.getTempC(sensor);
}
//Faz a leitura do sensor DHT
void readSensorDHT22()
{
humidityDHT22 = dht.readHumidity();
temperatureDHT22 = dht.readTemperature();
}
//Faz a leitura do sensor de luminosidade
void readSensorLuminosity()
{
luminosity = analogRead(PIN_LUMINOSITY);
}
MEGAESP_01.ino - getAction getValue
We return the action that the client wants to execute (on / off), as well as the value (number of the relay) of the
action that will be executed.
//Retorna a ação que o cliente deseja executar (on off)
String getAction(char *request)
{
return getStringBetween(request, '?', '=');
}
//Retorna o valor (numero do relê) que a ação será executada
String getValue(char *request)
{
return getStringBetween(request, '=', ' ');
}
MEGAESP_01.ino - getStringBetween
We continue, this time, returning the string that lies between the first “start” character and the first “end” character.
We return the memory address of the "start" character. If it does not find the character, it goes to the next one, until
it reaches the "end" character or the end of the string.
Arduino Mega + WiFi = Automation: Page 11
//Retorna a string que fica entre o primeiro caractere 'start' e o primeiro caractere 'end'
String getStringBetween(char *input, char start, char end)
{
String str = "";
//retorna o endereço de memória do caractere 'start'
char *c = strchr(input, start);
//Se não achou o caractere
if(c == NULL)
{
return "";
}
//Vai para o próximo caractere
c++;
//Enquanto não chegar ao caractere 'end' ou ao final da string
while(*c != end && *c!='\0')
{
str += *c;
c++;
}
return str;
}
MEGAESP_01.ino - execute
Finally, executed in the action next to the value (number of the relay), we observe if it is one of the two actions that
we expect (On or Off). The relays are numbered from 1, but the array starts from 0. Then we draw 1.
The pin number will be the index plus the pin number where the relays start. The relays must be in sequence from
the starting pin.
//Executada a ação junto ao valor (número do relê)
void execute(String action, String value)
{
//Se é uma das duas ações que esperamos
if(action == "on" || action == "off")
{
//Os relês são numerados a partir do 1, max o array começa do 0
//então tiramos 1
int index = value.toInt() - 1;
//O número do pino será o índice mais o número do pino onde os relês
//começam. Os relês devem estar em sequência a partir do pino inicial (FIRST_PIN)
int pinNumber = FIRST_PIN + index;
int status = action == "on" ? HIGH : LOW;
digitalWrite(pinNumber, status);
pinsStatus[index] = status;
}
}
" "body{" "text-align: center;" "font-family: sans-serif;" "font-size: 14px;" "}" "p{" "color:#555;" "font-size: 12px;" "}"
".button{" "outline: none;" "display: block;" "border: 1px solid #555;" "border-radius:18px;" "width: 150px;" "height:
30px;" "margin: 10px;" "margin-left: auto;" "margin-right: auto;" "cursor: pointer;" "}" ".button_off{" "background-
color:#FFF;" "color: #555;" "}" ".button_on{" "background-color:#2C5;" "color: #fff;" "}" "
Arduino Mega + WiFi = Automation: Page 12
Step 5: Files
Download the files:
INO
PDF
Arduino Mega + WiFi = Automation: Page 13