Uma das formas mais interessantes de controlar um circuito a distância é por aplicativo. Portanto, vamos aprender a criar um aplicativo simples que comunica com o NodeMcu.

Na aula anterior, aprendemos a fazer requisições GET e POST em domínios na internet.


Aplicativo

Meu objetivo é ensinar a fazer um aplicativo que seja o mais simples possível, apenas para mostrar qual o caminho para aplicações que envolvam o NodeMcu e aplicativos Android. Sendo assim, vou utilizar a plataforma do AppInventor para criar um aplicativo bem básico.

Em outro post, já mostrei um pouco sobre o AppInventor ensinando a criar um aplicativo para comunicar com um módulo Bluetooth HC-05. O primeiro passo é acessar o site e fazer login.

Enfim, a ideia deste post é criar um aplicativo para ligar/desligar dois LEDs e também para exibir o estado deles (se cada um está aceso ou não). Com isso, cobrimos a parte de envio e recebimento de informações entre o NodeMcu e o aplicativo.

Interface

Componentes principais

Para o aplicativo proposto, vamos precisar de:

  • 2 botões (1 para cada LED), sendo que cada botão comuta o estado atual do LED.
  • Uma caixa de texto para inserir o IP do NodeMcu.
    • É por meio do IP que mandaremos as informações.
  • Um botão para definir o IP inserido na caixa de texto.
  • Alguns Labels para criar textos.
  • Adicionalmente, resolvi colocar uma imagem para melhorar o visual do aplicativo.

A forma como posicionei cada componente está mostrada abaixo:

Tela inicial do aplicativo

A forma como os itens acima estão listados está mostrada na imagem abaixo:

Lista de componentes usados

Dicas

Para adicionar a imagem, veja o passo a passo mostrado abaixo:

processo para adicionar imagem no app inventor

Primeiro, faça upload do arquivo desejado e depois selecione ele no componente de imagem. Por último, ajuste a largura e altura da imagem. Os componentes da imagem acima não são os mesmo utilizados no projeto deste post.

Para centralizar os componentes no meio da tela, você deve arrastar os componentes para dentro de um outro chamado “HorizontalArrangement” (ou “Organização Horizontal” em português). As configurações dele, devem ficar igual a imagem abaixo:

alinhamento horizontal no app inventor

Na imagem acima, a largura (Width) e o alinhamento horizontal foram alterados. Os componentes da imagem acima não são os mesmo utilizados no projeto deste post.

Por fim, para colocar dois elementos lado a lado, como é o caso do escrito “IP atual” e a caixa de texto, você deve fazer a mesma coisa que foi descrito acima. Utilizando um HorizontalArrangement, você coloca os componentes dentro dele e, entre os dois, você adiciona um Label sem texto.

O Label vazio serve para criar um espaço entre os dois elementos. Com isso, basta ajustar a largura (Width) do Label vazio para aumentar ou diminuir o espaço entre os dois outros componentes.

Componente da comunicação

Um outro elemento muito importante é o de comunicação, chamado ‘Web’. Portanto, encontre ele na paleta de componentes e arraste ao projeto.

Componente da comunicação

Como ele não é um elemento visível, ele irá aparecer no AppInventor apenas abaixo da tela:

Aviso componente web

 

Com a interface pronta, podemos passar para a programação do nosso aplicativo.

Programação

A programação foi feita o mais simples possível para facilitar o entendimento do processo todo. Entretanto, é possível criar diversas funcionalidades diferentes para deixar o aplicativo mais completo e inteligente.

Não pretendo mostrar o passo a passo de como encontrar cada componente da programação. Sendo assim, basta procurar, na paleta de blocos, os componentes que mostrarei nas imagens. Dar uma lida neste post antes, talvez ajude neste ponto.

Inicialização

Na inicialização do aplicativo, precisamos criar uma variável para guardar o IP do NodeMcu. Além disso, é interessante definir o texto da caixa de texto do IP atual como sendo o IP configurado a princípio. O IP inicial pode ser vazio, mas, como rodei os testes várias vezes, gravei o valor do IP e já deixei ele definido nesta parte. Veja a programação:

Inicialização do aplicativo

Repare que a variável IP é iniciada com um “http://” e a caixa de texto contém apenas o IP sem o “http://”. Fiz isso, porque o módulo web precisa do IP no formato “http://XXX.XXX.XX.XX” (endereço web) e decidi deixar a caixa de texto sem o “http://” para ficar mais fácil de digitar. A falta do “http://” será compensada no tópico abaixo.

Trocando o IP

Agora, precisamos trocar o IP utilizado na comunicação pelo IP que foi digitado na caixa de texto. Para fazer isso, basta mudar o valor da variável IP que criamos no tópico acima quando o botão “Definir IP” for pressionado. Mas lembrando que precisamos adicionar o “http://” antes do texto digitado. Com isso, temos:

