Controle ativado por voz com Android e NodeMCU

Em meu último tutorial: Quando o IoT encontra a Inteligência Artificial: Automação residencial com Alexa e NodeMCU exploramos como equipamentos ativados por voz como o Amazon Echo-Dot utilizando-se de um serviço da web (como o “Alexa”) podem controlar “dispositivos inteligentes” em nossas casas. Neste novo tutorial faremos o mesmo,  porém  em vez de usar o Alexa desenvolveremos nossa própria App em um smartphone Android controlando, tanto com botões quanto por voz, nossos dispositivos domésticos.

O diagrama de blocos nos dá uma geral do que pretendemos desenvolver:

Block Diagram.jpg

e o filme nos mostra como ficará o projeto final:

1: Lista de materiais (BoM)

Valores em USD, utilizados apenas como referência

  1. NodeMCU ESP8266-12E ($8.79)
  2. Mini BreadBoard ($1.00)
  3. 400-point Experiment Breadboard Breadboard ($ 4.97)
  4. 4-Channel Relay Module ($8.49)
  5. LEDs (vermelho, amarelo, verde e azul) ($1.00)
  6. 4 x Resistor (220 ohm)
  7. Male-Female Dupont Cables ($1.00)
  8. Fonte externa DC de 5V ou bateria

….. e naturalmente um telefone ou tablet Android (qualquer modelo com wifi servirá).

2: Conectando o NodeMCU à rede local de WiFi

Conectaremos o NodeMCU a rede WiFi local,  verificando seu endereço IP. Para isso, usaremos o pequeno programa abaixo, o qual fará parte do projeto final:
#include <ESP8266WiFi.h>
WiFiClient client;
WiFiServer server(80);
const char* ssid = "YOUR SSID";
const char* password = "YOUR PASSWORD";

void setup() 
{
  Serial.begin(115200);
  connectWiFi();
  server.begin();
}

void loop() 
{
}

