Construa Projetos IoT Simples com Arduino UNO, ESP-01, ThingSpeak e MIT App Inventor
Componentes e Materiais Necessários
- Arduino UNO × 1
- Espressif ESP8266 ESP-01 × 1
- Sensor de Temperatura DHT22 × 1
- Sensor de Temperatura DS18B20 1-Wire (para solo) × 1
- LDR - Resistor Dependente de Luz × 1
- Módulo Relé 2 Canais 5V CC × 1
Aplicativos e Serviços Online
- Arduino IDE
- ThingSpeak API
- MIT App Inventor
Sobre este Projeto
Nosso objetivo é basicamente coletar informações de uma unidade local e enviá-las à internet. Um usuário em qualquer lugar do planeta, visualizando essas informações, tomará decisões enviando comandos remotos aos atuadores, também localizados nesta unidade. Qualquer sensor ou atuador pode ser utilizado.
A maior parte do meu trabalho na área de IoT usava NodeMCU e, mais recentemente, ESP32. Mas acho importante não esquecer meus primeiros passos, há alguns anos, quando comecei a aprender IoT usando Arduino UNO e o bom e velho ESP8266-01. Decidi retornar a essa época (com um pouco mais de experiência) e explorar novamente esses ótimos dispositivos, conectando-os à nuvem usando o serviço web ThingSpeak.com. Também exploraremos controle remoto usando um App Android desenvolvido com MIT App Inventor.
O "Centro do nosso projeto IoT" será o ThingSpeak.com. A unidade local (UNO/ESP-01) capturará dados de sensores e status de atuadores, enviando-os à internet, "escrevendo" em um Canal de Status ThingSpeak específico. A unidade local também receberá dados da internet, "lendo-os" de Canais de Atuadores ThingSpeak específicos.
Um App Android também lerá esses dados do Canal de Status ThingSpeak e os exibirá ao usuário. Da mesma forma, o usuário, baseado nessas informações de status, pode enviar comandos aos atuadores, escrevendo nos Canais de Atuadores ThingSpeak (veja o diagrama de blocos acima para entender o fluxo de dados).
Passo 1: Introdução
Usando sensores comuns, nosso projeto capturará diversos dados, enviando-os à nuvem, onde todos podem vê-los pela internet. Para trabalhar esses dados, usaremos o serviço do ThingSpeak.com, uma plataforma IoT aberta que nos permite coletar, analisar e agir sobre esses dados.
Dados a serem coletados pelos sensores:
- Temperatura do ar e umidade relativa
- Temperatura e umidade do solo
- Luminosidade
O projeto terá 2 atuadores:
- Bomba Elétrica
- Lâmpada Elétrica
O status desses atuadores ("LIGADO/DESLIGADO") também deve ser enviado à nuvem.
A ideia é capturar dados dos sensores, por exemplo, de uma plantação, e enviá-los à nuvem. Baseado nesses dados, o usuário deve decidir:
- Ligar a Bomba se a umidade do solo estiver muito baixa
- Ligar a Lâmpada se a temperatura do solo estiver muito baixa
Para comandar remotamente nossos atuadores, usaremos um App Android.
Passo 2: BoM - Lista de Materiais
Alguns dos componentes mais importantes listados aqui têm link e preço indicativo em USD. Links são apenas para informação.
- Arduino UNO (Microcontrolador) - $10.00
- ESP8266-01 (Módulo de Comunicação) - $3.50
- DHT22 (Sensor Umidade e Temperatura do Ar) - $9.00
- DS18B20 (Sensor Temperatura Digital 1-Wire para solo) - $6.00
- YL-69 + LM393 (Sensor Umidade do Solo) - $2.00
- LDR (Sensor Luminosidade) - $0.20
- 2 x LEDs (Vermelho e Verde)
- 1 x Módulo Relé 2 Canais 5V CC com Optoacoplador Low Level Trigger - $7.00
- Bomba 5V CC - $3.00
- Lâmpada 220V
- 2 x Resistor 330 ohm (para LEDs)
- 2 x Resistor 10K ohm (para DHT22 e LDR)
- 1 x Resistor 4K7 ohm (para DS18B20)
- Protoboard
- Jumpers
- Fonte Externa 5V CC para Relés
Passo 3: O Hardware
Vamos montar o hardware do projeto. O ideal é instalar e testar por partes. Sugestão de etapas:
- Instalar e testar localmente todos os sensores
- Instalar e configurar o ESP-01 (BareMinimum)
- Alterar a instalação do ESP-01 para configuração final e testar
- Configurar Canal de Status ThingSpeak
- Instalar código ThingSpeak no Arduino e verificar status dos sensores na nuvem
- Desenvolver primeira versão do App Android para exibir status e mensagens
- Instalar atuadores (LEDs e Relés)
- Configurar Canais de Atuadores ThingSpeak
- Instalar e testar código Arduino com atuadores
- Desenvolver versão final do App Android
Passo 4: Conectando Sensores
Precisamos de algumas bibliotecas instaladas na IDE para ler os sensores corretamente. Verifique se tem todas instaladas. Configuração inicial:
// DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 5 // DS18B20 no pino D5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
int soilTemp = 0;
// DHT
#include "DHT.h"
#include <stdlib.h>
int pinoDHT = 11;
int tipoDHT = DHT22;
DHT dht(pinoDHT, tipoDHT);
int airTemp = 0;
int airHum = 0;
// LDR (Luz)
#define ldrPIN 1
int light = 0;
// Umidade do solo
#define soilHumPIN 0
int soilHum = 0;
No Setup e Loop:
void setup() {
Serial.begin(9600);
DS18B20.begin();
dht.begin();
}
void loop() {
readSensors();
displaySensors();
delay(10000);
}
Duas funções específicas: uma para ler sensores e outra para exibir valores no Monitor Serial:
/********* Leitura dos Sensores *************/
void readSensors(void) {
airTemp = dht.readTemperature();
airHum = dht.readHumidity();
DS18B20.requestTemperatures();
soilTemp = DS18B20.getTempCByIndex(0); // Sensor 0 captura Temp Solo em Celsius
soilHum = map(analogRead(soilHumPIN), 1023, 0, 0, 100);
light = map(analogRead(ldrPIN), 1023, 0, 0, 100); // LDR Escuro:0 => luz 100%
}
/********* Exibição dos Valores *************/
void displaySensors(void) {
Serial.print("airTemp (oC): "); Serial.println(airTemp);
Serial.print("airHum (%): "); Serial.println(airHum);
Serial.print("soilTemp (oC): "); Serial.println(soilTemp);
Serial.print("soilHum (%): "); Serial.println(soilHum);
Serial.print("light (%): "); Serial.println(light);
Serial.println("");
}
O código pode ser baixado do meu GitHub: Sensors_Test.ino
Passo 5: Configuração Inicial do ESP8266-01
O ESP-01 será usado como Ponte Serial, programado via "comandos AT". Primeiro, certifique-se que o ESP-01 está no Baud Rate correto (9.600 bauds). Geralmente vêm de fábrica com 115.200 baud e devemos alterar.
- Conecte o ESP-01 como mostrado acima.
- Conecte o Arduino ao computador, abra a IDE e carregue o exemplo
File > Examples > 01.Basics > BareMinimum(código vazio para evitar conflito de comunicação serial). - Abra o Monitor Serial da IDE e mude velocidade para 115.200 baud. Envie comando "AT". O ESP-01 deve retornar "OK".
- Mude a velocidade:
AT+CIOBAUD=9600ou, se necessário,AT+UART_DEF=9600,8,1,0,0. - No Monitor Serial, mude para 9600 baud. Teste: digite AT e veja resposta OK.
- Configure o módulo em Station Mode (Cliente WiFi):
AT+CWMODE=1. - Conecte à sua rede WiFi:
AT+CWJAP="nome_rede","senha"(mantenha aspas). - Se vir
WIFI CONNECTED / WIFI GOT IP, conexão estabelecida. - Para ver o IP:
AT+CIFSR. Anote o endereço IP.
Passo 6: Testando o ESP-01
Uma vez configurado, instale o ESP-01 no circuito final. Altere a fiação:
- ESP-01 RX (Amarelo) → UNO Pino D7
- ESP-01 TX (Laranja) → UNO Pino D6
- ESP-01 Ch-Pd (Marrom) → Vcc (3.3V)
- ESP-01 Reset (Azul) → UNO Pino D8
- ESP-01 Vcc (Vermelho) → 3.3V
- ESP-01 Gnd (Preto) → UNO GND
Teste simples com código:
#include <SoftwareSerial.h>
SoftwareSerial esp8266(6,7); // Rx => Pin 6; TX => Pin 7
#define speed8266 9600
void setup() {
esp8266.begin(speed8266);
Serial.begin(speed8266);
Serial.println("ESP8266 Setup test - use AT commands");
}
void loop() {
while(esp8266.available()) Serial.write(esp8266.read());
while(Serial.available()) esp8266.write(Serial.read());
}
Teste comandos AT no Monitor Serial:
* AT =====> ESP8266 retorna OK
* AT+RST =====> ESP8266 reinicia e retorna OK
* AT+GMR =====> ESP8266 retorna AT Version; SDK version; id; OK
* AT+CWMODE? =====> ESP8266 retorna tipo de modo
* AT+CWLAP =====> ESP8266 retorna access points próximos
* AT+CIFSR =====> ESP8266 retorna IP designado
Código no GitHub: ESP_AT_Config.ino
Para conectar ao WiFi automaticamente a cada reset, adicione chamada à função connectWiFi() no final do setup():
void connectWiFi(void) {
sendData("AT+RST\r\n", 2000, 0); // reset
sendData("AT+CWJAP=\"SEU_USUARIO\",\"SUA_SENHA\"\r\n", 2000, 0); // Conecta rede
delay(3000);
sendData("AT+CWMODE=1\r\n", 1000, 0);
sendData("AT+CIFSR\r\n", 1000, 0); // Mostra IP
Serial.println("8266 Conectado");
}
A função sendData() também deve estar no código:
String sendData(String command, const int timeout, boolean debug) {
String response = "";
EspSerial.print(command);
long int time = millis();
while ((time + timeout) > millis()) {
while (EspSerial.available()) {
char c = EspSerial.read();
response += c;
}
}
if (debug) Serial.print(response);
return response;
}
Passo 7: Conectando Sensores e ESP-01
Uma vez que todos os sensores estão instalados e testados e o ESP-01 funcionando, vamos integrar tudo e preparar para envio de dados à internet.
Passo 8: O ThingSpeak
Uma das partes mais importantes é o ThingSpeak, plataforma IoT aberta para coletar, analisar e agir sobre dados. Se não tem conta, cadastre-se em ThingSpeak sign up.
Crie um novo Canal com 2 atuadores, 5 sensores e um campo reserva:
- Field 1: Atuador 1
- Field 2: Atuador 2
- Field 3: Temperatura Ar (°C)
- Field 4: Umidade Relativa Ar (%)
- Field 5: Temperatura Solo (°C)
- Field 6: Umidade Solo (%)
- Field 7: Luminosidade (%)
- Field 8: Reserva (ex: contador de erros de comunicação)
Passo 9: Enviando Status para a Nuvem
Temos serviço na nuvem e sensores capturando dados localmente. Vamos enviar esses valores ao ThingSpeak.com. Escreveremos no canal ThingSpeak via string GET em 3 partes:
- Comando "Start":
AT+CIPSTART="TCP","184.106.153.149",80 - Comando "length":
AT+CIPSEND=116 - String GET para escrever nos campos do Canal de Status:
GET /update?api_key=SUA_WRITE_KEY&field1=pump&field2=lamp&field3=airTemp&field4=airHum&field5=soilTemp&field6=soilHum&field7=light&field8=spare
Código completo para envio (disponível no GitHub: SendingStatusTS_EXT.ino):
// Thingspeak
String statusChWriteKey = "6SRPQQKIE6AJVQE6"; // Status Channel id: 385184
#include <SoftwareSerial.h>
SoftwareSerial EspSerial(6, 7); // Rx, Tx
#define HARDWARE_RESET 8
// ... (bibliotecas sensores e variáveis)
void setup() {
Serial.begin(9600);
pinMode(HARDWARE_RESET, OUTPUT);
digitalWrite(HARDWARE_RESET, HIGH);
DS18B20.begin(); dht.begin();
EspSerial.begin(9600);
EspHardwareReset();
startWriteTiming = millis();
}
void loop() {
start:
error = 0;
elapsedWriteTime = millis() - startWriteTiming;
if (elapsedWriteTime > (writeTimingSeconds * 1000)) {
readSensors();
writeThingSpeak();
startWriteTiming = millis();
}
if (error == 1) {
Serial.println(" <<<< ERROR >>>>");
delay(2000);
goto start;
}
}
// ... (funções readSensors, writeThingSpeak, EspHardwareReset, startThingSpeakCmd, sendThingSpeakGetCmd)
Passo 10: App Android - Parte 1: Monitoramento de Status
Vamos criar a primeira parte do App Android. Primeiro, desenhamos a interface do usuário. A cada 2 segundos (definido pelo Clock1), chamamos um procedimento chamado "readArduino".
- O retorno do procedimento será o valor para cada variável de Status exibida na tela.
- Convertemos valores "0" e "1" dos atuadores para "OFF" e "ON" para melhor entendimento.
- Esses valores ("Status") serão exibidos nos "labels" correspondentes.
- As variáveis de status devem ser declaradas como Globais.
- O procedimento "readArduino" lerá o Canal de Status no ThingSpeak. Definimos a URL a ser enviada ao ThingSpeak. 3 variáveis globais devem ser declaradas e unidas para criar a URL. Um GET deve ser enviado ao Componente Web "ArduFarmBotStatusCh".
- O texto retornado chega em formato JSON. Este texto deve ser processado, lendo cada campo e armazenando na variável global correspondente.
- Por fim, chamamos o procedimento "Alarm", que analisa o status de dois sensores de solo. Se temperatura muito baixa (10°C), exibe mensagem. Se umidade menor que 60%, exibe mensagem. Um timer (Clock2) a cada 1 segundo alterna a cor do texto (branco/vermelho) para fazer a mensagem "piscar".
Código do App no GitHub: ArduFarmBot_Status_App_EXT.aia
Passo 11: Instalando Atuadores (LEDs e Relés)
Completamos o hardware. Instalamos os atuadores: controlaremos remotamente Liga/Desliga de Bomba e Lâmpada. A saída do Arduino ativará um Relé (e um LED) para essas ações. Usamos módulo relé com Optoacoplador Low-Level Trigger, alimentado por 5V separado para não exigir corrente no pino de entrada. O GND do Relé NÃO É CONECTADO ao GND do Arduino para evitar ruído.
Passo 12: Configurando Canais de Atuadores ThingSpeak
Criamos 2 novos canais, um para cada atuador. Anote Channel ID, Read e Write Keys. Escreveremos apenas no Field 1 de cada canal. Exemplo:
- Channel ID 375598 → LED Vermelho (Bomba): Field1=0 (OFF), Field1=1 (ON)
- Channel ID 375599 → LED Verde (Lâmpada): Field1=0 (OFF), Field1=1 (ON)
Passo 13: Instalando e Testando Código Arduino com Atuadores
Quando enviamos dados à web, escrevíamos no canal ThingSpeak (Status) para "transmitir" (upload). Agora devemos LER de um canal ThingSpeak (Atuador) para "receber" (download) dados.
Leremos do canal ThingSpeak via string GET em 3 partes:
- Comando "Start":
AT+CIPSTART="TCP","184.106.153.149",80 - Comando "length":
AT+CIPSEND=36 - String GET para ler último valor do Field 1 do Canal de Atuador:
GET /channels/375598/fields/1/last
Leremos dos canais ThingSpeak em intervalos de 10 segundos. Após enviar GET, recebemos resposta que deve ser "1" ou "0" em posição específica. Se diferente, ignoramos.
Principais diferenças do código anterior: função readThingSpeak(String channelID).
// Thingspeak
String canalID1 = "375598"; // Atuador1
String canalID2 = "375599"; // Atuador2
#include <SoftwareSerial.h>
SoftwareSerial EspSerial(6, 7); // Rx, Tx
#define HARDWARE_RESET 8
// ... (variáveis timers, relés, etc.)
void setup() {
Serial.begin(9600);
pinMode(ACTUATOR1, OUTPUT); pinMode(ACTUATOR2, OUTPUT);
pinMode(HARDWARE_RESET, OUTPUT);
digitalWrite(ACTUATOR1, HIGH); // Relé ativo em LOW
digitalWrite(ACTUATOR2, HIGH);
digitalWrite(HARDWARE_RESET, HIGH);
EspSerial.begin(9600);
EspHardwareReset();
startReadTiming = millis();
}
void loop() {
start:
error = 0;
elapsedReadTime = millis() - startReadTiming;
if (elapsedReadTime > (readTimingSeconds * 1000)) {
int command = readThingSpeak(canalID1);
if (command != 9) pump = command;
delay(5000);
command = readThingSpeak(canalID2);
if (command != 9) lamp = command;
takeActions();
startReadTiming = millis();
}
if (error == 1) {
Serial.println(" <<<< ERROR >>>>");
delay(2000);
goto start;
}
}
// ... (funções takeActions, readThingSpeak, EspHardwareReset, startThingSpeakCmd, sendThingSpeakGetCmd)
Código no GitHub: ReadingCommandTS_EXT.ino
Passo 14: Enviando Comandos aos Atuadores
Neste ponto, temos canais de atuadores configurados no ThingSpeak. Alterando valor do Field 1, vemos atuadores mudando. Para teste, podemos usar navegador comum:
- Ligar Bomba (LED Vermelho):
https://api.thingspeak.com/update?api_key=ACT1_WRITE_KEY&field1=1 - Desligar Bomba:
https://api.thingspeak.com/update?api_key=ACT1_WRITE_KEY&field1=0 - Ligar Lâmpada (LED Verde):
https://api.thingspeak.com/update?api_key=ACT2_WRITE_KEY&field1=1 - Desligar Lâmpada:
https://api.thingspeak.com/update?api_key=ACT2_WRITE_KEY&field1=0
Passo 15: Completando o App Android
Vamos completar o App. Anteriormente desenvolvemos App simples que lê status do ThingSpeak (READ do Canal Status). Agora devemos ESCREVER nos canais de atuadores, para que comandos sejam lidos pelo Arduino e atuem na Bomba e Lâmpada.
Para o usuário enviar comandos, usamos "botões". Um par (LIGAR e DESLIGAR) para cada atuador. Ao pressionar, cor do texto muda: LIGAR → Azul, DESLIGAR → Vermelho.
Teste o App enviando comandos para ligar/desligar atuadores. Verifique no Monitor Serial as mensagens trocadas entre ESP-01 e ThingSpeak.
Código completo do App no GitHub: ArduFarmBot_V1_EXT.aia
Passo 16: Juntando Tudo
Perfeito! Neste ponto, você tem App Android completo, hardware completo, mas ainda não tem código que leia e escreva continuamente no ThingSpeak. Vamos combinar tudo o que desenvolvemos. No código final, há verificações adicionais, ex: se ESP-01 não responde a comando AT, faz reset via hardware comandado por software. Código final no GitHub: ArduFarmBot_Light_EXT.ino
Passo 17: Conclusão
Há muito a explorar no mundo IoT com esses ótimos dispositivos, Arduino Uno e ESP8266-01. Voltaremos em breve com novos tutoriais! Acompanhe tutoriais MJRoBot!
Espero que este projeto ajude outros a encontrar seu caminho no excitante mundo da eletrônica, robótica e IoT!
Visite meu GitHub para arquivos atualizados: ArduFarmBot_Light
Para mais projetos, visite meu blog: MJRoBot.org
Saudações do sul do mundo!
Até o próximo tutorial!
Obrigado,
Marcelo
Código
Todos os trechos de código estão integrados nos passos acima. Repositório GitHub completo: https://github.com/Mjrovai/ArduFarmBot_Light
Esquemáticos
Diagrama elétrico: GitHub - Diagrama Fritzing
Processo de manufatura
- Construindo Código Paralelo C++17 SYCL em Placas IoT Raspberry Pi 4B+
- Monitor de Frequência Cardíaca IoT em Tempo Real com Arduino e MAX30100
- Servidor Web Arduino Uno WiFi: Controle LED via Navegador
- Construa uma Calculadora Básica com Arduino UNO – Projeto Fácil
- Display Portátil de Persistência da Visão com Arduino UNO e ATtiny85
- Portão de Triagem de Temperatura Sem Contato para Monitoramento Rápido e Preciso
- Arduino UNO com Shield WiFi: Exibição de Temperatura em Tempo Real na Web via Serial
- Monitoramento Meteorológico em Tempo Real com Arduino e ThingSpeak IoT
- Usando Termistor Facilmente: Guia Passo a Passo com Arduino
- Sistema de Controle de Piscina com Azure IoT: Sensores Inteligentes e Monitoramento Remoto