terça-feira, 10 de maio de 2016

Código Básico do Web Server no ESP8266



Pessoal,

Vou lançar uma série de posts sobre o ESP8266. Se você ainda está perdido no assunto, veja esse vídeo aqui e a segunda parte aqui.

Depois de assistir esses dois vídeos você estará apto a montar o circuito do ESP8266 e também já saberá como configurar o Arduino IDE para subir a programação.

Agora vamos falar da programação básica do ESP8266. Nesse primeiro post eu vou mostrar o código básico de um Web Server.

Para quem não sabe o que é um Web Server, imagine páginas de um site que você gosta. Essas páginas que acessamos, por exemplo do Facebook, estão hospedadas em algum lugar. Esse lugar chama Web Server, ou seja "Servidor Web".

No caso do Facebook, as páginas ficam hospedadas em um servidor gigantesco. Já no nosso caso o ESP8266 pode se conectar em uma rede sem fio (WiFi) e operar como um Servidor Web pequeno.

Para isso basta usar o código básico que vamos ver agora e configurar os dados da rede sem fio. É bem simples, vamos ver a primeira parte do código:

No código acima vemos alguns includes, algumas declarações e uma função chamada "handleRoot".

Nas duas primeiras linhas temos os includes das bibliotecas necessárias que são a "ESP8266WiFi.h" com funções para auxiliar na conexão da rede sem fio. E temos também a biblioteca "ESP8266WebServer.h" que possui as funções para hospedar páginas Web.

Na terceira linha, temos a declaração do ESP8266WebServer e entre parêntesis a porta 80 que é a padrão da Web.

A partir da quarta linha temos uma função chamada handleRoot() que será executada toda vez que o endereço raiz do ESP8266 for acessado pelo navegador. Veremos como o ESP8266 sabe que precisa chamar essa função, em breve.

Dentro dessa função temos a declaração de uma variável do tipo "String" chamada "html". Nessa string colocamos todo nosso código HTML que será exibido ao carregarmos a página inicial do ESP8266.

Depois de preencher todo valor do HTML na variável, chamamos a função server.send(), passando os parâmetros de código de retorno (200 significa retorno OK), o tipo do retorno (text/html significa que retornaremos dados do tipo texto na formatação HTML), e a variável "html" que contém o conteúdo da página.

Pronto, isso é o necessário para responder a uma chamada de página principal quando acessamos o ESP8266 no endereço raiz.

Vamos ver agora como configuramos a rede e as configurações para isso funcionar.

Na imagem acima podemos ver que nesse código também temos a função setup(), que é bem conhecida para quem programa em Arduino. Afinal de contas esse é um código Arduino, que será compilado e carregado pelo Arduino IDE, então isso facilita bastante as coisas pra quem já programa nessa linguagem.

Na função setup() declaramos o inicio da Serial através da função Serial.begin(), com o valor 9600 que é um valor comum de velocidade da Serial. Você pode usar aqui outras velocidades como 115200 etc.

Igualmente precisamos chamar a função WiFi.begin() para iniciar a rede sem fio do ESP8266, mas nesse caso passamos duas configurações que são: o "nome da rede" e a "senha". Esses dados são da rede que vamos conectar, então normalmente são do roteador ou ponto de acesso onde conectamos nossos computadores. É importante que o ESP8266 esteja na mesma rede que os computadores que vão acessá-lo.

A partir desse ponto, temos configurações de IP, que são meio chatas, mas necessárias para sabermos como acessar nosso WebServer do ESP8266. É possível fazer com que a rede atribua automaticamente o IP e também é possível usar um nome pra facilitar o acesso, mas essa última opção ainda não consegui fazer funcionar.

A opção do IP automático pelo DHCP da rede eu não costumo usar pois senão não sabemos qual IP o ESP8266 pegou.

Na primeira linha após a função WiFi.begin() temos a declaração de uma variável IP, utilizada como máscara de rede, chamada subnet. Na linha seguinte temos a chamada da função WiFi.config(), que recebe 3 parâmetros, sendo o IP do ESP8266, o IP do roteador e o IP da subnet.

Nos dois primeiros parâmetros eu crio o IP na mesma linha para, e para a máscara de rede, que é o terceiro parâmetro, eu utilizo a variável subnet, criada na linha acima.

O código a seguir é um loop verificando o status da rede para saber se o ESP8266 já conseguiu conectar. Então é utilizada a função WiFi.status() na condição de um while() para verificar o status de conexão. Se for WL_CONNECTED, significa que conseguiu conectar e o código sai do while() para continuar. Se o roteador não estiver ao alcance da rede, o código vai ficar preso eternamente nesse ponto. E isso gasta muita energia. Veremos como contornar isso em outro post.

Veremos também (em outro post) como configurar esses parâmetros de nome da rede, senha e IP's sem que sejam fixos no código.

Enquanto o ESP8266 tenta conectar imprimimos na serial um ponto, indicando um andamento, como se fosse uma barra de progresso, através da função Serial.print('.');

Depois que o código passou pelo while(), imprimimos o IP que o ESP8266 conectou na rede chamando a função WiFi.localIP().

Essa é uma técnica que usamos para saber qual o IP que o ESP8266 conectou, quando usamos a atribuição de IP automática. Mas essa técnica só funciona quando estamos em desenvolvimento com o ESP8266 conectado no computador através da USB. Depois quando colocamos o ESP8266 em produção, instalando na automação da casa, não temos mais essa informação. Por isso prefiro usar IP estático.

Na linha seguinte temos a configuração que define qual URL vai acionar qual Função. No caso, temos apenas a URL raiz, identificada pela barra invertida "/" e a função "handleRoot". Utilizamos a função server.on() para configurar isso. Veja que é bem simples e você pode criar outras funções para qualquer endereço que você quiser.

Por exemplo, vamos dizer que você quer criar uma URL de saída chamando a função "funcSair", você faria assim:

server.on("/sair", funcSair);

E depois lógico você precisa criar a função funcSair() conforme fizemos com a handleRoot() e isso precisa ser antes do setup().

Finalmente utilizamos a função server.begin() para iniciar o servidor Web e depois avisamos na Serial que o servidor HTTP foi iniciado.

Servidor HTTP é um outro nome que damos para o Servidor Web, ou Web Server. É tudo a mesma coisa, embora o Servidor Web possa também acumular tarefas de outros protocolos além do HTTP, como FTP, SMTP etc. Veremos isso em outra hora.

Para terminar temos a função loop() que tem apenas uma única instrução.

A função server.handleClient() fica eternamente lidando com a conexão do cliente. Nesse cenário, o Servidor é o ESP8266 e o cliente é o Navegador de Internet que utilizamos para acessar as páginas HTML do ESP8266.

Baixe o código completo clicando aqui!

Até o próximo artigo!

Abraços,
Renato

2 comentários:

  1. Respostas
    1. warning: espcomm_sync failed
      error: espcomm_open failed
      error: espcomm_upload_mem failed

      erro ao validar seu exemplo, sabria me informar oque poderia ser?

      Excluir