/* connecting WiFi */
void connectWiFi()
{
  Serial.println("Connecting to WIFI");
  WiFi.begin(ssid, password);
  while ((!(WiFi.status() == WL_CONNECTED)))
  {
    delay(300);
    Serial.print("..");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("NodeMCU Local IP is : ");
  Serial.print((WiFi.localIP()));
}

No monitor serial voce poderá ver o IP Address assignado por seu Modem ao NodeMCU:

Serial Monitor Comm Test

Tome nota do endereço (em meu acaso: 10.0.1.3). Necessitaremos deste endereço para a conexão ao aplicativo Android que será desenvolvido mais adiante.

3: Montando o HW

Assembling the HW

Usaremos um módulo de relé de 4 canais para controlar 4 LEDs, simulando 4 dispositivos domésticos. Siga as instruções a seguir e termine as conexões:

Conecte as entradas dos relés com os pinos do NodeMCU como mostrado no diagrama e definido no código como mostrado abaixo:

int relay1 = 14;
int relay2 = 15;
int relay3 = 3;
int relay4 = 1;

Nossos dispositivos inteligentes serão simulados pelos LEDs coloridos:

  • relé 1 ==> LED vermelho
  • relé 2 ==> LED amarelo
  • relé 3 ==> LED verde
  • relé 4 ==> LED azul

Nosso Android App irá enviar um comando em forma de string,  o qual deverá ser interpretado pelo código de maneira a ativar cada um dos relés. Definamos as strings para cada comando:

  • Relé 1:
    • Ligar: “r1on”;
    • Desligar: “r1off”;
  • Relé 2:
    • Ligar: “r2on”;
    • Desligar: “r2off”;
  • Relé 3:
    • Ligar: “r3on”;
    • Desligar: “r3off”;
  • Relé 4:
    • Ligar: “r4on”;
    • Desligar: “r4off”;

Definamos uma variável que irá receber os comandos (command) e a lógica associada a mesma:

String  command ="";

Assim, por exemplo, se o aplicativo Android enviar como um comando: “r1on”,  o relé 1 (relay1) deverá ser ativado:

if (command == "r1on")
{
  digitalWrite(relay1, LOW);
}

Observe que os relés usados no projeto são ativados com um nível baixo (LOW).

Utilizando alsoif, escreveremos os demais comandos (veja o codigo completo ao final).

Também definiremos “comandos de grupo” para ligar (“allon”) e desligar (“alloff”) simultaneamente todos os dispositivos. Por exemplo, para ativar ao mesmo tempo todos os relés, usaremos o comando “allon” como mostrado abaixo:

    if (command == "allon") 
    {
      digitalWrite(relay1,LOW);
      digitalWrite(relay2,LOW);
      digitalWrite(relay3,LOW);
      digitalWrite(relay4,LOW);
    }

A mesma lógica deverá ser empregada para o comando “alloff”.

Siga o diagrama elétrico acima para concluir a conexão de todo o HW.

Agora faça o download do código completo:

Home_Automation_NodeMCU_Android_Voice_V2_EXT.ino a partir de meu GitHub.

Entre com as credenciais de sua rede local de WiFi:

const char* ssid = "YOUR SSID";
const char* password = "YOUR PASSWORD";

Faça o upload do código em seu NodeMCU e pronto! Você poderá verificar no  Monitor Serial se o programa está em execução. Deixe o programa rodando para que se possa testar o aplicativo Android desenvolvido a partir do próximo passo.

CUIDADO: Quando fizer o upload do código, desligue a alimentação dos relés para não sobrecarregar o NodeMCU.

4: A App Android : “Designer Tab”

 Usaremos a aplicação on-line: MIT App Inventor para o desenvolvimento de nossaApp Android:

MIT V2 0

Componentes Principais da Screen1 (veja foto acima)

  • Entrada do endereço IP
    • TextBox denominado “IP_Address”
  • 8 botões ON / OFF, um para cada relé:
    • Relay_1_ON
    • Relay_2_OFF
    • Etc
  • 2 botões ON / OFF para todos os dispositivos:
    • All_Devices_ON
    • All_Devices_OFF
  • Botão de Entrada de Voz
    • Voice_Input
  • Componentes não visíveis:
    • Web1
    • SpeachRecognizer1
    • TextToSpeach1
  • Outros:
    • Caixa de texto:
      • Speach_To_Text
    • Label:
      • Comm_Status

Ao final o aplicativo deverá ficar assim:

Screenshot_2017-03-29-16-33-37

5: A App Android: Botões

Devemos criar na tab Blocks, 10 botões. Todos seguirão a mesma estrutura que os 2 mostrados na foto.

MIT V2 2

Esses blocos de 2 botões foram criados para:

  • Relay_1_ON. Click
  • Relay_1_OFF.Click

Estas funções são chamadas quando se “clica” em um desses botões. Por exemplo, quando você clica no botão Relay_1_ON, 3 ações serão executadas:

  1. Um comando será enviado no formato: http: / ip_address * / r1on
  2. Um “eco” no mesmo formato é esperado devido a “call Web1.Get”
  3. Uma “mensagem” sonora será lida pela App: no caso: “Relé 1 ligado”

* O IP_Address será o que você digitar na Tela 1. Utilizando-se o default (10.1.0.3), a mensagem real seria: http: /10.0.1.3/r1on

Voce poderá utilizar qualquer mensagem nesta etapa, ou deixá-la vazia (“”) caso não deseje um retorno auditivo.

6: O App Android: Reconhecimento de voz

Os blocos abaixo mostram a construção do código para o reconhecimento de voz de nosso aplicativo:

MIT V2 3

Note que para qualquer comando de voz, o comando enviado será sempre em  minúsculas (uso do bloco de texto downcase). Isso facilitará a decodificação do comando de voz pelo NodeMCU.

Por exemplo, se você deseja “ativar” o relé 1, uma palavra ou sentença deve ser enviada para ser reconhecida pelo código do NodeMCU. Enviaremos para isto um comando de voz em português: “Ligar UM”

if (command == "r1on"  || command == "ligar 1"    || command == "ligar um")
{
  digitalWrite(relay1,LOW);
}

Assim, quando digo “ligar um”, a App irá enviar: http: / 10.0.1.3/ligar um (ou http: / 10.0.1.3/ligar 1) e o NodeMCU colocará seu pino em LOW,  ativando o relé 1.

7: O App Android: Manipulação de erro

The Android App: Error Manipulation

Se ocorrer um erro, o bloco acima escreverá os detalhes referente ao mesmo na última linha do App (Comm_Status). Você somente irá ver-lo se ao criar o App usar a opção Responsive.

8: Testes finais

Final Test

Você poderá criar seu aplicativo passo a passo, como mostrado nas etapas anteriores ou utilizar o fonte de meu projeto (.aia) diretamente no MIT App Inventor:

MIT V2 1

Caso você não tenha experiência no desenvolvimento de aplicativos Android, poderá executar o arquivo .apk diretamente em seu dispositivo Android.

Ambos arquivos .aia e .apk poderão ser baixados de meu GitHub:

Home_Relay_Voice_Ctrl_V2.aia

Home_Relay_Voice_Ctrl_V2.apk

9: Conclusão

Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica, robótica e do IoT!

Verifique o depositário no GitHub para obter os arquivos atualizados:

Home-Automation-with-Android-and-NodeMCU

Saludos desde el sur del mundo!

Até o próximo tutorial!

Obrigado

Marcelo

Anúncios

MJRobot é novamente finalista em concurso no site do Instructables.com!!!!!!

Com apenas 1 semana de vida e 25.000 views no site do Instructables.com, meu projeto: IoT feito simples: Estação meteorológica doméstica com NodeMCU e OLED acaba de ser eleito um dos finalistas do concurso: “SENSORS”.

Sensors finalist 2

Muito obrigado a todos que prestigiaram o projeto lá no site! Isso me deixa muito orgulho e animado a continuar nessa aventura pelos caminhos da eletrônica, IoT e robótica!

Nos vemos em meu próximo post!

Saludos desde el sur del mundo!

Abração

Marcelo

Quando o IoT encontra a Inteligência Artificial: Automação residencial com Alexa e NodeMCU

Exploraremos neste tutorial, como usar a Alexa, um assistente pessoal inteligente desenvolvido pela Amazon Lab126, popularizado pelo Amazon Echo e Echo-Dot.

Alexa é capaz de interação de voz, reprodução de música, fazer listas de tarefas, configurar alarmes, transmitir podcasts, tocar audiobooks e fornecer informações meteorológicas, de trânsito e outras informações em tempo real. Alexa também pode controlar vários dispositivos inteligentes usando-se como um hub de automação residencial. Vamos usar neste projeto, o “Echo-Dot”, que permite aos usuários ativar o dispositivo usando um wake-word (no caso, “Alexa”).

echo-dot features

No espaço da Domótica (automação residencial), Alexa pode interagir com vários dispositivos diferentes como Philips Hue, Belkin Wemo, SmartThings, etc. Em nosso caso, emularemos dispositivos do tipo WeMo, como estes mostrados abaixo (mas por apenas uma fração de seu preço):

WeMo

WeMo é uma série de produtos da Belkin International, Inc. que permitem aos usuários controlar eletrônicos domésticos de qualquer lugar. A suite de produtos inclui um interruptor, sensor de movimento, Insight Switch, interruptor de luz, câmera e app. O WeMo Switch (nosso caso aqui) pode ser conectado a qualquer tomada de casa, que pode ser controlada a partir de um iOS ou Android smartphone executando o WeMo App, via rede doméstica WiFi ou rede de telefonia móvel.

O diagrama abaixo mostra o que será desenvolvido em nosso projeto:

Home Automation Block Diagram V2E o vídeo abaixo, mostra como ficará o projeto ao final:

1: Lista de materiais (BoM)

Valores referenciais em USD

  • LEDs (vermelho e verde) ($1.00)
  • 2 x Resistor (220 ohm)
  • Fonte de alimentação externa de 5V DC ou batteria

2: Emulando o WeMo Switch

 wemo_echo_upnp

Os dispositivos WeMo utilizam UPnP para executar certas funções através da rede. A função de detecção do dispositivo começa com o Echo ou Echo-Dot (em nosso caso aqui) à procura de dispositivos WeMo utilizando UPnP. O dispositivo então responde ao Echo-Dot com seu URL utilizando HTTP sobre UDP. OEcho-Dot então solicita a descrição do dispositivo utilizando esse URL HTTP. A descrição é então retornada como uma resposta HTTP. Neste ponto, o Echo-Dot já “descobriu” o dispositivo. O Echo-Dot simplesmente se conectará ao WeMo através da interface HTTP e emitirá um comando do tipo “SetBinaryState”. O WeMo então “obedecerá”, retornando uma confirmação via HTTP. O diagrama  acima resume a comunicação entre o Echo-Dote o WeMo Switch.

Este tutorial não entrará em muito mais detalhes sobre este tópico. Procurei compilar informações obtidas em vários projetos da web, simplificando sua apresentação de maneira a apresentar uma visão geral sobre o uso da Alexa na automação residencial .

Algumas excelentes fontes de informação sobre o assunto poderão ser encontradas nos links abaixo:

HOW TO MAKE AMAZON ECHO CONTROL FAKE WEMO DEVICES, escrito por Rick Osgut

Building an IoT power switch with the ESP8266 (and control it with your Amazon Echo!)  escrito por  Wai Lun

Amazon Alexa + WeMos switch made with Arduino D1 Mini , codigos desenvolvidos por Aruna Tennakoon:

Projects using NodeMCU, conjunto de códigos desenvolvidos por Christopher Kuzma

Dito isto, com o que fui aprendendo nos diversos sites acima terminei chegando a um código de teste, o qual você poderá baixar desde meu GitHib: Alexa_LED_Control_V2_EXT.ino

Verifique se você possui todas as bibliotecas necessárias para executar o código, como: ESP8266WiFi.h, ESP8266WebServer.h e WiFiUdp.h. Caso não as tenha, você poderá obtê-las aqui:  Arduino core for ESP8266 WiFi chip.

3: Criando nosso WeMo Switch com o NodeMCU

Alex and NodeMCU

Para o nosso primeiro teste, conectemos um LED ao NodeMCU pino D1 como mostrado no diagrama abaixo:

Abra o arquivo  Alexa_LED_Control_V2_EXT.ino , o qual você baixou de meu GitHub e entre com suas credenciais de rede:

const char* ssid = "YOUR SSID";
const char* password = "YOUR PASSWORD";

Confirme se você definiu corretamente o pino onde o LED está conectado e dê um nome ao seu dispositivo. Alexa reconhecerá seu dispositivo por este nome:

String device_name = "lights";  // Name of device
int relayPin = D1;              // Pin to toggle

No meu caso, o dispositivo será denominado “lights“. Aqui neste primeiro exemplo o dispositivo acionará um único LED, mas o NodeMCU poderia estar conectado a um relé que por sua vez poderia ligar as luzes de meu laboratório, por exemplo.

Carregue o código no NodeMCU.

No monitor serial você pode ver a mensagem “Connecting to UDP” e “Connection Successful”. Isso significa que do lado NodeMCU tudo está OK.

Serial Monitor1

Estarei levando em consideração que voce já tenha o Echo-Dot instalado em sua rede., bem como o Alexa App em seu smartphone. Os procedimentos para a instalação de ambos é bem simples e basta seguir as instruções da Amazon fornecidas junto com o dispositivo.

Agora, necessitamos que a Alexa encontre seu dispositivo. Existem dois métodos para isso:

  • Utilizando o aplicativo Alexa no smartphone como mostrado nas fotos abaixo. Em nosso caso, a Alexa encontrará “1 Smart Home device”:  lights WeMo Switch.

Alexa app

  • Pedindo diretamente à Alexa através de um comando de voz, como por exemplo: “Alexa, Find connected devices” como poderá ser visto no vídeo abaixo:

Uma vez que a Alexa descobriu seu dispositivo, você poderá usar comandos de voz para o acionamento do dispositivo como mostrado abaixo:

4: Acionando vários dispositivos ao mesmo tempo

IMG_1224
Aprofundando um pouco mais,  desenvolveremos um sistema um pouco mais realista que acionará vários dispositivos ao mesmo tempo. Desta maneira, o projeto poderia ser usado em projetos envolvendo automação residencial  (domótica).

Usaremos um módulo de relé de 4 canais para controlar 2 lâmpadas e 2 tomadas.

Esta parte do projeto foi baseada em grande parte no tutorial de Charles Gantt,

How To: DIY Home Automation With NodeMCU and Amazon Alexa.

Siga as instruções abaixo:

Conecte as entradas dos relés com os pinos do NodeMCU conforme descrito abaixo:

int relayOne = 14;  // NodeMCU pin D5
int relayTwo = 15;  // NodeMCU pin D8
int relayThree = 3; // NodeMCU pin RX
int relayFour = 1;  // NodeMCU pin TX

Nossos “smart devices” serão 2 lâmpadas fixas (“Lights”)e 2 tomadas para uso geral (“Outlets”). Como vimos nas etapas anteriores, deveremos emular “WeMo Devices” e para fazer isso devemos nomeá-los como abaixo:

  • Light One
  • Light Two
  • Outlet One
  • Outlet Two

Em seguida, deveremos defini-los em nosso código para que a Alexa consiga encontrá-los. Também definiremos 2 comandos (on e off) e um número de porta de comunicação (“Port”) para cada dispositivo.

O formato geral deve ser:

lightOne = new Switch("Light One", 80, lightOneOn, lightOneOff);
lightTwo = new Switch("Light Two", 81, lightTwoOn, lightTwoOff);
outletOne = new Switch("Outlet One", 82, outletOneOn, outletOneOff);
outletTwo = new Switch("Outlet Two", 83, outletTwoOn, outletTwoOff);

Agora, você deve definir as 2 funções relacionadas a cada condição do dispositivo:

Para as lampadas:

void lightOneOn() {
  Serial.print("Switch 1 turn on ...");
  digitalWrite(relayOne, LOW);   // sets relayOne on
}

void lightOneOff() {
  Serial.print("Switch 1 turn off ...");
  digitalWrite(relayOne, HIGH);   // sets relayOne off
}

void lightTwoOn() {
  Serial.print("Switch 2 turn on ...");
  digitalWrite(relayThree, LOW);   // sets relayTwo on
}

void lightTwoOff() {
  Serial.print("Switch 2 turn off ...");
  digitalWrite(relayThree, HIGH);   // sets relayTwo Off
}

E para as tomadas:

void outletOneOn() {
  Serial.print("Socket 1 turn on ...");
  digitalWrite(relayFour, LOW);   // sets relayThree on
}

void outletOneOff() {
  Serial.print("Socket 1 turn off ...");
  digitalWrite(relayFour, HIGH);   // sets relayThree off
}

void outletTwoOn() {
  Serial.print("Socket 2 turn on ...");
  digitalWrite(relayTwo, LOW);   // sets relayFour on
}

void outletTwoOff() {
  Serial.print("Socket 2 turn off ...");
  digitalWrite(relayTwo, HIGH);   // sets relayFour off
}

Uma vez que estamos utilizando relés, poderíamos testar o projeto com  qualquer tipo de dispositivo real como TVs, geladeiras, etc. Obviamente que pelas especificações dos relés utilizados neste projeto, os dispositivos estariam limitados a 250VAC/10A ou 30 VDA/30A.

Em meu caso, decidi testar os 4 WeMo switches com dispositivos alimentados externamente com 5 V DC .

  • Como “Light 1”,  usarei um LED vermelho
  • Como “Light 2”, usarei um LED verde
  • Como “Outlet 2”, usarei um pequeno buzzer (pense em um rádio, aparelho de som…)
  • Como “Outlet 1”, usarei um pequeno ventilador

Abaixo o diagrama elétrico com as conexões:

Home Automation Electric Diagram

Com o HW pronto, baixe o código de meu GitHub: NODEMCU_ALEXA_WeMos_4X_Serial_Monitor_EXT.ino

Entre com suas credenciais de rede:

const char* ssid = "YOUR SSID";
const char* password = "YOUR PASSWORD";

E pronto!

Siga o mesmo procedimento como definido na etapa anterior para permitir que a Alexa encontre seus 4 dispositivos.

O vídeo abaixo mostra uma demonstração desta etapa:

5: Aplicação em Domótica (Automação Residencial)

Neste ponto do projeto, possuímos 4 dispositivos inteligentes funcionando adequadamente, os quais podem ser ativados e desativados individualmente. Mas suponha que queremos agrupá-los de maneira a serem utilizados em nossa casa. O que deveria ser feito?

Por exemplo, suponha que a nossa casa tenha 2 cômodos:

  • Quarto (“Bed Room”)
  • Sala (“Living Room”)

Agora, suponha que você queira ter uma lâmpada e uma tomada em cada habitação. O que devemos fazer, é agrupar nossos 4 dispositivos como mostrado no diagrama de blocos da introdução:

  • IMG_9708Quarto (Bed Room)
    • Light 2
    • Outlet 1 (Ventilador)
  • Sala (Living Room)
    • Light1
    • Outlet 2 (Buzzer)

Também criaremos outro grupo para lidar com todos os dispositivos, ativando / desativando todos os dispositivos ao mesmo tempo.

Criaremos uma versão 2 de nosso código onde teremos  3 novos “switches” que agora devem ser também  ser identificados pela Alexa. Para isto, adicionemos as seguintes linhas ao nosso código:

1. Definição das “Switches”:

Switch *allDevices = NULL;
Switch *bedRoom = NULL;
Switch *livingRoom = NULL;

2. Declaração dos “callbacks” para os novos grupos de dispositivos:

void allDevicesOn();
void allDevicesOff();
void bedRoomOn();
void bedRoomOff();
void livingRoomOn();
void livingRoomOff();
  1. No setup(), devemos associar os switches com os novos callbacks and Ports (Lembre-se que temos um máximo de 14 dispositivos que podem ser manipulados com este código):
allDevices = new Switch("All Devices", 84, allDevicesOn, allDevicesOff);
bedRoom = new Switch("Bed Room", 85, bedRoomOn, bedRoomOff);
livingRoom = new Switch("Living Room", 86, livingRoomOn, livingRoomOff);
  1. Adicionando “Switches upnp Broadcast Responder” ao setup():
upnpBroadcastResponder.addDevice(*allDevices);
upnpBroadcastResponder.addDevice(*bedRoom);
upnpBroadcastResponder.addDevice(*livingRoom);
  1. Adicionando as linhas ao loop():
allDevices->serverLoop();
bedRoom->serverLoop();
livingRoom->serverLoop();
  1. E finalmente, criemos as funções para os “grupos de dispositivos” com as ações a serem executadas quando a Alexa receber um comando de voz:
void allDevicesOn() 
{
  Serial.print("All Devices turn on ...");
  digitalWrite(relayOne, LOW);   // sets relay1 on
  digitalWrite(relayTwo, LOW);   // sets relay2 on
  digitalWrite(relayThree, LOW);   // sets relay3 on
  digitalWrite(relayFour, LOW);   // sets relay4 on
}

void allDevicesOff() 
{
  Serial.print("All Devices turn off ...");
  digitalWrite(relayOne, HIGH);   // sets relay1 off
  digitalWrite(relayTwo, HIGH);   // sets relay2 off
  digitalWrite(relayThree, HIGH);   // sets relay3 off
  digitalWrite(relayFour, HIGH);   // sets relay4 off
}

void bedRoomOn() 
{
  Serial.print("Bed Room turn on ...");
  digitalWrite(relayThree, LOW);   // sets relay3 on
  digitalWrite(relayFour, LOW);   // sets relay4 on
}

void bedRoomOff() 
{
  Serial.print("Bed Room turn off ...");
  digitalWrite(relayThree, HIGH);   // sets relay3 off
  digitalWrite(relayFour, HIGH);   // sets relay4 off
}

void livingRoomOn() 
{
  Serial.print("Living Room turn on ...");
  digitalWrite(relayOne, LOW);   // sets relay1 on
  digitalWrite(relayTwo, LOW);   // sets relay2 on
}

void livingRoomOff() 
{
  Serial.print("Living Room turn off ...");
  digitalWrite(relayOne, HIGH);   // sets relay1 off
  digitalWrite(relayTwo, HIGH);   // sets relay2 off
}

Este procedimento de 6 passos poderá ser utilizado para qualquer comando, dispositivo ou grupo de dispositivos que você deseja adicionar ao seu projeto.

Você poderá baixar o código completo desta etapa. desde meu GitHub:

NODEMCU_ALEXA_WeMos_4X_V2_EXT

Depois que o código é enviado e executado pelo NodeMCU, é hora de solicitar Alexa que “localize os novos dispositivos”. Como explicado anteriormente, você poderá fazê-lo usando um comando de voz ou pelo Alexa App. Em ambos casos, o resultado poderá ser verificado no aplicativo como mostrado abaixo. Sete dispositivos (“WeMo Switches”) deverão ser encontrados agora pela Alexa:

  • IMG_1261Living Room
  • Bed Room
  • All Devices
  • Outlet One
  • Outlet Two
  • Light One
  • Light Two

O vídeo abaixo mostra como nosso projeto completo de Automação Residencial funcionará:

6: Conclusão

Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica, robótica e do IoT!

Verifique o depositário no GitHub para obter os arquivos atualizados:

Home-Automation-with-Alexa-and-NodeMCU

E não deixe de visitar e seguir minha página: MJRoBot.org no Facebook

Saludos desde el sur del mundo!

Até o próximo tutorial!

Obrigado

Marcelo

IoT feito simples: Estação meteorológica doméstica com NodeMCU e OLED

Continuemos nossa exploração pelo mundo do IoT, nas asas do NodeMCU! Neste tutorial, desenvolveremos uma estação meteorológica doméstica, onde se exibirá informações tais como temperatura e condições climáticas, tanto para o dia corrente quanto para os próximos 3 dias. Nossa estação também exibirá informações internas da casa, como temperatura e umidade relativa do ar.

O diagrama em blocos abaixo, nos dá uma visão geral sobre o projeto:

No vídeo abaixo, você pode ver como ficará o projeto final:

1: Lista de materiais (BoM)

Valores referenciais em USD

  • Fonte externa de 5V ou bateria

2: Instalando o OLED no NodeMCU

Suponho que você já tenha o IDE do Arduino preparado com todas as bibliotecas necessárias para executar o código NodeMCU. Caso não, leia as instruções em meu tutorial premiado: Do “blink” ao BLYNK, uma viagem pela “Internet das coisas” nas asas do NodeMCU ESP-12E

Agora é hora de instalar nosso velho conhecido, o display OLED SSD1306, cujas principais características são:

  • Tamanho da tela: 0.96 “
  • Comunicação Serial I2C IIC SPI
  • 128X64
  • Display de caracteres na cor branca

Conecte os pinos do OLED ao NodeMCU, conforme descritos abaixo e no diagrama elétrico acima:

  • SDA    ==> D1 (5)
  • SCL * ==> D2 (4) * Você também poderá encontrar “SDC” ao invés de SCL
  • VCC   ==> 3.3V ou 5V
    GND ==> GND

O SSD1306 pode ser alimentado tanto com 5V (externo) quanto com 3.3V fornecidos diretamente do módulo NodeMCU.

Depois de conectar o OLED,devemos baixar e instalar sua biblioteca no IDE do Arduino. Usamos em projetos anteriores a biblioteca desenvolvida pela ACROBOT, que apesar de fácil de usar, é mais limitada. Desta vez exploraremos a poderosa biblioteca gráfica desenvolvida por Daniel Eichhorn.  Entre no link abaixo e faça o descarregue a biblioteca, instalando-a no IDE do Arduino:

https://github.com/squix78/esp8266-oled-ssd1306

Certifique-se de usar a versão 3.0.0 ou maior!

Depois de reiniciado o IDE, a biblioteca já deverá estar instalada.

A biblioteca suporta o protocolo I2C para acessar a modulo OLED, usando a biblioteca Wire.h:

#include <Wire.h>   
#include "SSD1306.h"
SSD1306  display(ADDRESS, SDA, SDC);

Listaremos apenas algumas API mais importantes, as quais serão utilizadas com o OLED.

A lista completa poderá ser encontrada no GITHub fornecido anteriormente neste tópico.

A. Controle de exibição do display:

void init(); // Initialise the display
void resetDisplay(void); // Cycle through the initialisation
void displayOn(void); // Turn the display on
void displayOff(void); // Turn the display offs
void clear(void); // Clear the local pixel buffer
void invertDisplay(void); // Inverted display mode
void normalDisplay(void); // Normal display mode
void setContrast(char contrast); // Set display contrast
void flipScreenVertically(); // Turn the display upside down

B. Desenho gráfico

void setColor(OLEDDISPLAY_COLOR color); // Sets the color of all pixel operations
void setPixel(int16_t x, int16_t y); // Draw a pixel at given position
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1); // Draw a line from pos 0 to pos 1
void drawHorizontalLine(int16_t x, int16_t y, int16_t length); // Draw a line horizontally
void drawVerticalLine(int16_t x, int16_t y, int16_t length); // Draw a lin vertically
void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const char *image); // Draw a bitmap in the internal image format

