IP fixo no ESP8266 com Arduino

Como definir um IP fixo para o ESP8266 na rede WiFi com Arduino, e escapar da variação típica do IP dinâmico

O módulo ESP8266 pode ser usado para deixar seu Arduino acessível via rede WiFi mas, na configuração default (que usa IP dinâmico), ele recebe seu endereço IP do roteador a cada conexão, podendo ser um IP diferente a cada vez1 – exigindo um procedimento adicional para consultar esse IP antes de poder acessar ou enviar dados para o Arduino pela rede sem fio.

Mas há uma alternativa: assim como acontece com computadores desktop, o ESP8266 pode definir seu próprio endereço IP como um valor escolhido por você (o chamado IP fixo ou IP estático), e assim – se tudo o mais permanecer normal – os acessos após cada reinicialização dispensarão essa consulta prévia.

Para poder fazer isso, você precisa basicamente de 3 informações (além do nome e senha da rede sem fio à qual o ESP8266 deve se conectar):

  • um endereço IP livre na sua rede local,
  • a máscara de sub-rede dela (em redes domésticas geralmente é 255.255.255.0), e
  • o endereço do gateway, que em redes domésticas geralmente é o próprio IP do roteador WiFi.

Se você não souber algum desses parâmetros, consulte o administrador da sua rede ou a configuração do roteador.

Nota: este artigo é sobre programação do ESP8266 conectado a um Arduino e exige conhecimentos intermediários sobre o funcionamento prático de ambos. Sugere-se que o leitor tenha dominado os conceitos básicos expostos em “ESP8266 do jeito simples: conexão ao Arduino, acesso à rede WiFi e resposta a ping” e em “ESP8266: Comandos AT” antes de prosseguir.

O comando AT+CIPSTA_DEF

Tendo os 3 parâmetros acima à mão, basta usar o comando AT+CIPSTA_DEF do seu ESP8266 para definir o endereço IP fixo a ser usado por ele.

Como um exemplo simples, vamos imaginar que o IP do roteador WiFi da sua casa seja 192.168.0.254, que a máscara da sub-rede seja 255.255.255.0, e que você verificou que o IP 192.168.0.235 está permanentemente disponível para uso. Nesse exemplo, para o ESP assumir para si este IP que está disponível, o comando a ser enviado a ele pelo Arduino seria:

AT+CIPSTA_DEF="192.168.0.235","192.168.0.254","255.255.255.0"

Esse comando2 faz mais do que mudar o endereço IP naquele momento: ele define na memória permanente que esse IP fixo deve passar a ser usado sempre3 a partir de agora, inclusive em futuras conexões a qualquer rede.

A definição de IP fixo no ESP8266 fica gravada na memória permanente, até que você a defina de outra forma explicitamente.

Se um dia você quiser voltar a usar a obtenção automática de IP, pode usar o comando AT+CWDHCP_DEF=1,1 para reativá-la – inteligentemente, o ESP8266 faz com que o AT+CIPSTA_DEF e o AT+CWDHCP_DEF anulem automaticamente um ao outro (porque não faria sentido continuar a obter automaticamente um IP da rede se um IP default já está definido localmente, por exemplo).

Se você quiser apenas mudar temporariamente o IP, pesquise sobre o comando AT+CIPSTA_CUR, com os mesmos parâmetros do AT+CIPSTA_DEF mas que muda o IP apenas na hora, sem alterar as configurações permanentes do ESP8266. Se for usar essa forma alternativa, fique atento: se a conexão WiFI cair e o ESP8266 a reestabelecer, ou em qualquer outra descontinuidade, o módulo vai seguir o que estiver definido na sua configuração permanente, e pode vir a mudar o IP que você definiu, caso você tenha usado esse comando alternativo.

IP fixo no ESP8266 com Arduino: exemplo de código

O que nos interessa é apenas uma linha de código mas, para demonstrá-la, é necessário ter um programa com funcionalidades que permitam verificar o que essa linha faz.

