Módulo de interface WiFi ESP8266 com Raspberry Pi Pico
Neste tutorial, você aprenderá como fazer a interface do módulo WiFi ESP8266-01 com o Rasperry Pi Pico para obter conectividade com a Internet. Vamos criar um TCP Web Server com Raspberry Pi Pico usando comandos AT do módulo ESP-01 e usar a porta serial da placa Pico para configurar o módulo WiFi ESP-01 para conectar com WiFi e criar um servidor web. Usaremos o Thonny IDE para programar o Raspberry Pi Pico com o ESP-01 no MircoPython.
Raspberry Pi Pico é uma placa de baixo custo e alto desempenho baseada no chip microcontrolador Raspberry Pi RP2040. Mas, ele não suporta recursos WiFi, portanto, temos que usar um módulo WiFi externo para habilitar a conectividade WiFi para Raspberry Pi Pico.
Conteudo
Módulo WiFi ESP8266
Em agosto de 2014, a Espressif Systems lançou seu primeiro módulo bruto, fabricado por uma terceira parte do AI-Thinker e módulo conhecido como módulo ESP-01
O ESP8266 oferece uma solução WiFi altamente integrada que atende às necessidades dos setores da Internet das Coisas, como baixo custo, uso eficiente de energia, desempenho confiável e design compacto.
O módulo WIFI ESP8266 é basicamente uma solução WiFi completa, que possui uma pilha de protocolos TCP/IP integrada que pode ser facilmente conectada ao microcontrolador para obter acesso a qualquer rede WiFi.
Usaremos comandos de envio AT para o módulo ESP8266 sobre UART do Raspberry Pi Pico para configurar o servidor Web TCP.
Existem muitos módulos WiFi ESP8266 disponíveis no mercado, desde ESP-01 a ESP-12. Mas neste tutorial, estamos usando o ESP-01. Os comandos AT são os mesmos para todos esses módulos ESP.
Pinagem do módulo ESP-01
O módulo WiFi ESP8266-01 consiste em duas fileiras de oito pinos. O diagrama de configuração dos pinos é mostrado na figura abaixo:
Tem um total de 8 pinos dos quais 6 pinos estão ativos.
Etiqueta | Descrição |
---|---|
3.3V | Fornecimento de pino de 3,3 volts |
GND | Pino terra |
RST | Pino Reset |
CH_PD/EN | Potência do chip e pino de ativação |
GPIO 0 to 3 | Interface UART e pinos de entrada/saída |
- Pino_1, que é um pino GND, é conectado diretamente ao terra para alimentar este módulo.
- Pinos_2 e 3, que são o GPIO 2 e o GPIO 0, esses pinos decidem em qual modo o módulo seria uma partida, ou seja, são os pinos de modo selecionado.
- Pinos_4 e 5, que são RX e TX, esses pinos são usados para fins de comunicação e programação do módulo.
- Pino_6 que é CH_PD, é chamado de pino de desligamento do chip.
- Pino_7 que é o pino RST e este pino é usado para redefinir o módulo.
- Pino_8 é um pino VCC que é usado para alimentar o módulo. A tensão de operação do ESP-01 é de 3,3 volts.
Módulo de interface Wi-Fi ESP-01 com Raspberry Pi Pico
Vamos precisar dos seguintes componentes:
- Raspberry PI Pico
- Módulo ESP8266 ESP-01
- Fios de conexão
- Protoboard (não necessário)
Como vimos acima o módulo ESP-01 é composto por 8 pinos. No entanto, usaremos 5 pinos para conectá-lo à placa Raspberry Pi Pico. Estes incluem os pinos VCC, EN, GND, RX e TX. Os pinos RX e TX do módulo serão conectados aos pinos UART da placa Pi Pico. Vamos primeiro dar uma olhada nos pinos UART do Raspberry Pi Pi.
Pinos UART Raspberry Pi Pico
Raspberry Pi Pico contém dois periféricos UART idênticos com FIFOs 32×8 Tx e 32×12 Rx separados.
A tabela a seguir lista os pinos GPIO para ambos os periféricos UART que são expostos nas pinagens da placa de desenvolvimento Raspberry Pi Pico.
Pinos UART | Pinos GPIO |
---|---|
UART0-TX | GP0/GP12/GP16 |
UART0-RX | GP1/GP13/GP17 |
UART1-TX | GP4/GP8 |
UART1-RX | GP5/GP9 |
Diagrama de ligação
Para este tutorial, usaremos os pinos UART0 TX e RX do Raspberry Pi Pico. Siga o diagrama de conexão abaixo para conectar os dois dispositivos.
Raspberry Pi Pico | ESP-01 |
---|---|
3.3V | VCC |
3.3V | EN |
GND | GND |
GP1 (UART0 RX) | TX |
GP0 (UART0 TX) | RX |
Raspberry Pi Pico Web Server MicroPython Script
O seguinte script MicriPython do Raspberry Pi Pico envia comandos AT para o módulo ESP8266 para configurar o ESP8266 como um servidor Web TCP. Veremos detalhes de todos os comandos AT nas próximas seções.
import uos import machine import utime recv_buf="" # receive buffer global variable print() print("Machine: \t" + uos.uname()[4]) print("MicroPython: \t" + uos.uname()[3]) uart0 = machine.UART(0, baudrate=115200) print(uart0) def Rx_ESP_Data(): recv=bytes() while uart0.any()>0: recv+=uart0.read(1) res=recv.decode('utf-8') return res def Connect_WiFi(cmd, uart=uart0, timeout=3000): print("CMD: " + cmd) uart.write(cmd) utime.sleep(7.0) Wait_ESP_Rsp(uart, timeout) print() def Send_AT_Cmd(cmd, uart=uart0, timeout=3000): print("CMD: " + cmd) uart.write(cmd) Wait_ESP_Rsp(uart, timeout) print() def Wait_ESP_Rsp(uart=uart0, timeout=3000): prvMills = utime.ticks_ms() resp = b"" while (utime.ticks_ms()-prvMills)<timeout: if uart.any(): resp = b"".join([resp, uart.read(1)]) print("resp:") try: print(resp.decode()) except UnicodeError: print(resp) Send_AT_Cmd('AT\r\n') #Test AT startup Send_AT_Cmd('AT+GMR\r\n') #Check version information Send_AT_Cmd('AT+CIPSERVER=0\r\n') #Check version information Send_AT_Cmd('AT+RST\r\n') #Check version information Send_AT_Cmd('AT+RESTORE\r\n') #Restore Factory Default Settings Send_AT_Cmd('AT+CWMODE?\r\n') #Query the WiFi mode Send_AT_Cmd('AT+CWMODE=1\r\n') #Set the WiFi mode = Station mode Send_AT_Cmd('AT+CWMODE?\r\n') #Query the WiFi mode again #Send_AT_Cmd('AT+CWLAP\r\n', timeout=10000) #List available APs Connect_WiFi('AT+CWJAP="HUAWEI-u67E","4uF77R2n"\r\n', timeout=5000) #Connect to AP Send_AT_Cmd('AT+CIFSR\r\n') #Obtain the Local IP Address utime.sleep(3.0) Send_AT_Cmd('AT+CIPMUX=1\r\n') #Obtain the Local IP Address utime.sleep(1.0) Send_AT_Cmd('AT+CIPSERVER=1,80\r\n') #Obtain the Local IP Address utime.sleep(1.0) print ('Starting connection to ESP8266...') while True: res ="" res=Rx_ESP_Data() utime.sleep(2.0) if '+IPD' in res: # if the buffer contains IPD(a connection), then respond with HTML handshake id_index = res.find('+IPD') print("resp:") print(res) connection_id = res[id_index+5] print("connectionId:" + connection_id) print ('! Incoming connection - sending webpage') uart0.write('AT+CIPSEND='+connection_id+',200'+'\r\n') #Send a HTTP response then a webpage as bytes the 108 is the amount of bytes you are sending, change this if you change the data sent below utime.sleep(1.0) uart0.write('HTTP/1.1 200 OK'+'\r\n') uart0.write('Content-Type: text/html'+'\r\n') uart0.write('Connection: close'+'\r\n') uart0.write(''+'\r\n') uart0.write('<!DOCTYPE HTML>'+'\r\n') uart0.write('<html>'+'\r\n') uart0.write('<body><center><h1>Raspberry Pi Pico Web Server</h1></center>'+'\r\n') uart0.write('</body></html>'+'\r\n') utime.sleep(4.0) Send_AT_Cmd('AT+CIPCLOSE='+ connection_id+'\r\n') # once file sent, close connection utime.sleep(2.0) recv_buf="" #reset buffer print ('Waiting For connection...')
Como funciona o Código?
Começaremos importando o módulo máquina e o módulo uos. Em seguida, também importaremos o módulo utime para incorporar atrasos.
import uos import machine import utime
Em seguida, imprimiremos as informações sobre nosso sistema operacional atual no terminal Thonny shell. Vamos uos.uname() e imprimir a versão e lançamento do sistema operacional.
print() print("Machine: \t" + uos.uname()[4]) print("MicroPython: \t" + uos.uname()[3])
Em seguida, criaremos um objeto uart usando UART() e especificaremos o canal UART como o primeiro parâmetro e a taxa de transmissão como o segundo parâmetro. Estamos usando UART0 neste caso com baud rate 115200 para a comunicação uart. O ESP8266 tem uma taxa de transmissão padrão de 115200, portanto, usaremos a mesma taxa de transmissão aqui para a comunicação UART do Raspberry Pi Pico para criar a sincronização. Além disso, também imprimiremos os detalhes do UART no terminal do shell.
uart0 = machine.UART(0, baudrate=115200) print(uart0)
Esta função Connect_WiFi() é usada para conectar o ESP8266 com WiFi.
def Connect_WiFi(cmd, uart=uart0, timeout=3000): print("CMD: " + cmd) uart.write(cmd) utime.sleep(7.0) Wait_ESP_Rsp(uart, timeout) print()
A seguir, definiremos três funções. O primeiro é Rx_ESP_Data(). Isso lê os dados seriais que estão sendo recebidos. Esses dados são decodificados do formato UTF-8 e retornados.
def Rx_ESP_Data(): recv=bytes() while uart0.any()>0: recv+=uart0.read(1) res=recv.decode('utf-8') return res
A segunda função é Send_AT_Cmd(cmd, uart=uart0, timeout=3000). Leva em três parâmetros, o comando AT, o canal UART e o tempo de resposta. Esta função será utilizada para enviar um comando AT para o ESP8266 via uart0. O tempo de resposta é definido para 3 segundos.
def Send_AT_Cmd(cmd, uart=uart0, timeout=3000): print("CMD: " + cmd) uart.write(cmd) Wait_ESP_Rsp(uart, timeout) print()
A função Wait_ESP_Rsp(uart=uart0, timeout=3000) aguarda 3 segundos para obter a resposta do ESP8266. Após receber os dados do ESP8266 ele concatena os bytes recebidos e os imprime no terminal shell.
def Wait_ESP_Rsp(uart=uart0, timeout=3000): prvMills = utime.ticks_ms() resp = b"" while (utime.ticks_ms()-prvMills)<timeout: if uart.any(): resp = b"".join([resp, uart.read(1)]) print("resp:") try: print(resp.decode()) except UnicodeError: print(resp)
Comandos AT
Agora vamos ver a série de comandos AT que enviaremos através do UART0 para o ESP8266.
Send_AT_Cmd('AT\r\n') #Test AT startup Send_AT_Cmd('AT+GMR\r\n') #Check version information Send_AT_Cmd('AT+CIPSERVER=0\r\n') Send_AT_Cmd('AT+RST\r\n') #Check version information Send_AT_Cmd('AT+RESTORE\r\n') #Restore Factory Default Settings Send_AT_Cmd('AT+CWMODE?\r\n') #Query the WiFi mode Send_AT_Cmd('AT+CWMODE=1\r\n') #Set the WiFi mode = Station mode Send_AT_Cmd('AT+CWMODE?\r\n') #Query the WiFi mode again Send_AT_Cmd('AT+CWJAP="HUAWEI-u67E","4uF77R2n"\r\n', timeout=5000) #Connect to AP utime.sleep(3.0) Send_AT_Cmd('AT+CIFSR\r\n') #Obtain the Local IP Address utime.sleep(3.0) Send_AT_Cmd('AT+CIPMUX=1\r\n') utime.sleep(1.0) Send_AT_Cmd('AT+CIPSERVER=1,80\r\n') #Obtain the Local IP Address utime.sleep(1.0)
AT: Este tipo de comando é usado para testar a função de inicialização do módulo WiFi. A resposta seria ok, contra este comando se tudo estiver ok.
Send_AT_Cmd('AT\r\n') #Test AT startup
AT+GMR : Este tipo de comando AT é usado para verificar a versão do comando AT e usamos a versão SDK do comando AT neste tipo de módulo WIFI.
Send_AT_Cmd('AT+GMR\r\n') #Check version information
AT+CIPSERVER=0: Isso configura o ESP8266 como servidor e define o modo como 0, o que significa excluir servidor (precisa seguir por reinicialização)
Send_AT_Cmd('AT+CIPSERVER=0\r\n')
AT+RST: Este tipo de comando é usado para redefinir o módulo WiFi quando estiver em condições de funcionamento. A resposta seria ok, quando resetar o módulo.
Send_AT_Cmd('AT+RST\r\n')
AT+RESTORE: Este tipo de comando é usado para restaurar as configurações de fábrica significa, quando este comando é inserido, todos os parâmetros são redefinidos automaticamente para os padrões.
Send_AT_Cmd('AT+RESTORE\r\n') #Restore Factory Default Settings
AT+CWMODE? : Este tipo de comando é usado para consultar o modo WiFi do ESP8266.
Send_AT_Cmd('AT+CWMODE?\r\n') #Query the WiFi mode
AT+CWMODE=1 : Isso define o modo WiFi do ESP8266 neste caso no modo estação.
Send_AT_Cmd('AT+CWMODE=1\r\n') #Set the WiFi mode = Station mode
AT+CWJAP=”SSID”,”PASSWORD”\r\n’, timeout=TIME_ms : Isso conecta o ESP8266 com um AP cujo SSID e senha são fornecidos, O tempo limite aqui é o tempo de reconexão.
Connect_WiFi('AT+CWJAP="A31-x221","1uX73A1n"\r\n', timeout=5000) #Connect to AP
AT+CIFSR: Este comando obtém o endereço IP local.
Send_AT_Cmd('AT+CIFSR\r\n')
AT+CIPMUX=1: Este comando é usado para habilitar múltiplas conexões (máximo 4)
Send_AT_Cmd('AT+CIPMUX=1\r\n')
AT+CIPSERVER=1: Este comando configura o ESP8266 como servidor.
Send_AT_Cmd('AT+CIPSERVER=1,80\r\n')
loop while
Dentro do loop while, vamos primeiro chamar Rx_ESP_Data() que retorna os dados que o ESP8266 recebe. Isso é salvo na variável ‘res.’ Agora, após um atraso de 2 segundos, verificaremos se o buffer contém uma conexão IPD ou não. Se isso acontecer, responda com um handshake HTML.
Imprima a resposta no terminal shell.
res ="" res=Rx_ESP_Data() print("resp:") print(res)
Obtenha o ID de conexão e imprima-o.
id_index = res.find('+IPD') connection_id = res[id_index+5] print("connectionId:" + connection_id)
Então, usando o objeto uart no método write(), enviaremos os bytes para o UART. Primeiro, estamos escrevendo o comando AT: AT+CIPSEND=’ID’, ‘LENGTH’ Isso definirá o comprimento dos dados que serão enviados. Em seguida, após um atraso de 1 segundo, escreveremos o corpo HTML que construirá a página da web na porta serial. Depois disso, fecharemos as múltiplas conexões enquanto estamos enviando o comando AT: AT+CIPCLOSE=’ID’. Em seguida, vamos redefinir o buffer e aguardar a conexão.
print ('! Incoming connection - sending webpage') uart0.write('AT+CIPSEND='+connection_id+',200'+'\r\n') #Send a HTTP response then a webpage as bytes the 108 is the amount of bytes you are sending, change this if you change the data sent below utime.sleep(1.0) uart0.write('HTTP/1.1 200 OK'+'\r\n') uart0.write('Content-Type: text/html'+'\r\n') uart0.write('Connection: close'+'\r\n') uart0.write(''+'\r\n') uart0.write('<!DOCTYPE HTML>'+'\r\n') uart0.write('<html>'+'\r\n') uart0.write('<body><center><h1>Raspberry Pi Pico Web Server</h1></center>'+'\r\n') uart0.write('</body></html>'+'\r\n') utime.sleep(4.0) Send_AT_Cmd('AT+CIPCLOSE='+ connection_id+'\r\n') # once file sent, close connection utime.sleep(2.0) recv_buf="" #reset buffer print ('Waiting For connection...')
Demonstração
Para testar o script MicroPython, faça o upload do arquivo main.py para sua placa e obtenha um endereço IP para acessar o servidor web:
No terminal shell do seu IDE, você poderá visualizar as seguintes mensagens:
Agora vá para o navegador web do seu sistema e pesquise com o endereço IP que foi exibido no terminal shell. A página da web será aberta.