C. Operações com texto:

void drawString(int16_t x, int16_t y, String text); 
// Write the text at given position
uint16_t getStringWidth(const char* text, uint16_t length); 
// Returns the width of the const char* with the current font settings
uint16_t getStringWidth(String text); 
// Convenience method for the const char version
void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment); 
// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH
void setFont(const char* fontData); 
// Sets the current font. 

// Available default fonts: ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24

D. Frames (“Ui Library”)

A Ui Library é utilizada para fornecer um conjunto básico de elementos Ui chamados, Frames e Overlays. Um Frame é usado para fornecer informações onde o comportamento padrão é exibir um Frame por um tempo definido e passar para o próximo (como “Paginas”). A biblioteca também fornece um Indicador de qual frame (ou página) está sendo mostrada. Um overlay, por outro lado, é uma informação (por exemplo, um relógio) que é exibido sempre na mesma posição.

void init(); // Initialise the display
void setTargetFPS(uint8_t fps); //Configure the internal used target FPS
void enableAutoTransition(); //Enable automatic transition to next frame
void disableAutoTransition(); // Disable automatic transition to next frame.
void setAutoTransitionForwards(); // Set the direction if the automatic transitioning
void setAutoTransitionBackwards(); // Set the direction if the automatic transitioning
void setTimePerFrame(uint16_t time); //Set the approx. time a frame is displayed
void setTimePerTransition(uint16_t time); //Set the approx. time a transition will take
void setFrameAnimation(AnimationDirection dir); //Configure what animation is used to transition
void setFrames(FrameCallback* frameFunctions, uint8_t frameCount); //Add frame drawing functions
int8_t update();  // This needs to be called in the main loop

Uma vez que o OLED e sua biblioteca estejam instalados, escreveremos um simples programa, o “Hello World” para testá-los. Entre com o código abaixo em seu IDE, o resultado deverá ser algo como mostrado na foto:

/* Hello World OLED Test */
#include   // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
SSD1306  display(0x3c, 5, 4); // Initialise the OLED display using Wire library
void setup() 
{
  Serial.begin(115200);
  display.init(); // Initialising the UI will init the display too.
  display.flipScreenVertically();
  
  display.clear();
  drawHelloWorld(); 
  display.display();
}
void loop() 
{
  
}
void drawHelloWorld() 
{
    display.setTextAlignment(TEXT_ALIGN_LEFT);
    display.setFont(ArialMT_Plain_10);
    display.drawString(0, 0, "Hello world");
    display.setFont(ArialMT_Plain_16);
    display.drawString(0, 10, "Hello world");
    display.setFont(ArialMT_Plain_24);
    display.drawString(0, 26, "Hello world");
}

