The Raspberry Pi Pico is the first microcontroller from the Raspberry Pi foundation and it came with a lot to offer for its size. The RP2040 dual-core Arm Cortex-M0+ processor with 264KB internal RAM gives this microcontroller the ability to handle multiple threads at an incredible clock speed of up to 133 MHz. The high amount of GPIO pins will surely come in handy for IoT applications where many sensors come together.

This board is programmable with MicroPython and is expecting Arduino IDE compatibility in the future. For now, guide will show how to connect the Raspberry Pi Pico with the ESP8266 WiFi module and publish data to Ubidots through AT commands.

In this article you will learn how to read the Raspberry Pi Pico's internal temperature sensor value and send it to Ubidots through HTTP and TCP.

Requirements

Table of contents

  1. Thonny IDE setup

  2. Hardware setup

  3. Send data through HTTP

  4. Send data through TCP

  5. Summary

1. Thonny IDE setup

A great IDE for working with Python and MicroPython is Thonny, as it is intuitive to use and it provides a handful of benefits that speed up your coding.

To install and setup Thonny IDE for Raspberry Pi, please follow these steps:

  1. First you will need to install the Thonny IDE.

  2. After installing, upon opening the IDE, the following window will pop up. You may choose the language you'd like the IDE to have, but make sure to leave the "Initial settings:" set to Standard.

  3. Once with the IDE open, to configure it to work with the Raspberry Pi, go to Run > Select interpreter...

    After that, select "MicroPython (Raspberry Pi Pico) from the dropdown menu.


  4. Finally, select the port where you have your Raspberry Pi Pico connected to.

2. Hardware setup

In order to make your Raspberry Pi Pico compatible to the MicroPython environment follow the steps shown in Raspberry's website for Getting Started with MicroPython.

After that, the connection between the Raspberry Pi Pico and the ESP8266 goes as follows:

Raspberry Pi Pico

ESP8266

3V3

3V3

3V3

EN

GND

GND

GP5

TX

GP4

RX



IMPORTANT NOTE: make sure you connect the ESP8266 to 3.3V, as connecting it to 5V might permantently damage the chip. Also, the pin distribution for the ESP8266 may be different to the one shown in the image, so verify your brand's documentation.
IMPORTANT NOTE: the ESP8266 must have the factory firmware, as it must accept AT commands.

3. Send data through HTTP