O programa a seguir é uma versão reduzida e adaptada daquele que eu apresentei no artigo “ESP8266 do jeito simples: conexão ao Arduino, acesso à rede WiFi e resposta a ping”, e o que ele faz é conectar-se à rede sem fio, trocar (definitivamente) por um IP fixo o IP dinâmico recebido dela, e aí parar, deixando o ESP conectado, de modo que possamos ir no nosso computador e dar ping no endereço que escolhemos para o ESP8266 – e ele vai responder.

Vamos ao código completo para o IP fixo no ESP8266 com Arduino, colorizado para facilitar a explicação que vem após:

#define VELOCIDADE 115200

String REDE="br-arduino";
String SENHA="senha-da-rede-wifi";

String IPLIVRE="192.168.0.235";
String MASCARA="255.255.255.0";
String ROTEADOR="192.168.0.254";

#include <SoftwareSerial.h>
SoftwareSerial monitorSerial(9, 8); // RX, TX

void cmdESP(String cmd, String msg="", int limite=7000) {
  // envia um comando para o ESP, aguarda, exibe e descarta a resposta
  if (msg!="") monitorSerial.println(msg);
  Serial.println(cmd);
  unsigned long chegada=millis();
  boolean continuar=true; 
  String S="";
  unsigned long ultimochar=0;
  while (continuar) { 
    if (Serial.available()) {
      char c = Serial.read();
      ultimochar=millis();
      S=S+c;
      if (c==10) {  // LF, fim da linha recebida
        byte p=S.indexOf(13);
        String S1=S.substring(0,p);
        if (S1=="OK") continuar=false;
        if (S1=="ready") continuar=false;
        if (S1=="no change") continuar=false;
        if (S1=="ERROR") continuar=false;
        monitorSerial.print(S);
        S="";
      }  
    }  
    if (millis()-chegada > limite) continuar=false;
  }
  if (S!="") monitorSerial.print(S);      
}


void setup() {
  monitorSerial.begin(VELOCIDADE);
  monitorSerial.println("*** ESP8266 Static IP / IP fixo - BR-Arduino.org");
  delay(2000);
  Serial.begin(VELOCIDADE);
  Serial.setTimeout(5000);

  String cmdConectar="AT+CWJAP=\""+REDE+"\",\""+SENHA+"\"";
  String cmdMudarIP="AT+CIPSTA_DEF=\"" + IPLIVRE + "\",\"" + ROTEADOR +"\",\"" + MASCARA + "\"";
  
  cmdESP("AT+CWMODE=3", "Modo de operacao misto, AP + STATION");
  cmdESP(cmdConectar,"Conectando a uma rede WiFi",30000);
  cmdESP("AT+CIFSR","Consultando os enderecos IP definidos inicialmente",10000);
  cmdESP(cmdMudarIP,"Definindo nosso proprio IP fixo");
  cmdESP("AT+CIFSR","Consultando novamente os enderecos IP, apos definicao acima.",10000);
  
  //cmdESP("AT+CWDHCP_DEF=1,1","Reativando o IP dinamico.");
}

void loop() {
}

As linhas iniciais são as definições do programa: a velocidade de conexão ao seu ESP8266 (115200 é o default nos modelos e firmwares recentes, mas antes o default era 9600), os dados da rede sem fio, e as informações sobre o endereçamento da sua rede local, que já comentamos acima.

A seguir vem a inclusão da biblioteca softwareSerial, que nos permitirá enviar dados para o monitor serial mesmo já tendo usado os pinos RX e TX para fazer conexão entre o Arduino e o ESP8266. Da forma como a usamos, os pinos 9 e 8 do nosso Arduino Uno ou similar se transformam em um segundo par de pinos RX e TX independentes, que podem ser conectados a um segundo Arduino para fazer a ponte com o monitor serial, conforme detalhado em Usando outro Arduino como intermediário para debug no Monitor com a softwareSerial.