Agora, carregue a sketch: SSD1306SimpleDemo.ino, a qual faz parte dos EXEMPLOS incluídos com biblioteca.

Antes de executar o código, altere a conexão OLED pinos em conformidade:

// Initialise the OLED display using Wire library
SSD1306  display(0x3c, 5, 4);

O vídeo abaixo mostra o OLED executando o código de teste:

3: Obtendo os dados internos (“Indoor”)

Neste momento, nosso NodeMCU já pode se comunicar com o mundo pelo display! Instalemos agora um sensor digital de Temperature  e umidade, nosso bom e velho DHTxx (DHT11 ou DHT22). O site da ADAFRUIT fornece ótimas informações sobre esses sensores. Abaixo, algumas informações retiradas do site:

Visão geral

Os sensores de temperatura e umidade de baixo custo da família DHT, são muito básicos e lentos, mas ótimos para hobbyists que querem fazer algum registro de dados básico. Os sensores DHT são construídos em duas partes, um sensor de umidade capacitiva e um termistor. Há também um chip muito básico no interior que faz a conversão analógica para digital. O sinal digital gerado é bastante simples de ser lido usando-se qualquer micro controlador.

DHT11 vs DHT22

Temos duas versões do sensor DHT, eles se parecem e têm a mesma pinagem, mas possuem algumas características diferentes. Aqui estão as especificações:

DHT11

  • Bom para leituras de 20-80% de humidade com 5% de precisão
  • Bom para leituras de temperatura de 0-50 ° C ± 2 ° C de precisão
  • Não mais de 1 Hz taxa de amostragem (uma vez por segundo)
  • Ultra baixo custo
  • Alimentação: 3 a 5V
  • Consumo: 2.5mA max (durante a conversão de dados)
  • Tamanho do corpo 15.5mm x 12mm x 5.5mm
  • 4 pinos com espaçamento de 0,1 “

DHT22

  • Bom para leituras de 0-100% de humidade com precisão de 2 a 5%
  • Bom para leituras de temperatura de -40 a 125 ° C Precisão de ± 0,5 ° C
  • Não mais de 0,5 Hz taxa de amostragem (uma vez a cada 2 segundos)
  • Baixo custo
  • Alimentação: 3 a 5V
  • Consumo: 2.5mA max (durante a conversão de dados)
  • Tamanho do corpo 15.1mm x 25mm x 7.7mm
  • 4 pinos com espaçamento de 0,1 “

Como você pode ver, o DHT22 é um pouco mais preciso e melhor sobre um intervalo ligeiramente maior. Ambos usam um único pino digital e são “lentos”, pois você não pode consultá-los mais de uma vez a cada segundo (DHT11) ou dois (DHT22).

Ambos os sensores funcionam bem para obter informações sobre o interior da casa a serem exibidas em nossa Estação Meteorológica Doméstica.

O DHTxx tem 4 pinos (olhando para o sensor, como mostra a foto, o pino 1 é o mais à esquerda):

  1. VCC (conectado a 5V externo ou a 3.3V de NodeMCU)
  2. Dados
  3. Não conectado
  4. Terra.

Uma vez que normalmente você usará o sensor em distâncias inferiores a 20m, um resistor de 10K ohms deve ser conectado entre os pinos Data e VCC. O pino de saída será conectado ao pino D3 do NodeMCU (veja o diagrama acima).

Uma vez instalado o sensor em nosso módulo, faça o download da biblioteca DHT do repositório GitHub da Adafruit e instale-o no arquivo de bibliotecas do Arduino.

Uma vez recarregado o IDE do Arduino, a “biblioteca de sensores DHT” deverá estar instalada.

Definamos os parâmetros e variáveis associadas para o sensor  (usaremos em primeiro lugar oDHT22):

/* DHT22 */
#include "DHT.h"
#define DHTPIN D3  
#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);
int localHum = 0;
int localTemp = 0;

Agora criaremos uma função para leitura dos dados:

/***************************************************
* Get indoor Temp/Hum data
****************************************************/
void getDHT()
{
  float tempIni = localTemp;
  float humIni = localHum;
  localTemp = dht.readTemperature();
  localHum = dht.readHumidity();
  if (isnan(localHum) || isnan(localTemp))   // Check if any reads failed and exit early (to try again).
  {
    Serial.println("Failed to read from DHT sensor!");
    localTemp = tempIni;
    localHum = humIni;
    return;
  }
}

Uma vez de posse dos dados, usemos o OLED para mostrá-los :

/***************************************************
* Draw Indoor Page
****************************************************/
void drawDHT() 
{
  int x=0;
  int y=0;
  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(0 + x, 5 + y, "Hum");
  
  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(43 + x, y, "INDOOR");

  display.setFont(ArialMT_Plain_24);
  String hum = String(localHum) + "%";
  display.drawString(0 + x, 15 + y, hum);
  int humWidth = display.getStringWidth(hum);

  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(95 + x, 5 + y, "Temp");

  display.setFont(ArialMT_Plain_24);
  String temp = String(localTemp) + "°C";
  display.drawString(70 + x, 15 + y, temp);
  int tempWidth = display.getStringWidth(temp);
}

A foto abaixo mostra como os dados serão apresentados no display:

Você poderá fazer o download do código completo para operação “indoor” á partir de meu GitHub:

Home Weather Station Indoor code

4: Obtendo os dados externos (“Outdoor”):

Depois de ter as bibliotecas instaladas e o IDE reiniciado, baixe o programa completo a partir de meu GitHub:

MJRoBot Home Weather Station code

Depois de ter o código carregado no IDE do Arduino, abra o arquivo stationCredentials.h e entre com seus dados pessoais:

/* WIFI */
const char* WIFI_SSID = "YOUR SSID";
const char* WIFI_PWD = "YOUR PASSWORD";

/* Wunderground Settings */
const boolean IS_METRIC = true;
const String WUNDERGRROUND_API_KEY = "YOUR KEY";
const String WUNDERGRROUND_LANGUAGE = "EN";
const String WUNDERGROUND_COUNTRY = "CL";
const String WUNDERGROUND_CITY = "Santiago";

Observe que as informações meteorológicas que iremos recuperar do serviço W.Underground serão sobre Santiago (“city”) e CL (“country”: Chile). Você também deve alterá-las com os dados de sua cidade.

E é isso aí, pessoal!

Sua estação meteorológica doméstica deverá estar funcionando agora! Nas fotos abaixo, você pode ver meu protótipo funcionando:

5: Colocando a estação “na caixa”

A última etapa é montar nossa estação em uma caixa. Fiz duas montagens diferentes em caixas plásticas. Você decide a melhor maneira de “empacotar” seu projeto!

in the box 2

Em outra montagem, aproveitei e também testei a estação com o DHT11.

Não se esqueça de alterar os dados do DHT no arquivo “stationDefines.h”.

6: Conclusão

Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica e do IoT!

Visite o meu depositário no GitHub para obter os arquivos atualizados:

MJRoBot Home Weather Station depository

Não deixem de visitar e seguir minha página: MJRoBot.org no Facebook

Saludos desde el sur del mundo!

Até o próximo tutorial!

Obrigado

Marcelo

ArduFarmBot, o livro!

Acaba de sair do forno o primeiro livro da série “Tutoriais MJRoBot”, o “ArduFarmBot: Automatizando uma horta de tomates com a ajuda da Internet das Coisas – IoT”.

O livro pode ser adquirido nas lojas do Kindle na Amazon:

book amazon

Por favor divulguem o livro e se gostaram, deixem um comentário na página da: Amazon.com.br

Caso encontrem erros ou tenham sugestões, por favor usem a area de mensagens aqui no blog, que procurarei corrigir nas próximas edições.

O livro usa o controlador eletrônico “ArduFarmBot” como base para o aprendizado de como se trabalhar tanto em HW quanto em SW, com: a) Displays do tipo LCD e OLED; b) LEDs e botões; c) Acionamento de bombas e lâmpadas via relés e d) Leitura de sensores tais como: DHT22 (temperatura e umidade relativa do ar), DS18B20 (temperatura do solo), YL69 (umidade do solo) e LDR (luminosidade).

Todas as principais etapas dos projetos são detalhadamente documentadas através de textos explicativos, diagramas de blocos, fotos coloridas de alta resolução, diagramas elétricos utilizando-se do aplicativo “Fritzing”, códigos completos armazenados no “GitHub” e vídeos do “YouTube”.

No livro, são desenvolvidas duas versões do controlador eletrônico “ArduFarmBot”, que a partir da captura de dados provenientes de uma horta de tomates, tais como temperatura do ar e solo, umidade relativa do ar, umidade do solo e luminosidade, decidem autonomamente a quantidade certa (e quando) uma plantação deve receber calor e água. O ArduFarmBot também permite a intervenção manual, tanto em forma local quanto remota via Internet, a fim de controlar o acionamento de uma bomba de água e de uma lâmpada elétrica, esta última para ser usada na geração de calor para as plantas.

O livro está dividido em 3 partes.

Na primeira parte, a partir do “Arduino Nano” de desenvolve uma versão tanto manual operada por botões, quanto automática do “ArduFarmBot”.

book1

Na segunda parte, se aprofunda no projeto da automação e introduz a operação remota através da criação de uma página na internet. O “ESP8266-01” é utilizado para a conexão “Wifi”, enviando dados para o serviço especializado em IoT, “ThingSpeak.com“.

book2

Na terceira parte, uma segunda versão do “ArduFarmBot” é desenvolvida, introduzindo o “NodeMCU ESP8266-12E”, um poderoso e versátil dispositivo para projetos em IoT, que substitui de forma integrada tanto o “Arduino Nano” quanto o “ESP8266-01”, utilizados nas partes anteriores do livro. Nesta última, se explora também uma nova plataforma de serviços do universo IoT, o “Blynk”.

book4

Espero que gostem! E se preparem para o Tutoriais MJRoBot 2: “Brincando com robôs”.

Não deixem de visitar e seguir minha página: MJRoBot.org no Facebook

Saludos desde el sur del mundo!

Nos vemos em meu próximo post!

Obrigado e um abração,

Marcelo

 

“ArduFarmBot 2” – Sistema automático para irrigação e calor, agora com o NodeMCU e Blynk

Algum tempo atrás, desenvolvemos aqui o projeto de um sistema de jardinagem totalmente automatizado: “ArduFarmBot: Controlando um tomateiro com a ajuda de um Arduino e Internet das coisas (IoT)“. As principais especificações originais serão mantidas nesta nova versão, o ArduFarmBot 2, porém agora o projeto será baseado nas plataformas de IoT: NodeMCU ESP8266BLYNK.