To send data to Ubidots using HTTP, please use the code below. Just copy it and paste it into your Thonny IDE window. Also, please define the following constants;

  1. Set your WiFi credentials

  2. Place your Ubidots' Token (Follow this article if you aren't sure where to find it)

  3. Set the label for variable and device that the data is to be sent to (no uppercase letters, whitespaces or periods)

  4. Set the user_agent (any ascii random string, 25 character recommended)

    from machine import UART
    import machine
    import _thread
    import time



    uart = UART(1,115200)

    print('-- UART Serial --')
    print('>', end='')


    #Define all constants
    SSID = "YOUR WIFI SSID"
    PASSWORD = "YOUR WIFI PASSWORD"
    TOKEN = "YOUR UBIDOTS TOKEN"
    DEVICE_LABEL="raspberry-pi-pico"
    VARIABLE_LABEL="temperature"
    USER_AGENT="randomstring"


    def uartSerialRxMonitor(command):
    recv=bytes()
    while uart.any()>0:
    recv+=uart.read(1)
    res=recv.decode('utf-8')
    erase_len=len(command)+5
    res = res[erase_len:]
    return res

    def wifi_is_connected():
    res=""
    send = "AT+CWJAP?"
    uart.write(send+'\r\n')
    time.sleep(4)
    res=wifi_is_connected_response(send)
    if res=="No AP":
    print("WiFi Status:"+res)
    return res

    def wifi_is_connected_response(command):
    recv=bytes()
    while uart.any()>0:
    recv+=uart.read(1)
    res=recv.decode('utf-8')
    erase_len=len(command)+3
    res = res[erase_len:]
    res = res[:5]
    return res

    def wifi_connect(SSID,PASSWORD):
    res=""
    send = "AT+CWJAP=\""+SSID+"\",\""+PASSWORD+"\""
    uart.write(send+'\r\n')
    time.sleep(7)
    res=uartSerialRxMonitor(send)
    print("Attempting to connect to WiFi..."+res)
    return res

    def sendhttp(value):

    send='AT+CIPSTART="TCP","industrial.api.ubidots.com",80'
    uart.write(send+'\r\n')
    time.sleep(2)

    #build payload and find its length
    payload= '{"'+VARIABLE_LABEL+'":'+str(value)+'}'
    payload_length= len(payload)

    #find request length
    req_length = 147
    req_length+= len(DEVICE_LABEL+TOKEN+str(payload_length)+payload+USER_AGENT)

    send="AT+CIPSEND="+str(req_length)
    uart.write(send+'\r\n')
    time.sleep(0.6)

    send="POST /api/v1.6/devices/"+DEVICE_LABEL+" HTTP/1.1"
    uart.write(send+'\r\n')
    time.sleep(0.6)

    send="Host:industrial.api.ubidots.com"
    uart.write(send+'\r\n')
    time.sleep(0.6)

    send="User-Agent:"+USER_AGENT
    uart.write(send+'\r\n')
    time.sleep(0.6)

    send="X-Auth-Token:"+TOKEN
    uart.write(send+'\r\n')
    time.sleep(0.6)

    send="Content-Type:application/json"
    uart.write(send+'\r\n')
    time.sleep(0.6)

    send="Content-Length:"+str(payload_length)
    uart.write(send+'\r\n')
    time.sleep(0.6)

    send=""
    uart.write(send+'\r\n')
    time.sleep(0.6)

    uart.write(payload+'\r\n')

    send=""
    uart.write(send+'\r\n')
    time.sleep(0.6)

    print("Data sent: "+payload)


    #Here the code begins to run (Similar to arduino's setup())

    wifi_connect(SSID,PASSWORD)
    time.sleep(10)

    send='AT+CWMODE=1'
    uart.write(send+'\r\n')
    time.sleep(1)

    send='AT+CIPMUX=0'
    uart.write(send+'\r\n')
    time.sleep(1)

    #temperature reading
    sensor_temp = machine.ADC(4)
    conversion_factor = 3.3 / (65535)

    print("Setup done")



    #Here the code runs indefinitely (Similar to arduino's loop())


    while True:
    #temperature reading
    reading_temp = sensor_temp.read_u16() * conversion_factor
    temperature = 27 - (reading_temp - 0.706)/0.001721

    state = wifi_is_connected()

    if state=="No AP":
    time.sleep(10)
    wifi_connect(SSID,PASSWORD)


    sendhttp(temperature)
    time.sleep(3)

    IMPORTANT NOTE: the time.sleep() after each AT Command is necessary, as it gives the ESP8266 the time required to complete the Command and output the command response through the UART. In order to change the data sending period, change the time.sleep() at the end of the indefinite loop.

To save the previous code into the Raspberry Pi Pico, go to File > Save as... and select the option to save the code to the Raspberry and not to the computer.

IMPORTANT NOTE: it is crucial that you name this code "main.py", as this is the file that the Raspberry Pi Pico will try to run once powered on.

Finally, once you run the code, you can check our Ubidots account to verify that the data is being sent accordingly. In this case, we’ve labelled this device “raspberry-pi-pico” with one variable labelled “temperature”.

The payload sent to Ubidots is shown in Thonny. This is useful for debugging purposes.

4. Send data through TCP