Mudança do IP

Botões dos LEDs

O funcionamento do acionamento dos LEDs vai ser praticamente igual nós vimos nas aulas anteriores. Iremos mandar uma requisição para o NodeMcu com um certo parâmetro. Para ler mais a respeito das requisições, veja a aula 7.

O parâmetro que usarei para acionar cada led será apenas o nome dele (led1 para o 1º LED e led2 para o 2º LED). Portanto, enviando o parâmetro ‘led1’, o NodeMcu irá reconhecer esse texto e irá comutar o valor do 1º LED. Para mandar um certo parâmetro, basta adicionar ao IP uma barra com o parâmetro (XXX.XXX.XX.XX/parâmetro). Veja um exemplo da aula 7 abaixo:

nodemcu comandando led pelo web server

No módulo ‘Web’ do AppInventor, nós, primeiro, mudamos a URL (endereço) do módulo, para então fazer a requisição em cima desta URL. A requisição que o módulo ‘Web’ aceita é a GET. Veja os blocos de código utilizados  para os botões de cada LED:

Programação do acionamento dos LEDs

No caso do 1º LED, alteramos a URL para “http://192.168.0.7/led1” (exemplificando com o meu IP). Dessa forma, o NodeMcu irá receber a requisição com a URL com o ‘/led1’ e poderá processar o texto para fazer o acionamento do LED. Veremos isso mais à frente.

Lendo estado dos LEDs

Para ler o estado dos LEDs faremos o mesmo procedimento acima, mandaremos uma requisição para o NodeMcu. E, a partir desta requisição, o NodeMcu irá retornar um texto com o valor de cada LED.

O primeiro passo é fazer a requisição, e, para isso, usarei o parâmetro ‘estados’. Os blocos de código para o botão de receber o estado são os mesmos do acionamento dos LEDs:

Requisição para receber os dados

A diferença aqui é que a URL agora é “http://192.168.0.7/estados”. Feito isso, precisamos criar um bloco para processar os dados recebidos pelo aplicativo. Existe um bloco de código do próprio módulo ‘Web’ para isso, chamado “when Web.GotText”.

Com esse bloco, iremos testar se a resposta recebida contém o texto “LED1” para, então, mudar o texto do Label que mostra o estado dos LEDs.

Isso é feito pois o NodeMcu retorna uma mensagem tanto ao pressionamos o botão de acionar os LEDs, quanto ao pressionamos o botão de receber o estado deles. Logo, devemos exibir o estado dos LEDs apenas quando a mensagem recebida conter algo que tenha a ver com o estado dos LEDs. Para isso, escolhi o texto “LED1” mesmo.

Veja o código deste procedimento abaixo:

Recebendo dados pelo aplicativo

Se o conteúdo da resposta tiver o texto “LED1”, o texto do Label “Resposta” é difinido como todo o conteúdo da resposta. O conteúdo da resposta virá no formato “LED1: 0 – LED2: 0”, sendo que o 0 é o estado do LED para apagado e 1 para aceso.

Resultado

O último passo é construir o ‘apk’ do aplicativo e instalá-lo no celular. Fiz isso indo em Build->App (save .apk to my computer), e depois transferi o arquivo para o celular. O aplicativo funcionando pode ser visto abaixo (na imagem o código do NodeMcu já estava funcionando também):

Tela final do aplicativo


NodeMcu

Vamos então ao ponto de como integrar o aplicativo desenvolvido com o NodeMcu.

Circuito

Para o exemplo dado, em que temos dois LEDs, o circuito utilizado foi:

Circuito NodeMcu acendendo 2 LEDs

Os dois LEDs estão ligados em série com um resistor (220Ω). Além disso, o primeiro LED está ligado no pino D1 e o segundo no pino D2.

Programação

A programação para comunicar com o aplicativo é a mesma que a de criar um web server, com a diferença que não precisamos enviar uma página em ‘html’ mais. Portanto, para ver essa parte mais detalhada, recomendo ler a aula 7.

Só relembrando, a criação do web server se dá no seguinte formato:

1
2
3
4
5
6
7
8
9
10
srv = net.createServer(net.TCP)

srv:listen(80, function(conn)
    conn:on("receive", function(conn, payload)

        --Comandos

        conn:on("sent", function(conn) conn:close() end) -- Finaliza a comunicação
    end)
end)

Reconhecendo parâmetros recebidos

O parâmetro ‘payload’ será a mensagem recebida pelo NodeMcu. Sendo assim, devemos usar ele para verificar se nossos parâmetros (/led1, ou /led2 ou /estados) foram recebidos. A forma como fiz isso está mostrada abaixo:

1
2
3
if string.find(payload,"led1") ~=nil then
    gpio.write(led1, 1-gpio.read(led1)) -- Comuta o estado do LED
end

Então, se existe o texto “led1” na mensagem, comutamos o estado do LED.

Resposta do NodeMcu

Como o aplicativo está fazendo uma requisição, ele precisa receber uma resposta indicando que a comunicação foi bem sucedida. Para isso, basta enviar o código “HTTP/1.1 200 OK\n\n”:

1
conn:send("HTTP/1.1 200 OK\n\n");

Estado dos LEDs

Quando a mensagem recebida tiver o parâmetro “estados”, precisamos retornar o estado dos LEDs. Novamente, devemos verificar se, na mensagem recebida, existe o parâmetro “estados”, para então enviar a mensagem com o estado dos LEDs.

1
2
3
4
5
6
7
8
9
if string.find(payload,"estados") ~=nil then
    -- Envia o estado de cada LED no formato:
    -- LED1: 0 ou 1 - LED2: 0 ou 1
    conn:send("LED1: "
    .. gpio.read(led1)
    .. " - LED2: "
    .. gpio.read(led2)
    .. "\n\n");
end

Código completo

Leia os comentários para ter um melhor entendimento do programa.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
wifi.setmode(wifi.STATION)
wifi.sta.config {ssid="NOME_DO_SEU_WI-FI", pwd="SENHA_DO_WI-FI"}

-- Define os pinos de cada LED
led1 = 1
led2 = 2
-- Define os LEDs como saída
gpio.mode(led1,gpio.OUTPUT)
gpio.mode(led2,gpio.OUTPUT)

tmr.alarm(0, 1000, 1, function() --Aguarda conectar na rede
   if wifi.sta.getip() == nil then
      print("Conectando à rede...\n")
   else
      ip=wifi.sta.getip()
      print("IP: ",ip)
      tmr.stop(0)
   end
end)


srv = net.createServer(net.TCP)

srv:listen(80, function(conn)
    conn:on("receive", function(conn, payload)

        print(payload) -- Imprime os dados recebidos do servidor

        -- Verifica se na mensagem recebida existe o parâmetro led1
        -- Este é o caso da URL ter o parâmetro /led1
        if string.find(payload,"led1") ~=nil then
            gpio.write(led1, 1-gpio.read(led1)) -- Comuta o estado do LED
        end

        -- Verifica se na mensagem recebida existe o parâmetro led2
        -- Este é o caso da URL ter o parâmetro /led2
        if string.find(payload,"led2") ~=nil then
            gpio.write(led2, 1-gpio.read(led2)) -- Comuta o estado do LED
        end

        -- Envia o status de OK (sucesso na comunicação)
        conn:send("HTTP/1.1 200 OK\n\n");

        -- Verifica se na mensagem recebida existe o parâmetro estados
        -- Este é o caso da URL ter o parâmetro /estados
        if string.find(payload,"estados") ~=nil then
            -- Envia o estado de cada LED no formato:
            -- LED1: 0 ou 1 - LED2: 0 ou 1
            conn:send("LED1: "
            .. gpio.read(led1)
            .. " - LED2: "
            .. gpio.read(led2)
            .. "\n\n");
        end

       
        conn:on("sent", function(conn) conn:close() end) -- Finaliza a comunicação
    end)
end)

Resultados finais

Depois de instalar o aplicativo que criamos e rodar o código no NodeMcu, devemos esperar ele nos retornar o seu IP. Pois é esse IP que deveremos digitar no aplicativo para controlar o NodeMcu por ele. Veja o resultado que obtive logo após rodar o código no NodeMcu:

NodeMcu aguardando conexão

Sabendo o IP, basta ir no aplicativo, inserir ele na caixa de texto e clicar em “Definir IP”:

Tela final do aplicativo

O último passo é testar o aplicativo e ver se está tudo funcionando. É possível acompanhar o monitor de mensagens do NodeMcu para ver como as mensagens estão sendo recebidas. Clicando nos botões de acionar os LEDs e no de receber o estado deles, as mensagens chegaram ao NodeMcu corretamente:

NodeMcu recebendo mensagens

É possível ver o parâmetro de cada uma delas, além de algumas informações adicionais, como o dispositivo que transmitiu as mensagens (Lenovo) e a versão Android instalada nele (6.0.1).

 

Enfim, com essa base de como criar a comunicação entre um aplicativo e o NodeMcu, você deve ser capaz de criar aplicações mais interessantes e complexas. Por exemplo, controlar as lâmpadas de sua casa por meio de um aplicativo.

Interrupção e sleep com NodeMcu – Aula 10 – NB