O envio de comandos e recepção da resposta do ESP8266 ficam concentrados na conveniente função cmdESP().

A função cmdESP() é interessante, mas seu funcionamento não é relevante para esta explicação. O que ela faz é receber um comando a ser enviado ao ESP8266, um texto descrevendo esse comando e, opcionalmente, um limite de espera. Aí ela envia para o ESP o comando, envia para o monitor serial o texto descritivo, e aguarda até o ESP dar a sua resposta4, exibindo-a também no monitor serial.

A seguir vem a função setup() do Arduino, onde toda a mágica do nosso programa de exemplo acontece, e que dividi em 3 blocos coloridos.

O trecho em vermelho é uma inicialização tradicional, que define a velocidade das 2 portas seriais (a real nos pinos 0 e 1 para conexão ao ESP8266, e a virtual nos pinos 8 e 9 para conexão ao monitor serial).

Em verde temos um trecho que monta (mas não envia ainda) os 2 comandos que incluem os dados dos parâmetros definidos no início do programa. O primeiro deles é o cmdConectar, que usa o comando AT+CWJAP e o nome e senha da sua rede local; o outro é o cmdMudarIP, que usa o AT+CIPSTA_DEF, já explicado acima.

O trecho em rosa concretiza nosso teste: ele envia os comandos para conectar à rede sem fio e para definir um IP estático.

Finalmente, em rosa, temos a sequência que ativa o ESP8266 na rede e define seu IP fixo. É uma sequência de chamadas à nossa cmdESP repassando os comandos necessários para entrar na rede, mostrar qual o endereço IP do ESP, mudá-lo com o comando que montamos acima, e mostrar novamente o endereço IP do ESP.

Após a execução desse programa, o ESP8266 estará permanentemente com o IP fixo definido. Para voltar a ter IP dinâmico, tire a // do início da linha de comentário que deixei ao final do programa, que usa o AT+CWDHCP_DEF (já mencionado acima) para reestabelecer o uso do IP dinâmico.

O que aparece no monitor serial

Na primeira execução do programa, meu módulo ESP-01 ainda estava com a configuração default, e assim obteve um IP dinâmico no momento da conexão da rede sem fio, que depois foi modificado pelo nosso programa, levando ao log abaixo:

*** ESP8266 Static IP / IP fixo - BR-Arduino.org
Modo de operacao misto, AP + STATION
AT+CWMODE=3
OK

Conectando a uma rede WiFi
AT+CWJAP="br-arduino","senha-da-rede-wifi"
WIFI DISCONNECT
WIFI CONNECTED
WIFI GOT IP
OK

Consultando os enderecos IP definidos inicialmente
AT+CIFSR
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"1a:fe:34:f2:0e:1f"
+CIFSR:STAIP,"192.168.0.121"
CIFS:STMAC"18fe34f20e1"
OK


Definindo nosso proprio IP fixo
AT+CIPSTA_DEF="192.168.0.235","192.168.0.254","255.255.255.0"
OK

Consultando novamente os enderecos IP, apos definicao acima.
AT+CIFSR
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"1a:fe:34:f2:0e:1f"
+CIFSR:STAIP,"192.168.0.235"
+CIFSR:STAMAC,"8:e:34:20e1f
OK

Note que na primeira consulta ao endereço IP, destaquei em vermelho a resposta, que indica um IP dinâmico fornecido pela rede sem fio. Na segunda consulta, a resposta (que destaquei em rosa) já é o IP fixo definido pelo nosso programa.

Se você executar novamente o programa, verá que a linha em rosa e a linha em vermelho exibirão o mesmo IP, porque a primeira execução do programa definiu um IP fixo e desativou a obtenção de IP dinâmico, como já vimos acima.

A montagem física

As conexões da minha montagem foram bem simples. As suas podem variar entre modelos de Arduinos5 e de módulos ESP8266, mas as minhas envolveram:

  1. Arduino principal: Um Arduino Uno.
  2. Arduino auxiliar para monitor serial: Outro Arduino Uno, para fazer o papel de USB-Serial, complementando a porta serial adicional emulada no Arduino principal.
  3. Placa ESP-01.
  4. Placa conversora de nível lógico.