Com base em dados coletados de uma plantação qualquer tais como, temperatura e umidade, tanto do ar quanto do solo, o ArduFarmBot 2 decidirá a quantidade certa (e quando) o plantio deve receber calor e água. O sistema deverá também permitir a intervenção manual de um operador para controlar uma bomba de água e uma lâmpada elétrica para gerar calor para a plantação. Esta intervenção manual deverá ser possível de ser executada tanto no local como remotamente via Internet.

Em suma, o sistema deve receber como

A. ENTRADA

  • Sensores:
    • Temperatura do ar
    • Umidade Relativa ao Ar
    • Temperatura do solo
    • Umidade do solo
  • Botões:
    • Bomba ON / OFF
    • Lâmpada ON / OFF

B. SAÍDA:

  • Atuadores:
    • Relé para controle da bomba
    • Relé para controle de lâmpada
  • Mensagens automáticas devem ser enviadas na ocorrência de eventos, tais como:
    • Bomba LIGADA
    • Lâmpada LIGADA
    • Sistema off-line
  • Exibição de dados
    • Todos os dados analógicos e digitais devem estar disponíveis para avaliação imediata
  • Armazenamento de dados
    • Dados históricos devem ser armazenados remotamente

O diagrama de blocos abaixo mostra os principais componentes do projeto.

1: Bill of Material (BoM)

  • 4.7K Ohms resistor – ($0.03)
  • 10K Ohms resistor – ($0.03)
  • 220 Ohms resistor – ($0.03)

2: O NodeMCU

Picture of The NodeMCU

O NodeMCU ESP-12E é a versão integrada do popular ESP8266, um Serial to Wi-Fi System On a Chip (SoC), que apareceu pela primeira vez em 2013 e lançado no mercado já no ano seguinte. O ESP8266 foi desenvolvido pela empresa chinesa com sede em Shangai, Espressif Systems, uma fabricante de circuitos integrados focada no desenvolvimento de chips de RF, particularmente Wi-Fi.

Existem vários módulos no mercado que se utilizam do chip ESP8266, Eles são nomeados ESP-NN, onde NN é um número 01, 02, … .. 12, etc. e as vezes seguido de uma letra. Estes módulos tipicamente possuem: o ESP8266 SoC, memória flash, um cristal e na maioria dos casos, uma antena. No link você pode encontrar a lista completa de dispositivos baseados  no ESP8266 encontradas no mercado: Família ESP8266 .

Os 2 módulos mais importantes são sem dúvida, a ESP-01 e o ESP-12E. No ArduFarmBot 2, usaremos o: ESP-12E Development Board (NodeMCU DevKit 1.0)

Para aumentar ainda mais a capacidade de utilização do módulo ESP-12E, foram adicionados regulação de potência e conectividade USB. O ESP-12E inclui:

  • Adaptador USB para UART: Silicon Labs CP2102,
  • NCP1117 3,3VDC Voltage Regulator,
  • Conector micro-USB,
  • Pinos adicionais com GND, Vin, 3,3VDC para facilitar o acesso durante o desenvolvimento.

Em suma, o NodeMCU ESP-12E é um dispositivo pronto para ser usado, bastando que você instale os drivers USB ao seu computador e comece a escrever programas que se conectam à sua rede Wi-Fi !

Especificações Técnicas:

  • Support STA/AP/STA+AP 3 working modes;
  • Built-in TCP/IP protocol stack, support multiple-channel TCP Client connection (max 5);
  • 0~D8, SD1~SD3: used for GPIO, PWM (D1-D8), IIC, ect; the driven ability can be arrived at 15mA;
  • AD0: one-way 10 bits ADC;
  • Power input: 4.5V~9V(10VMAX), support USB powered and USB debug;
  • Working current: ≈70mA(200mA MAX, continue), standby<200uA;
  • Transmission data rate: 110-460800bps;
  • Support UART/GPIO data communication interface;
  • Support update firmware remotely (OTA);
  • Support Smart Link;
  • Working temperature:-40℃~+125℃;
  • Driven mode: double large-power H bridge driven
  • Weight: 7g.

3: Instalando o NodeMCU com o Arduino IDE

Se você já tiver o NodeMCU instalado com o IDE, ignore esta etapa

Se você deseja programar e usar o NodeMCU como se fosse um Arduino, a boa notícia é que é possível escrever-se firmwares personalizados e carregá-los no chip (“flash-it”). É importante lembrar que qualquer novo “firmware personalizado” irá substituir qualquer coisa previamente armazenada na memória flash do chip, incluindo o firmware original carregado em fábrica (aquele que aceita os comandos AT). Embora possamos usar o SDK do fabricante para o desenvolvimento de firmwares personalizados, é muito mais fácil usar o bom e velho Arduino IDE.

Comecemos:

No Arduino IDE,  abra a janela de preferências e digite a URL (marcado em vermelho na foto abaixo) no campo Additional Boards Manager URLs e selecione OK.

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Picture of Installing the NodeMCU board at Arduino IDE

  • Selecione MENU  Tools → Board → Boards Manager…e vá rolando até encontrar a opção: esp8266 by ESP8266 Community , a qual deverá ser o último item da lista e clique INSTALL

arduino_ide_boards_esp8266

  • Instalando USB Drivers: O USB to Serial UART module incluído no dispositivo, é o  Silicon Labs’ CP2102, para o qual deveremos instalar o driver Virtual COM Port (VCP). No caso de meu MAC, o arquivo criado para comunicar com o CP2102 foi:  /dev/cu.SLAB_USBtoUART. Você pode encontrar o driver apropriado ao seu computador no seguinte link: CP210x USB to UART Bridge VCP Drivers
  • Depois de restartar o Arduino IDE , poderemos selecionar a placa no menu: Option Tools → Board → NodeMCU 1.0 (ESP-12E Module). Em seguida, especificar a correta frequência de operação da CPU: (Tools → CPU Frequency: “” → 80MHz) e velocidade de comunicação (Tools → Upload Speed: “” → 115,200). Finalmente, selecionar o port apropriado ao seu computador: (Tools → Port → /dev/cu.SLAB_USBtoUART).

nodemcu-ide-setup-3

Neste ponto estamos prontos para escrever nosso próprio firmware e enviá-lo ao dispositivo, mas vamos primeiramente tentar um dos exemplos incluídos com a biblioteca: File → Examples → ESP8266WiFi → WiFiScan. Após o upload, podemos abrir a janela do Serial Monitor e observar os resultados. Verifique que 115,200 baud é a velocidade selecionada no menu do canto inferior direito do Serial Monitor.

nodemcu-ide-setup-4

4: Instalando o Display OLED

Um grande companheiro para o nosso ESP-12E é o pequeno display do tipo OLED: SSD 1306. Ele será muito útil ao projeto, mostrando localmente os dados capturados, mensagens, etc. O modelo usado é um display de 128 x 64 pixels que se comunica via I2C, o SSD 1306, cujas principais características são:

  • 128 pixels na horizontal por 64 pixels na vertical. Assim se você usar por exemplo, caracteres de  8×8 pixels, obteremos um display de “16X8” (8 linhas de 16 caracteres cada).
  • Comunicação via I2C : se deve conectar ao NodeMCU I2C pins, usando:
    • SCL ==> D1 (equ. Arduino 5)
    • SDA ==> D2 (equ. Arduino 4)

Outra característica importante do SSD1306 é que você pode tanto alimentar-lo com 3.3V gerado diretamente pelo módulo nodeMCU, como via um Power Suppley externo de 5V, que será como faremos no projeto.

Uma vez conectado o display, você deve baixar e instalar sua biblioteca ao Arduino IDE. Nós usaremos a versão ACROBOT abaixo:

SSD1306 Arduino Library

Depois de ter reiniciado o IDE, a biblioteca deverá estar instalada. Carreguemos o sketch abaixo para testar o display OLED:


/***********************************************************************
* NodeMCU and OLED display "Hello World"
* Based on original code developed by: Makerbro at https://acrobotic.com/
* MJRoBot 12Oct16
************************************************************************/

#include 
#include 

void setup()
{
 Wire.begin(); 
 oled.init(); // Initialze SSD1306 OLED display
 oled.clearDisplay(); // Clear screen
 oled.setTextXY(0,0); // Set cursor position, start of line 0
 oled.putString(" MJRoBot.org");
 oled.setTextXY(4,0); // Set cursor position, start of line 4
 oled.putString(" HELLO, WORLD");
}

void loop()
{
}

Observe que quando você não definir um tamanho em pixels para os caracteres de texto, o padrão será 8X8. Para se definir um tamanho diferente, por exemplo,5X7, você poderá utilizar: oled.setFont(font5x7);

Abaixo o código para o “Hello World”:

5: Capturing Air Temperature and Humidity

Um dos sensores mais utilizados para a captura de dados meteorológicos é o DHT22 (ou seu irmão, o  DHT11), um sensor digital de humidade relativa do ar e temperatura. Ele usa internamente um sensor capacitivo de humidade e um termistor para medir o ar circundante, gerando um sinal digital em sua saída de dados. 

De acordo com a sua folha de dados (Datasheet), o sensor deve ser alimentado entre 3.3V e 5V (algumas especificações falam em até 6V max). Ele trabalha a partir de -40  a + 80 graus centígraods (algumas especs falam em + 125 ° C) com uma precisão de +/- 0,5 ° C de temperatura e +/-2% de umidade relativa. É importante ter em mente que o seu (“sencing period”) é em média de dois segundo (tempo mínimo entre leituras).

O site da Adafruit fornece uma série de informações sobre ambos, DHT22 e seu irmão DHT11. Para mais detalhes, visite a página:  Tutorial DHT22 / 11 .

O DHT22 tem 4 pinos (de frente para o sensor, o pino 1 é o mais esquerda):

    1. VCC (5V externo)
    2. Saída de dados
    3. Não conectado
    4. GND (Terra)

Uma vez que normalmente você usará o sensor em distâncias inferiores a 20m, um resistor de 10K deve ser conectado entre os pinos de dados e o VCC. O pino de saída deve ser conectado ao pino D3 do ESP-12E (veja o diagrama acima).

Uma vez que o sensor esteja instalado fisicamente no NodeMCU, baixe a biblioteca DHT a partir do repositório de programas:  Adafruit github e a instale junto as outras  bibliotecas de seu IDE (ambiente de desenvolvimento de programas do Arduino).

Uma vez que você recarregue o IDE, a biblioteca para o  sensor de DHT deverá aparecer como instalada. Execute o código abaixo para verificar se tudo está funcionando OK:

6: Capturando a humidade do solo

  • LM393 A0:    ao NodeMCU A0
  • LM393 VCC:  ao  VCC  5V externo (ou ao NodeMCU D8) Vide Nota abaixo *
  • LM393 GND: ao NodeMCU GND
  • LM393 D0:    Não conectado

(*) É importante destacar que o correto é conectar-se o VCC do Sensor a um Pino Digital do NodeMCU, definido como saída, de maneira a que o LM393 seja “alimentado” somente quando precisemos de uma leitura. Isto é importante não apenas para economizar energia, mas também para evitar a corrosão das sondas. Utilizando-se um sensor caseiro como foi o caso no projeto ArduFarmBot original, o sensor funcionaría sem problemas, mas tendo-se que alimentar o módulo comparador, o NodeMCU apresentou problemas com o  “soilMoisterVcc” conectado. Assim, conectei o LM393 direto a VCC (5V) externo como mostrado no diagrama elétrico acima  o código não precisa ser alterado).

Abaixo, rotina para ler o sensor conectado à porta analógica:

/***************************************************
 * Get Soil Moister Sensor data
 **************************************************/
void getSoilMoisterData(void)
{
  soilMoister = 0;
  digitalWrite (soilMoisterVcc, HIGH);
  delay (500);
  int N = 3;
  for(int i = 0; i < N; i++) // read sensor "N" times and get the average
  {
    soilMoister += analogRead(soilMoisterPin);   
    delay(150);
  }
  digitalWrite (soilMoisterVcc, LOW);
  soilMoister = soilMoister/N; 
  Serial.println(soilMoister);
  soilMoister = map(soilMoister, 600, 0, 0, 100); 
}

Alguns comentários sobre a rotina acima:

  • O dado do sensor é capturado 3 vezes, tirando-se uma média das mesmas.
  • Usamos MAP para configurar o intervalo em percentagem. Para definir os valores extremos, procedemos como abaixo:
    • Fazer um “curto-circuito” nas pontas de prova do higrômetro, isso equivalente a “100% de umidade”, o que gerará um valor de cerca de 0 na saída do ADC
    • Colocar o higrômetro”no ar”, se observa que o valor exibido no Serial Monitor, que em meu caso foi em torno de 600.
 Abaixo um codigo parcial para os testes até esta etapa do projeto:

7: Capturando a temperatura do solo

O DS18B20 é um sensor digital, o que o torna ideal para o uso em longas distâncias! Estes sensores digitais de temperatura  tipo “1-Wire” são bastante precisos (± 0,5 ° C em grande parte da gama) e podem fornecer até 12 bits de precisão à partir de seu conversor digital-analógico integrado. Eles funcionam muito bem com o NodeMCU usando um único pino digital, e você pode até mesmo conectar vários sensores no mesmo pino, pois cada um possui um ID único de 64 bits gravado de fábrica, para poder diferenciár-los.

  • O sensor funciona de 3,0 a 5,0V.
  • O sensor tem 3 fios:
    • Preto: GND
    • Vermelho: VCC
    • Amarelo: dados de 1 fio

Aqui, você pode encontrar os dados completos: DS18B20 Datasheet

Para usar o DS18B20 com o IDE do Arduino, importe as bibliotecas abaixo e a s instale em seu IDE:

Para testar o sensor, você pode usar o código “Simple.ino” incluído nos Exemplos da Biblioteca, como mostrado na foto acima. Carregue o código no seu NodeMCU e monitore a temperatura usando o Monitor Serial.

fp44q1eixkpxu98-large

A foto acima mostra o resultado esperado. Segure o sensor em sua mão, você deve ver a temperatura mudar para cerca de 32 / 34oC.

NOTA1: A biblioteca OneWire DEVE ser uma versão especial, modificada para ser usada com o ESP8266, caso contrário você receberá um erro durante a compilação. Você encontrará a última versão no link acima ou no arquivo zip abaixo:

8: Completando o HW

Para verificar se existe um “comando local”, ou seja se um botão foi pressionado, a função readLocalCmd() deve ser executada. Esta função lê cada botão, atualizando o status das variáveis correspondentes aos estados dos atuadores (pumpStatus e lampStatus). Observe que em vez de executar diretamente um comando digitalRead (pin), a função debounce(pin) é chamada. Isso é para evitar leituras falsas do botão. Se você quiser saber mais sobre o “debouncing”, visite o link:  Debouncing Tutorial.

/****************************************************************
* Read local commands (Pump and Lamp buttons are normally "HIGH"):
****************************************************************/
void readLocalCmd() 
{  
  boolean digiValue = debounce(PUMP_ON_BUTTON);
  if (!digiValue) 
  {
    pumpStatus = !pumpStatus;
    aplyCmd();
  }

  digiValue = debounce(LAMP_ON_BUTTON);
  if (!digiValue) 
  {
    lampStatus = !lampStatus;
    aplyCmd();
  }
}

No caso em que um botão é pressionado, outra função será chamada: aplyCmd (). E como o nome diz, esta aplicará o comando correspondente, ativando ou desativando os atuadores:

/***************************************************
* Receive Commands and act on actuators
****************************************************/
void aplyCmd()
{
  if (pumpStatus == 1) 
  {
    digitalWrite(PUMP_PIN, HIGH);
    displayData();
  }
  else
      {
        digitalWrite(PUMP_PIN, LOW);
        displayData();
      }
  
  if (lampStatus == 1) 
  {
    digitalWrite(LAMP_PIN, HIGH);
    displayData();
  }
  else
      {
        digitalWrite(LAMP_PIN, LOW);
        displayData();
      }
}

Considerações acerca do código:

Quando pensamos sobre o 4 grandes “grupo de tarefas” desenvolvidos até agora, podemos resumir-los em:

  • Ler Sensores
  • Ler Botões (comando local)
  • Atuar na bomba / lâmpada
  • Exibir dados

Perceberemos que o momento em que devemos realizar essas tarefas não são necessariamente os mesmos. Por exemplo, para ler os dados de temperatura e umidade do DHT 22, teremos que esperar pelo menos 2 segundos entre uma medida e outra, mas se esperamos alguns minutos, isto não fará diferença no projeto final. Para o sensor de umidade do solo, quanto menos medições fizermos, melhor (diminui a corrosão das sondas geradas por eletrólise). Mas quando pensamos nos atuadores, logo que pressionamos um botão, gostaríamos (e possivelmente precisaremos) de uma reação rápida.

Portanto, devemos usar aqui um “timer” para controlar corretamente o timing correto dessas tarefas. Poderíamos fazer isso usando o millis (), como fizemos no projeto ArdFarmBot original, mas aproveitaremos para conhecer outra ótima ferramenta, o SimpleTimer.h (siga as instruções no link ao lado para instalar a Biblioteca: SimpleTimer)

A biblioteca deve ser incluída no corpo principal do seu código, seguido de uma definição para o Timer do projeto:

  SimpleTimer timer;

Em seguida, defina os temporizadores:

  timer.setInterval(1000L, readLocalCmd);       // Read buttons at every 1 second
  timer.setInterval(2000L, getSoilTempData);    // Read Soil Temp at every 2 seconds
  timer.setInterval(2000L, getDhtData);         // Read DHT Sensor at every 2 seconds
  timer.setInterval(10000, getSoilMoisterData); // Read Soil Humidity at every 10 seconds
  timer.setInterval(10000, displayData);        // Display Data at OLED at every 10 seconds

9: ArduFarmBot 2,  “Contrôle Local”- Concluindo o código

Apresentando o Botão para Leitura dos sensores (“O amarelo”)

Como observamos na última etapa, precisaremos aguardar ciclos longos entre as medições do sensor de umidade do solo. Isto está bem para as nossas necessidades automáticas, mas para uma operação manual não vamos querer “esperar” 10, 15 ou mais segundos (ou mesmo minutos no caso real) para atualizar a leitura de um sensor. Também no mundo real, não faz sentido manter o display OLED “ACESO” ou “ON”, o tempo todo. Assim, o normal será “APAGADO” ou “OFF”.

Introduziremos esse 3 ª botão ao nosso projeto, o qual permitirá exibir os dados de leitura dos sensores a qualquer momento que quisermos, independentemente do tempo das leituras automáticas. Além disso, usaremos este mesmo botão para exibir dados no OLED quando os sensores forem atualizados. Abaixo da função readLocaCmd () alterada para interação com o novo botão:

/**************************************************************************
* Read local commands (Pump, Lamp and Sensor buttons are normally "HIGH"):
**************************************************************************/
void readLocalCmd() 
{  
  boolean digiValue = debounce(PUMP_ON_BUTTON);
  if (!digiValue) 
  {
    pumpStatus = !pumpStatus;
    aplyCmd();
  }

  digiValue = debounce(LAMP_ON_BUTTON);
  if (!digiValue) 
  {
    lampStatus = !lampStatus;
    aplyCmd();
  }

  digiValue = debounce(SENSORS_READ_BUTTON);
  if (!digiValue) 
  {
    turnOffOLED = !turnOffOLED;
    if (!turnOffOLED)
    {
      oled.setTextXY(0,0); oled.putString("UPDATING SENSORS");
      getDhtData();
      getSoilMoisterData();
      getSoilTempData();
      oledStart();
      displayData();
    }else oled.clearDisplay(); //turn off OLED
  }
}

Neste ponto, todo o HW está completado (usando-se LEDs como atuadores) e temos portanto todas as peças de SW à serem montadas.

O vídeo mostra o ArduFarmBot 2, operando em modo Local e Manual:

Você poderá fazer o download do código a ser utilizado na versão “Controle local”, diretamente em meu repositório:  GitHub: ArduFarmBot2_Local_Manual_Ctrl_V1

10: Automatizando nosso sistema de jardinagem

Neste ponto, todos os componentes do HW estão no lugar e como se viu na etapa anterior, o ArduFarmBot 2 pode ser controlado localmente por um operador através dos botões. O que falta agora é definir-se a “lógica” que permitirá ao nosso sistema realizar a tarefa de irrigar a plantação automaticamente! Para isto, precisamos incluir algum “cérebro” ao nosso projeto.

Para começar, definamos o intervalo inicial onde funcionarão os sensores. Esses valores devem ser alterados mais tarde usando-se valores práticos a serem obtidos em uma plantação real:

Umidade do solo:

  • “HÚMIDO”: Mais de 88% (não regar)
  • “IDEAL”: Entre 66% e 88% (Onde queremos trabalhar) e
  • “SECO”: abaixo de 66% (necessário ligar a bomba para aumentar a umidade)

