Automação utilizando ESP01 com
16 relés. Este é um modelo de projeto, super barato, por sinal, que vou te
mostrar hoje, a partir do qual você pode multiplicar os módulos e chegar até
128 relés, isso porque é possível colocar até oito expansores de portas neste
microcontrolador. No nosso circuito, você terá
uma aplicação em um smartphone que comunica com o ESP01. Este estará com um
expansor que contará com 16 portas, cada uma ligada a um relé. Temos ainda uma
fonte regulável de 3v3. Vamos, portanto, controlar um módulo de relé de 16
canais utilizando o ESP01 através do aplicativo Android, que vou disponibilizar
para você.
Relembrando
Importante destacar, pessoal,
que usei neste circuito um chip que chama MCP23016. Não menos importante é você
assistir ao vídeo EXPANSOR DE IOS PARA ESP32, ESP8266 E ARDUINO, no qual testo o
dispositivo e mostro que ele funciona para estes três tipos de placas.
MCP23016
Temos aqui uma imagem do
MCP23016, esse chip com 28 pinos. Devo te contar que existe também o modelo
MCP23017, que é mais comum e não precisa de resistor e capacitor, pois tem um
clock interno. Isso facilita, mas a sua pinagem é diferente da que mostramos
neste vídeo.
Endereço
Para definir o endereço do
MCP23016, utilizamos os pinos A0, A1 e A2. Bastando deixar eles em estado HIGH
ou LOW para a troca de endereço.
O endereço será formado da
seguinte forma:
MCP_Address = 20 + (A2 A1 A0)
Onde A2 A1 A0 podem tomar
valores HIGH/LOW, formando assim um número binário de 0 a 7.
Por exemplo:
A2 > GND ,
A1 > GND, A0 > GND (significa 000, logo 20+0 = 20)
Ou então,
A2 > HIGH ,
A1 > GND, A0 > HIGH (significa 101, logo 20+5 = 25)
Comandos
Aqui temos uma tabela com os
comandos para comunicação:
Acessos
GP0 / GP1 – Data Port
Registers
São dois registradores que
fornecem acesso às duas portas do GPIO.
A leitura do registrador
fornece o estado dos pinos naquela porta.
Bit = 1 > HIGH Bit = 0 > LOW
IODIR0 / IODIR1
São dois registradores que
controlam o modo de pino. (Entrada ou Saída)
Bit = 1 > INPUT Bit = 0 >
OUTPUT
Estrutura para a comunicação
Aqui tratamos do endereço do
chip, comando de acesso e dados, que é uma espécie de protocolo que precisa ser
feito para o envio de informações.
Programa
Faremos um programa que
consiste em comunicar o ESP01 com o MCP23016, a fim de termos mais GPIOs para
utilizar. Esses novos 16 GPIOs que teremos, então, controlarão um módulo relé
de 16 canais.
Os comandos serão enviados
para o ESP01 através de um aplicativo Android.
MCP23016
ESP-01
Essa é uma placa de 16 relés.
Montagem ESP01
Bibliotecas e variáveis
Vamos incluir as bibliotecas
responsáveis pela comunicação i2c e por criar o Access Point e o webserver.
Definimos o endereço do chip e das portas. Por fim, as variáveis para guardarmos os valores dos
pinos do MCP.
#include <Wire.h> // responsável pela comunicação i2c. #include <ESP8266WiFi.h>//responsável por criar o accesspoint e o webserver WiFiServer server(80);//webserver para acessarmos através do aplicativo //endereço I2C do MCP23016 #define MCPAddress 0x20 //ENDEREÇOS DE REGISTRADORES #define GP0 0x00 // DATA PORT REGISTER 0 #define GP1 0x01 // DATA PORT REGISTER 1 #define IODIR0 0x06 // I/O DIRECTION REGISTER 0 #define IODIR1 0x07 // I/O DIRECTION REGISTER 1 // guarda os valores dos pinos do MCP uint8_t currentValueGP0 = 0; uint8_t currentValueGP1 = 0;
Setup
Inicializamos o ESP01 e
configuramos as portas. Também efetuamos a configuração do Access Point e inicializamos
o server.
void setup() { Serial.begin(9600); delay(1000); Wire.begin(0,2); //ESP01 Wire.setClock(200000); configurePort(IODIR0, OUTPUT); configurePort(IODIR1, OUTPUT); writeBlockData(GP0, 0x00); writeBlockData(GP1, 0x00); setupWiFi(); //configuração do Access Point server.begin();//inicializa o server }
Loop
Aqui verifico
se algum cliente foi conectado ao server. Efetuamos ainda a leitura da primeira linha de
requisição. Extraímos os dados para manipulação, definimos o cabeçalho padrão
de resposta e enviamos esta resposta ao cliente.
void loop() { WiFiClient client = server.available(); // Verifica se um cliente foi conectado if (!client) { return; } String req = client.readStringUntil('\r');// Faz a leitura da primeira linha da requisição /* /MR é o header prefixo para saber se a requisição é a esperada para os relés */ if(req.indexOf("/MR") != -1) { parserData(req); //a partir da requisição extrai os dados para manipulação } else{ Serial.println("invalid request"); return; } client.flush(); String s = "HTTP/1.1 200 OK\r\n"; // cabeçalho padrão de resposta client.print(s); // envia a resposta para o cliente delay(1); } // end loop
parserData
A partir da requisição,
buscamos os dados referentes aos relés. Enviamos, então, os dados para o MCP23016.
//a partir da requisição busca os dados referente aos relés void parserData(String data) { uint8_t relay = -1; uint8_t gp = -1; uint8_t value = -1; int index = data.indexOf("/MR"); //busca o index do prefixo MR if(data[index+5] == '/') // /MR01/1, onde 0 = GP; 1 = RELE; 1 = ESTADO(on/off) { gp = data[index+3]-'0'; relay = data[index+4]-'0'; value = data[index+6]-'0'; //envia os dados para o MCP23016 //[relay-1] porque o MCP vai de 0-7 os pinos writePinData(relay-1, value, gp); } }
configurePort
Configuramos o modo dos pinos
GPIO (GP0 ou GP1).
//configura o modo dos pinos GPIO (GP0 ou GP1) //como parametro passamos: // port: GP0 ou GP1 // INPUT para todos as portas do GP trabalharem como entrada // OUTPUT para todos as portas do GP trabalharem como saida // custom um valor de 0-255 indicando o modo das portas (1=INPUT, 0=OUTPUT) // ex: 0x01 ou B00000001 ou 1 : indica que apenas o GPX.0 trabalhará como entrada, o restante como saida void configurePort(uint8_t port, uint8_t custom) { if(custom == INPUT) { writeBlockData(port, 0xFF); } else if(custom == OUTPUT) { writeBlockData(port, 0x00); } else { writeBlockData(port, custom); } }
writePinData
Nesta parte do código, mudamos
o estado de um pino desejado e enviamos os dados para o MCP.
//muda o estado de um pino desejado, passando como parametro: //pin = pino desejado; value = 0/1 (on/off); gp = 0/1 (PORT do MCP) void writePinData(int pin, int value, uint8_t gp) { uint8_t statusGP = 0; if(gp == GP0) statusGP = currentValueGP0; else statusGP = currentValueGP1; if (value == 0) { statusGP &= ~(B00000001 << (pin)); // muda o pino para LOW } else if (value == 1) { statusGP |= (B00000001 << (pin)); // muda o pino para HIGH } if(gp == GP0) currentValueGP0 = statusGP; else currentValueGP1 = statusGP; //envia os dados para o MCP writeBlockData(gp, statusGP); delay(10); }
writeBlockData & setupWiFi
Aqui, enviamos dados para o
MCP23016 através do barramento i2c. Na sequência, configuramos as propriedades
para habilitar o Access Point. Por fim, configuramos o WiFi para o modo Access
Point e criamos um AP com SSID e PASSWORD.
//envia dados para o MCP23016 através do barramento i2c //reg: REGISTRADOR //data: dados (0-255) void writeBlockData(uint8_t port, uint8_t data) { Wire.beginTransmission(MCPAddress); Wire.write(port); Wire.write(data); Wire.endTransmission(); delay(10); }
//configura as propriedades para habilitar o ACCESS POINT void setupWiFi() { WiFi.mode(WIFI_AP); WiFi.softAP("ESP01_RELAY", "12345678"); }
Aplicativo
Para criar o aplicativo
utilizamos o MIT App Inventor 2, que pode ser acessado através do link: http://ai2.appinventor.mit.edu/.
O aplicativo consiste em duas
telas contento oito pares de botões em cada, indicando o estado de cada relé.
A seguir veremos alguns dos blocos
de programação utilizados:
IMPORTANTE: o endereço IP padrão
do ESP como Access Point é 192.168.4.1
1. Quando
a tela inicializa guardamos na memória o IP e chamamos o procedimento para
recuperar o estado dos botões (ON/OFF).
2. Chama
a outra tela
1. Ao
clicar no botão ON de algum dos relés, faremos alterações visuais no botão
(blocos verdes). WebViewer1.GoToUrl faz uma requisição para o nosso ESP01
concatenando na url os dados MR01/1.
2. Ao
clicar no botão OFF de algum dos relés, faremos alterações visuais no botão
(blocos verdes). WebViewer1.GoToUrl faz uma requisição para o nosso ESP01
concatenando na url os dados MR01/0.
Esse procedimento serve para
recuperar o estado dos botões (relés), pois, ao mudar de tela, ela volta ao
padrão de criação.
O bloco amarelo se repete para
cada um dos pares de botões.
Seguem os arquivos do projeto
para download:
Arquivo de projeto MIT App
Inventor 2 – download
APK do aplicativo para
instalar no android – download
Faça o download dos outros
arquivos:
8 Comentários
Fernando, muito obrigado por semear o conhecimento!!!!!
ResponderExcluirFernando, muito obrigado
ResponderExcluirpode dar uma dica como faço para utilizar só o esp8266 sem o mcc23016
por exe: wemos d1 mini
Fernando, muito obrigado
ResponderExcluirpode dar uma dica como faço para utilizar só o esp8266 sem o mcc23016
por exe: wemos d1 mini
muito bom!!!!! como expandir as portas analógicas? o ideal é que as lâmpadas sejam ligadas a um interruptor three way, então é necessário sensor de corrente para cada relé e estes usam portas analógicas. Outra solucação seria usar um esp32 e suas 18 portas adc. será que dá certo?
ResponderExcluirAlguem pode me dizer uma foma de adcionar um interruptor fisico para esse projeto
ResponderExcluirvc é o cara meu amigo, parabens
ResponderExcluirnao consigo baixar
ResponderExcluirInfelizmente os links estão quebrados... Muita vontade de baixar e estudar os códigos... Tomara que fiquem disponíveis novamente!
ResponderExcluir