A imagem acima mostra as conexões dos pinos6, cuja descrição textual vem a seguir.

O Arduino auxiliar estava rodando o programa Blink (pode ser qualquer programa que não interfira com a serial), conectado a uma porta USB do computador, e com um jumper ligando o seu pino digital 1 ao pino digital 8 do Arduino principal. O monitor serial no computador deve ser aberto apontando para a porta serial correspondente à porta USB do Arduino auxiliar (essa parte da montagem é melhor explicada no artigo “Usando outro Arduino como intermediário para debug no Monitor com a softwareSerial”).

O Arduino Uno usa 5V e o ESP8266 usa 3,3V, cabe ao projetista compatibilizá-los.

Como o Arduino usa nível lógico de 5V e o ESP8266 usa 3,3V, é necessário recorrer a alguma técnica para converter as tensões dos sinais entre o Arduino principal e o ESP-01. Eu usei uma baratíssima7 placa de conversão de nível lógico como a descrita no final deste artigo anterior, mas poderia ter recorrido aos tradicionais divisores de tensão feitos com 2 resistores. No caso específico deste artigo, a única conexão que exige a conversão é a que fica entre o pino 1 (TX) do Arduino principal e o pino RX do ESP8266.

Quanto à alimentação, o pino GND do Arduino principal estava conectado aos pinos GND do ESP8266 e da placa de conversão de nível lógico. O pino 3V3 do Arduino principal estava conectado aos pinos 3V3 do ESP-01 e da placa de conversão de nível lógico, e o pino 5V do Arduino principal estava ligado ao pino 5V da placa de conversão de nível lógico.

Quanto ao sinal, o pino TX do ESP-01 estava conectado diretamente ao pino digital 0 (RX) do Arduino principal, e o pino TX do Arduino principal estava conectado, por meio da placa de conversão de nível lógico, ao pino RX do ESP-01.

Acima você vê a montagem real (exceto quanto aos cabos USB, que retirei para a foto) usada durante a escrita deste artigo. O Arduino auxiliar é o da esquerda, e o ESP-01 está plugado na placa auxiliar descrita neste artigo, que incorpora a placa de conversão de nível lógico, que não está visível devido ao ângulo, pois o ESP-01 fica suspenso acima dela.

 
  1.  A existência de variação depende da configuração do roteador e do uso da rede.

  2.  Testado com o firmware AT oficial versão 0.25.0.0, de junho de 2015 – tudo o que está descrito neste artigo assume que o seu módulo ESP está com essa versão, ou com outra que seja compatível. Versões antigas certamente não contavam com alguns dos comandos aqui aplicados.

  3.  Até que você reconfigure explicitamente, claro.

  4.  Ou o prazo limite acabar, claro.

  5.  Ou até mesmo substituindo o Arduino auxiliar por um conversor USB-Serial adequado de sua preferência.

  6.  Fique atento à ordem dos pinos do seu conversor de nível lógico, pois ela não é padronizada e varia bastante.

  7.  Comprada na Proesi, mas pesquise e você encontrará preços e fretes na melhor combinação para o seu caso.

Comentar

Dos leds ao Arduino, ESP8266 e mais

Aprenda eletrônica com as experiências de um geek veterano dos bits e bytes que nunca tinha soldado um led na vida, e resolveu narrar para você o que descobre enquanto explora esse universo – a partir da eletrônica básica, até chegar aos circuitos modernos.

Por Augusto Campos, autor do BR-Linux e Efetividade.net.

Recomendados

Livro recomendado


Artigos já disponíveis

Comunidade Arduino

O BR-Arduino é integrante da comunidade internacional de entusiastas do Arduino, mas não tem relação com os criadores e distribuidores do produto, nem com os detentores das marcas registradas.

Livros recomendados