Temperatura do ar:

  • “FRIO”: Abaixo de 12oC (Ligar a lâmpada para gerar calor)
  • “IDEAL”: entre 12oC e 22oC
  • “QUENTE”: Acima d 22oC (não ligar a lâmpada)

Você deve levar em conta que cada tipo de semente possui um intervalo ótimo de temperatura onde germinarão mais rapidamente. Por exemplo, para tomates o tempo mínimo para germinar as sementes será de 6 dias em temperaturas entre 20 e 25 oC, sendo que esta quantidade de dias aumentará para temperaturas inferiores ou superiores (mais de 43 dias para temperaturas inferiores a 10oC e 9 dias para temperaturas superiores a 35oC.

Você poderá verificar mais informações sobre este relacionamento (Temp / dias de germinação) no link abaixo:

The effect of soil temperature on seeds germination

Uma vez de posse desses dados: temperatura do ar, umidade do ar, umidade do solo e temperatura do solo, poderemos construir uma matriz complexa definindo como queremos que o nosso sistema de jardinagem automático funcione. Na Etapa 7 do ArduFarmBot: Part 2 – “Estação Remota” – IoT, se desenvolveu uma abordagem em profundidade sobre a relação Sensor-Matrix. Nesta etapa porém, utlizaremos apenas relações simples para facilidade de entendimento.

Definamos os parâmetros à serem usados em nosso código:

/* Automatic Control Parameters Definition */
#define DRY_SOIL      66
#define WET_SOIL      85
#define COLD_TEMP     12
#define HOT_TEMP      22
#define TIME_PUMP_ON  15
#define TIME_LAMP_ON  15

TIME_PUMP_ON e TIME_LAMP_ON são definidos como o tempo em segundos que a bomba e a lâmpada devem permanecer LIGADAS durante a operação automática.

Com base nos parâmetros acima, pensemos em algumas suposições muito simples a serem implementadas no código:

  • Se o solo estiver seco: (DRY) ==> Ligar a bomba (PUMP = ON)
  • Se a temperatura estiver fria (COLD) ==> Ligar a lâmpada (LAMP = ON)

Manteremos a coisa simples e não exploraremos todas as possíveis combinações bem como o  papel dos demais sensores como a umidade do ar ou temperatura do solo na equação, como fizemos no projeto original. Isto ficará como “lição de casa”! 😉

O código:

Criemos uma nova função, que com base na leitura dos sensores lidará automaticamente com os atuadores, ligando / desligando a bomba e a lâmpada: autoControlPlantation (). Esta função conforme mostrado abaixo, será chamada em todas os ciclos de leitura de sensores:

/**************************************************************
* Automatically Control the Plantation based on sensors reading
**************************************************************/
void autoControlPlantation(void)
{ 
  if (soilMoister < DRY_SOIL) 
  {
    turnPumpOn();
  }

  if (airTemp < COLD_TEMP) 
  {
    turnLampOn();
  }
}

A função tem duas tarefas básicas:

  • Controlar a bomba
  • Controlar a lâmpada

Abaixo as duas funções de controle chamadas a partir da função autoControlPlantation ():

***************************************************
* Turn Pump On for a certain amount of time
****************************************************/
void turnPumpOn()
{
  pumpStatus = 1;
  aplyCmd();
  delay (TIME_PUMP_ON*1000);
  pumpStatus = 0;
  aplyCmd();
}

/***************************************************
* Turn Lamp On for a certain amount of time 
****************************************************/
void turnLampOn()
{
  lampStatus = 1;
  aplyCmd();
  delay (TIME_LAMP_ON*1000);
  lampStatus = 0;
  aplyCmd();
}

Por fim, usemos o botão Sensor Read (“amarelo”) para não só interromper o programa durante um certo tempo durante a inicialização, mas também para exibir os parâmetros iniciais mais importantes, como mostrado na foto acima.

Neste ponto, o ArduFarmBot está totalmente funcional em termos de HW e SW.

O vídeo mostra o ArduFarmBot 2, operando em modo Local e Automático:

O código para a versão  “Local e Automático” do ArduFarmBot2 pode ser descarregada  de meu depositário:  GitHub: ArduFarmBot2_Local_Automatic_Ctrl_V2.

11: Criando a App BLYNK

É realmente muito fácil de se construir projetos IoT usando o BLYNK. A primeira coisa que você precisará, é ter a aplicação BLINK instalada no telefone e sua biblioteca instalada no IDE do Arduino. Se ainda não as tiver, siga os passos abaixo:

Uma vez que o Arduino IDE é recarregado, você deve estar OK para começar a usar BLINK em seu projeto IoT.

Agora, vamos abrir o aplicativo “Blynk”  no smartphone:

  1. Clique na tela Create New Project
  2. De um nome para seu projeto (Por exemplo: “ArduFarmBot 2”)
  3. Selecione o HW apropriado: NodeMCU
  4. Anote seu código do Authorization Token (você pode enviar-lo por e-mail e copiar-lo em seu código):
    char auth[] = "YourAuthToken";
  5. Pressione OK. Uma tela vazia cheia de pontos irá aparecer.
  6. Clique na tela para abrir o Widget Box

OK, vamos tomar um momento e pensar sobre o nosso ArduFarmBot 2 Blynk App e definir quais serão os Widgets a serem instalados. Revisitando a especificação geral descrita na introdução do projeto, podemos resumir que o nosso aplicativo precisará:

  • Ler todos os sensores e verificar o status dos atuadores
  • Tomar ações remotas, como “ligar / desligar” a bomba e a lâmpada
  • Enviar mensagens quando o sistema estiver “off-line” e / ou um atuador for ligado
  • Registrar a história de leitura dos sensores

De maneira a organizar as coisa, vamos dividir as tarefas descritas acima em 3 Tabs:

  • SENSORS
  • ACTUATORS / CONTROL
  • GRAPHICS

“Tabs” será o primeiro Widget a ser instalado. Uma vez selecionado, defina “Tab names” como acima.

Em seguida, entre em cada um dos Tabs criados e instale os Widgets como descritos abaixo:

SENSORS

  • Gauge: “Temp Air [oC]” Blue; input: V10 0 to 50; frequency: 5 sec
  • Gauge: “Humidity Air [%]” Green; input: V11 0 to 100; frequency: 5 sec
  • Gauge: “Soil Humidity [%]” Red; input: V12 0 to 100; frequency: 5 sec
  • Gauge: “Soil Temperature[oC]” Yellow; input: V13 -10 to 50; frequency: 5 sec
  • LED: “PUMP” Red; V0
  • LED: “LAMP” Green; V1

ACTUATORS / CONTROL

  • Button: “PUMP” Red; output: V3 0 to 1; mode: Switch; label: on: ACT, off: OK
  • Button: “LAMP” Green; output: V4 0 to 1; mode: Switch; label: on: ACT, off: OK
  • LED: “PUMP” Red; V0
  • LED: “LAMP” Green; V6
  • Notifications: Notify When HW goes offline: ON

GRAPHICS

  • Data to Show:
  • V10 “Temp Air”
  • V11 “Humidity Air”
  • V12 “Soil Humidity “
  • V13 “Soil Temp”

12: Alterando o código para introduzir as funcionalidades do Blynk

Para executar um aplicativo Blynk juntamente com seu código, você precisará:

  • Incluir a biblioteca BlynkSimpleEsp8266 no início do seu código
  • Durante o setup(), inicie com as credenciais do Blynk: Blynk.begin (auth, ssid, pass);
  • Defina uma temporização para enviar dados locais para o servidor Blynk: timer.setInterval (5000L, sendUptime);
  • Dentro do loop (), execute a função Blynk.run();
  • Crie a função sendUptime (); Onde você introduzirá os dados do sensor a serem enviados ao Blynk Server: Blynk.virtualWrite (VirtualPin, dados do sensor);

O código final deverá incluir agora um novo arquivo: “StationCredentials.h”:

char auth[] = "YOUR PROJECT TOKEN"; // Blynk project: "ArduFarmBot2"
char ssid[] = "YOUR LOCAL WIFI NAME";
char pass[] = "YOUR WIFI PASSWORD";

Other considerations:

Para usar um Widget do tipo: “Virtual LED” na app do Blynk, você necessitará definir-lo no início do código:

WidgetLED PUMPs(V0);  // Echo signal to Sensors Tab at Blynk App
WidgetLED PUMPa(V5); // Echo signal to Actuators Tab at Blynk App
WidgetLED LAMPs(V1);  // Echo signal to Sensors Tab at Blynk App
WidgetLED LAMPa(V6); // Echo signal to Actuators Tab at Blynk App

Para acender ou apagar o LED relacionado com a Bomba (PUMPs LED) que está conectado ao virtual PIN V0 por exemplo, chame as funções correspondentes abaixo:

  • PUMPs.on() ou
  • PUMPs.off()

Incluiremos os comandos na função applyCmd (), de maneira que os LEDs na app Blynk irão imitar os LEDs reais de nosso projeto. Também deveremos incluir o comando: Blynk.notify (“Mensagem a ser enviada”); na mesma função applyCmd (), uma para a Bomba e outra para a Lâmpada. Abaixo, a nova função:

/***************************************************
* Receive Commands and act on actuators
****************************************************/
void aplyCmd()
{
  if (pumpStatus == 1) 
  {
    Blynk.notify("ArduFarmBot2: Warning ==>> Pump ON"); 
    digitalWrite(PUMP_PIN, HIGH);
    if (!turnOffOLED) displayData();
    PUMPs.on();
    PUMPa.on();
  }
  else
      {
        digitalWrite(PUMP_PIN, LOW);
        if (!turnOffOLED) displayData();
        PUMPs.off();
        PUMPa.off();
      }
  
  if (lampStatus == 1) 
  {
    Blynk.notify("ArduFarmBot2: Warning ==>> Lamp ON");
    digitalWrite(LAMP_PIN, HIGH);
    if (!turnOffOLED) displayData();
    LAMPs.on();
    LAMPa.on();
  }
  else
      {
        digitalWrite(LAMP_PIN, LOW);
        if (!turnOffOLED) displayData();
        LAMPs.off();
        LAMPa.off();
      }
}

Para receber um comando a partir de um botão (Widget button) incluído na app Blynk, uma função BLYNK_WRITE () deve ser definida fora de uma função, loop () ou setup (). Para isso foi criado o código abaixo, um para cada Botão Blynk (PUMP e LAMP):

/****************************************************************
* Read remote commands 
****************************************************************/
BLYNK_WRITE(3) // Pump remote control
{
  int i=param.asInt();
  if (i==1) 
  {
    pumpStatus = !pumpStatus;
    aplyCmd();
  }
}

BLYNK_WRITE(4) // Lamp remote control
{
  int i=param.asInt();
  if (i==1) 
  {
    lampStatus = !lampStatus;
    aplyCmd();
  }
}

Abaixo, o vídeo mostra a operação automática do ArduFarmBot 2, agora incluíndo o Blynk:

O código para o ArduFarmBot2 em sua versão “Remote and Automatic control”, usando o Blynk pode ser descarregada de meu repositório:  GitHub: ArduFarmBot2_Ext_Auto_Ctrl__V3_0

13: Relés como atuadores

Como discutido na introdução, nosso objetivo final será cuidar de uma plantação. Com os dados fornecidos pelos sensores, vamos saber a temperatura do ar e do solo, umidade relativa do ar e o mais importante, quão “seco” está o solo. Com esses dados na mão, o nosso programa deve calcular se é necessário irrigar a plantação ligando uma bomba de água ou acender uma lâmpada elétrica para fornecer o calor adequado para a cultura.

Para isso, usaremos um pequeno módulo de relé de 5V tanto para a ativação da bomba quanto da lâmpada.

O circuito do diagrama do módulo de relé pode ser visto abaixo:

Pelo diagrama, devemos conectar :

  • Power Supply 5V ==> (4) “Vcc”
  • NodeMCU D6 ==> (3) “IN1” (Pump)
  • NodeMCU D7 ==> (2) “IN2” (Lamp)
  • NodeMCU GND ==> (1) “GND”

Dependendo do módulo de relés escolhido, os labels podem ser diferentes

Normalmente encontramos como saída, 3 pinos para cada relé: “NO” (“Normal Open“), “Ref” or “COM” (“Reference” or “Common“) and “NC” (“Normal Closed“). Usaremos o NO e o COM para cada relé.

No exemplo abaixo, o “COM” é o terminal para conectar ao pino positivo externo da fonte de alimentação de 5V(no caso da bomba (ou do 220VAC para a lâmpada). O “NO” será conectado à Bomba (ou Lâmpada).

No caso do relé escolhido e confirmado pelo diagrama acima, normalmente o IN1 e o IN2 devem estar em ALTO e sua ativação acontecerá com um nível BAIXO (menos de 2V). Com um nível BAIXO na saída do NodeMCU, a corrente fluirá de VCC para o pino D6 do NodeMCU, ativando a entrada do optoacoplador. O solenóide será acionado, “fechando” a saída NO (normalmente aberta) do relé, o que ligará a bomba.

Em relação a versão V3.0 do código desenvolvida na etapa anterior,  deveremos “inverter”a logica de acionamento dos atuadores (ou pinos digitais como saída). Os pinos D6 e D7 do NodeMCU deverão estar normalmente em HIGH. Assim a função de setup(), deverá ser alterada:

digitalWrite(PUMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
digitalWrite(LAMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)

Também deveremos  alterar a função applyCmd():

/***************************************************
* Receive Commands and act on actuators
****************************************************/
void aplyCmd()
{
  if (pumpStatus == 1) 
  {
    Blynk.notify("ArduFarmBot2: Warning ==>> Pump ON"); 
    digitalWrite(PUMP_PIN, LOW); // To be used with Relay module (inverted logic: activate with LOW)
    if (!turnOffOLED) displayData();
    PUMPs.on();
    PUMPa.on();
  }
  else
      {
        digitalWrite(PUMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
        if (!turnOffOLED) displayData();
        PUMPs.off();
        PUMPa.off();
      }
  
  if (lampStatus == 1) 
  {
    Blynk.notify("ArduFarmBot2: Warning ==>> Lamp ON");
    digitalWrite(LAMP_PIN, LOW); // To be used with Relay module (inverted logic: activate with LOW)
    if (!turnOffOLED) displayData();
    LAMPs.on();
    LAMPa.on();
  }
  else
      {
        digitalWrite(LAMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
        if (!turnOffOLED) displayData();
        LAMPs.off();
        LAMPa.off();
      }
}

O código para o ArduFarmBot2 em sua versão “Remote and Automatic control”, usando o Blynk e relés (ativos com “LOW”)pode ser baixado desde meu repositório:  Github: ArduFarmBot2_Ext_Auto_Ctrl__V4_0

14: Teste real com o ArduFarmBot 2

Você pode instalá-lo submerso em água ou “inline”. Usaremos o segundo método.

Ligue um dos fios da bomba ao relé IN1 e o outro ao pino de alimentação externa de 5V (+). Pegue o pino de alimentação (-) e ligue-o ao relé COM1.

O filme abaixo mostra o ArduFarmBot 2 operando em modo manual (local e remoto):

E finalmente, o vídeo abaixo mostra sua operação em modo automático:

15: Conclusão

Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da eletrônica e do IoT!

Para obter os arquivos atualizados, consulte meu repositório: ArduFarmBot2 GitHub

Não deixe de visitar e seguir minha página: MJRoBot.org no Facebook

Saludos desde el sur del mundo!

Nos vemos em meu próximo post!

Obrigado

Marcelo

O IoT feito simples: Monitorando a temperatura desde qualquer lugar

É incrível como hoje em dia podemos montar rapidamente um projeto de IoT utilizando-se apenas de um “chip” de uns poucos dólares e um aplicativo carregado em seu smartphone.

Neste tutorial também aprenderemos sobre um sensor digital de temperatura confiável e muito fácil de usar, o DS18B20.

Como mostrado no diagrama de bloco acima, os dados coletados pelo sensor serão enviados à Internet com a ajuda de um NodeMCU ESP8266-E e monitorados em um celular ou tablet utilizando-se o aplicativo Blynk.

1: Lista de Material

  • Resistor 4.7K Ohms

2: DS18B20 Sensor Digital de Temperatura

Usaremos neste tutorial, uma versão à prova de agua do sensor DS18B20. Esta configuração é  muito útil para se medir temperaturas de maneira remota em condições de umidade, por exemplo em coleta de dados de solo. O sensor é isolado e pode ser usado em até 125oC (Adafrut não recomenda usá-lo acima dos 100oC devido a a capa de PVC  utilizada em seu cabo).

O DS18B20 é um sensor do tipo digital, o que o torna util para uso mesmo em longas distâncias! Estes sensores digitais de temperatura  “1-Wire” são bastante precisos (± 0,5 ° C em grande parte da faixa) e podem fornecer até 12 bits de precisão a partir do conversor digital-analógico integrado. Eles funcionam muito bem com micro-controladores como o NodeMCU ou Arduino, utilizando-se de apenas um único pino digital. Você poderá até mesmo conectar-lo a vários outros sensores no mesmo pino, pois cada um dos sensores possui um único ID de 64 bits gravado de fábrica para diferenciá-los.

O sensor funciona de 3.0 a 5.0V, o que significa que ele pode ser alimentado diretamente a partir de um dos pinos de 3.3V do NodeMCU.

O Sensor possui 3 fios:

  • Preto: GND
  • Vermelho: VCC
  • Amarelo: 1-Wire Data

No link ao lado, voce encontrará a especificação completa: DS18B20 Datasheet

3: Conectando o sensor ao NodeMCU

Conecte os 3 fios do sensor NodeMCU como mostrado no diagrama abaixo:

  • Vermelho ==> 3.3V
  • Preto ==> GND
  • Amarelo ==> D4

Insira o NodeMCU, de forma que seus pinos correspondam ao diagrama elétrico acima. Observe que o chip pressionará o cabo do sensor, ajudando a manter os contatos do sensor no lugar.

introduza um resistor de 4.7K ohms entre VCC (3.3V) e Data (D4)

4: Instalando as bibliotecas apropriadas

Para o uso apropriado e de maneira simplificada do DS18B20, será necessária a instalação de 2 novas bibliotecas:

Instale ambas bibliotecas em seu diretório de Libraries do IDE

Observe que a biblioteca OneWire DEVE ser a versão modificada para ser usada com o ESP8266, caso contrário você receberá um erro durante a compilação. Você encontrará a última versão no link acima ou fazendo o download do arquivo zip abaixo:

5: Testando o sensor

Carregue o código em seu NodeMCU e monitore a temperature utilizando-se do  Serial Monitor IDE.

6: Utilizando o Blynk

  • Defina um nome (em meu caso: “Temperature Sensor”)
  • Selecione “NodeMCU” (ESP8266+WiFi) como HW Model
  • Copie o AUTH TOKEN a ser utilizado em seu programa (voce poderá enviar-lo diretamente a seu email).
Inclua um “Gauge” Widget

Defina:

  • Virtual pin a ser utilizado com o sensor: V10
  • A faixa de temperatura: -10 to 100 oC
  • A frequência para leitura dos dados: 1 sec
Includes a “History Graph” Widget,

definir V10 como virtual pin

Press “Play” (The triangle at right up corner)

Naturalmente, o Blynk  irá dizer-lhe que o NodeMCU está fora de linha. É hora de carregar o código completo no IDE do Arduino:

/**************************************************************
 * IoT Temperature Monitor with Blynk
 * Blynk library is licensed under MIT license
 * This example code is in public domain.
 * 
 * Developed by Marcelo Rovai - 05 January 2017
 **************************************************************/

/* ESP & Blynk */
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
char auth[] = "YOUR AUTH CODE HERE";

/* WiFi credentials */
char ssid[] = "YOUR SSID";
char pass[] = "YOUR PASSWORD";

/* TIMER */
#include <SimpleTimer.h>
SimpleTimer timer;

/* DS18B20 Temperature Sensor */
#include <OneWire.h>
#include<DallasTemperature.h> 
#define ONE_WIRE_BUS 2 // DS18B20 on arduino pin2 corresponds to D4 on physical board
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float temp;

void setup() 
{
 Serial.begin(115200);
 Blynk.begin(auth, ssid, pass);
 DS18B20.begin();
 timer.setInterval(1000L, getSendData);
}

void loop() 
{
 timer.run(); // Initiates SimpleTimer
 Blynk.run();
}

/***************************************************
 * Send Sensor data to Blynk
 **************************************************/
void getSendData()
{
 DS18B20.requestTemperatures(); 
 temp = DS18B20.getTempCByIndex(0);
 Serial.println(temp);
 Blynk.virtualWrite(10, temp); //virtual pin V10
}

Assim que o código for carregado e estiver em execução, verifique a aplicação BLYNK. Esta deverá também estar em execução.

Abaixo do código completo do Arduino para o seu projeto:

F05G780IXKPYLO4.ino

7: Conclusão

Como sempre, espero que este projecto possa ajudar outras pessoas a encontrarem o seu caminho no emocionante mundo da electrónica e do IoT!

“Saludos desde el sur del mundo!”

Não deixe de visitar e seguir minha página: MJRoBot.org no Facebook

Obrigado

Marcelo