To send data to Ubidots using TCP, please use the code below. Just copy it and paste it into your Thonny IDE window. Also, please define the following constants;

  1. Set your WiFi credentials

  2. Place your Ubidots' Token (Follow this article if you aren't sure where to find it)

  3. Set the label for variable and device that the data is to be sent to (no uppercase letters, whitespaces or periods)

  4. Set the user_agent (any ascii random string, 25 character recommended)

    from machine import UART
    import machine
    import _thread
    import time


    uart = UART(1,115200)

    print('-- UART Serial --')
    print('>', end='')


    #Define all constants
    SSID = "YOUR WIFI SSID"
    PASSWORD = "YOUR WIFI PASSWORD"
    TOKEN = "YOUR UBIDOTS TOKEN"
    DEVICE_LABEL="raspberry-pi-pico"
    VARIABLE_LABEL="temperature"
    USER_AGENT="randomstring"


    def uartSerialRxMonitor(command):
    recv=bytes()
    while uart.any()>0:
    recv+=uart.read(1)
    res=recv.decode('utf-8')
    erase_len=len(command)+5
    res = res[erase_len:]
    return res

    def wifi_is_connected():
    res=""
    send = "AT+CWJAP?"
    uart.write(send+'\r\n')
    time.sleep(4)
    res=wifi_is_connected_response(send)
    if res=="No AP":
    print("WiFi Status:"+res)
    return res

    def wifi_is_connected_response(command):
    recv=bytes()
    while uart.any()>0:
    recv+=uart.read(1)
    res=recv.decode('utf-8')
    erase_len=len(command)+3
    res = res[erase_len:]
    res = res[:5]
    return res

    def wifi_connect(ssid,password):
    res=""
    send = "AT+CWJAP=\""+SSID+"\",\""+PASSWORD+"\""
    uart.write(send+'\r\n')
    time.sleep(7)
    res=uartSerialRxMonitor(send)
    print("Attempting to connect to WiFi..."+res)
    return res

    def sendtcp(value):

    send='AT+CIPSTART="TCP","industrial.api.ubidots.com",9012'
    uart.write(send+'\r\n')
    time.sleep(2)

    #build payload and find its length
    payload= DEVICE_LABEL+"=>"+VARIABLE_LABEL+":"+str(value)
    payload_length= len(payload)

    #find request length
    req_length = 11
    req_length+= len(USER_AGENT+TOKEN+str(payload_length)+payload)

    send="AT+CIPSEND="+str(req_length)
    uart.write(send+'\r\n')
    time.sleep(0.6)

    send=USER_AGENT+"|POST|"+TOKEN+"|"+payload+"|end"
    # print("request sent: "+USER_AGENT+"|POST|"+TOKEN+"|"+payload+"|end") #uncomment for debugging purposes
    uart.write(send+'\r\n')
    time.sleep(0.6)


    print("Data sent: "+payload)


    wifi_connect(SSID,PASSWORD)
    time.sleep(10)

    send='AT+CWMODE=1'
    uart.write(send+'\r\n')
    time.sleep(1)

    send='AT+CIPMUX=0'
    uart.write(send+'\r\n')
    time.sleep(1)

    #temperature reading
    sensor_temp = machine.ADC(4)
    conversion_factor = 3.3 / (65535)

    print("Setup done")


    while True:
    #temperature reading
    reading_temp = sensor_temp.read_u16() * conversion_factor
    temperature = 27 - (reading_temp - 0.706)/0.001721

    state = wifi_is_connected()

    while state=="No AP":
    time.sleep(10)
    wifi_connect(SSID,PASSWORD)


    sendtcp(temperature)
    time.sleep(3)

    IMPORTANT NOTE: it is crucial that you name this code "main.py", as this is the file that the Raspberry Pi Pico will try to run once powered on.

    IMPORTANT NOTE: the time.sleep() after each AT Command is necessary, as it gives the ESP8266 the time required to complete the Command and output the command response through the UART. In order to change the data sending period, change the time.sleep() at the end of the indefinite loop.

Again, now we can check our Ubidots account to verify that the data is being sent accordingly.

5. Summary

We have now sent data successfully to Ubidots via HTTP and TCP, it's time to apply this new microcontroller in IoT applications where high power and small form factor are needed.

Other users also found helpful...

Did this answer your question?