Maker Pi Pico with ESP01S Module

It has been a while since my last post, most of which has been spent dealing with other things, as well as waiting for electronics modules to arrive from overseas. A lot of my time has also been spent on getting to grips with the Raspberry Pi Pico, and in particular, the Maker Pi Pico, from Cytron Technologies. This has been an experience with quite a lot of mixed feelings… As Usual, Cytron has done an excellent job with the development board, which, while apparently still in Beta, seems to be rock solid. Most of my frustration came from the “patchy” C/C++ support for the Pi Pico (Yes, I know there are great support, BUT it is not exactly user friendly 🙂 ). That left me with MicroPython, which although I am fluent, are not my goto language…

Lets get back on track though… The Maker Pi Pico has built in support for an ESP01/ESP01S Module. Lets look at the schematic….

Maker Pi Pico Schematic

As we can see, Cytron has provided us with access to Tx (GP17) and Rx(GP16) directly on the Pi Pico. Power (+3.3v) and Ground are connected as well… On this version of the board, no access to IO0,IO2 and the Reset Pin for the ESP01/ESP01S was provided… Maybe this will change in future…?

I have used the standard AT command firmware that comes pre-loaded onto the ESP01/S module. This allows you to send AT commands to the ESP01 Module to control it. It is also possible to setup a transparent WiFi “channel” to communicate between Pico and a remote application , making it possible to control Pico remotely. I have however not prepared and example of that for release yet….

MicroPython Code to communicate with ESP01 from Maker Pi Pico

import uos
from machine import UART, Pin
import utime


print("Machine: \t" + uos.uname()[4])
print("MicroPython: \t" + uos.uname()[3])

#indicate program started visually
led_onboard = machine.Pin(25, machine.Pin.OUT)
led_onboard.value(0)     # onboard LED OFF/ON for 0.5/1.0 sec

uart0 = UART(0, rx=Pin(17), tx=Pin(16), baudrate=115200)
# NOTE that we explicitly set the Tx and Rx pins for use with the UART
# If we do not do this, they WILL default to Pin 0 and Pin 1
# Also note that Rx and Tx are swapped, meaning Pico Tx goes to ESP01 Rx 
# and vice versa.

def sendCMD_waitResp(cmd, uart=uart0, timeout=2000):
    print("CMD: " + cmd)
    waitResp(uart, timeout)
def waitResp(uart=uart0, timeout=2000):
    prvMills = utime.ticks_ms()
    resp = b""
    while (utime.ticks_ms()-prvMills)<timeout:
        if uart.any():
            resp = b"".join([resp,])
    except UnicodeError:
sendCMD_waitResp('AT\r\n')          #Test AT startup
sendCMD_waitResp('AT+GMR\r\n')      #Check version information
#sendCMD_waitResp('AT+RESTORE\r\n')  #Restore Factory Default Settings
sendCMD_waitResp('AT+CWMODE?\r\n')  #Query the Wi-Fi mode
sendCMD_waitResp('AT+CWMODE=1\r\n') #Set the Wi-Fi mode = Station mode
sendCMD_waitResp('AT+CWMODE?\r\n')  #Query the Wi-Fi mode again
#sendCMD_waitResp('AT+CWLAP\r\n', timeout=10000) #List available APs
sendCMD_waitResp('AT+CWJAP="jean_iot","master123abc"\r\n', timeout=5000) #Connect to AP
sendCMD_waitResp('AT+CIFSR\r\n')    #Obtain the Local IP Address

You can now extend and adapt this code to suit your purposes…

The ESP01/ESP01S AT Command Datasheet is available for download here

Thank you

Leave a Reply

Your email address will not be published. Required fields are marked *