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 also Arduino IDE compatible. For now, this guide will show how to connect the Raspberry Pi Pico with the ESP8266 WiFi module in order to Post and Get data.

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

IMPORTANT NOTE: It's very important know that we're going to manage two codes, one for the logger(Raspberry Pi Pico), and a second for the telemetry unit(ESP8266).

Requirements

Table of contents

  1. Thonny IDE setup

  2. Arduino IDE setup

  3. ESP8266 firmware

  4. Hardware setup

  5. Send data through TCP

  6. Get a variable's last value through TCP

  7. 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. Arduino IDE Setup

For the ESP8266 we will be using the Ubidots ESP8266 Serial library, which allows to send TCP payloads from any datalogger (in this case the Raspberry Pi Pico) to the ESP8266 module through serial.

1. To be able to work with the ESP8266 platform in the Arduino IDE, you will need to install the ESP8266 board using the preconfigured Arduino Board Manager. If you are not familiar with adding a board with the Arduino IDE, refer to this article for additional guidance.

2. With the ESP8266 platform installed, select the ESP8266 device you are working with. In the case, we are working with a “Generic ESP8266 Module”. To select your board from the Arduino IDE, select Tools > Board Generic ESP8266 Module”.

3. Download and install the Ubidots ESP8266 Serial. For a detailed explanation of how to install libraries using the Arduino IDE, refer to this guide.


3. ESP8266 Firmware

To flash the code onto the ESP8266 you will need any UART to USB device. You can use an Arduino Mega (for more information refer to this article), an UartSBee, or an ESP8266 to USB Adapter like the following one:

Once the module is ready to flash, set your WiFi credentials, your Ubidots Token, and then upload the following code to the ESP8266:

/****************************************
* Include Libraries
****************************************/
#include "UbidotsESP8266.h"

/****************************************
* Define Constants
****************************************/
namespace {
const char * WIFISSID = "..."; // Assign your WiFi SSID
const char * PASSWORD = "..."; // Assign your WiFi password
const char * TOKEN = "..."; // Assign your Ubidots TOKEN
}

Ubidots client(TOKEN);

/****************************************
* Main Functions
****************************************/
void setup() {
Serial.begin(115200);
client.wifiConnection(WIFISSID, PASSWORD);
}

void loop() {
client.readData(); // Reads the command from the logger
delay(1000);
}

4. 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

GND

GND

GP01

RX

GP02

TX

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.

5. 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 the user_agent (any ascii random string, 25 character recommended)

  2. Assign your Ubidots TOKEN

  3. Add the variables and their values that will be sent within the variables_to_send dictionary

    from machine import UART, Pin
    import machine
    import time

    uart0 = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1)) # UART tx/rx

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


    USER_AGENT = "UbidotsESP8266" # Assign the user agent
    VERSION = "1.0" # Assign the version

    TOKEN = "..." # Assign your Ubidots TOKEN
    DEVICE_LABEL = "..." # Assign the device label


    #payload example
    #init#USER_AGENT/VERSION|POST|TOKEN|DEVICE_LABEL:DEVICE_NAME=>VARIABLE:VALUE|end#final

    ####### function definition #######

    def temperatureC():
    reading_temp = sensor_temp.read_u16() * conversion_factor
    temperature = 27 - (reading_temp - 0.706)/0.001721
    return temperature

    def post_payload_builder(**variables):
    body = ""
    for key,value in variables.items():
    body += f"{key}:{value},"
    body = body[:-1]

    payload = f"init#{USER_AGENT}/{VERSION}|POST|{TOKEN}|{DEVICE_LABEL}=>{body}|end#final"
    return payload

    def send_message(msg):
    uart0.write(msg)
    return

    def read_post_response():
    rxData = bytes()
    while uart0.any() > 0:
    rxData += uart0.read(1)

    if len(rxData):
    rxData = rxData.decode('utf-8')
    print(f"Server response: {rxData}")
    return rxData
    else:
    return None

    ####### setup to read temperature from internal sensor #######

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


    ####### main code #######

    while True:
    #temperature reading
    tempC = temperatureC()
    tempF = tempC * 9/5 + 32

    #variables_to_send format = {<VAR_LABELZ>: VALUE,....}
    #variables_to_send example = {"humidity": 34, "temperature": 54, "pressure": 23,....}
    variables_to_send = {"tempC":tempC, "tempF":tempF}


    payload = post_payload_builder(**variables_to_send)
    print(payload)
    print(f"Temperature read was: {tempC} °C ({tempF} °F)")
    send_message(payload)

    response = read_post_response()

    time.sleep(5)

    IMPORTANT NOTE: Remember that this code must syncronize with the code in the ESP8266, that is, it cannot have loop frequency higher than the ESP8266 loop frequency.

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 Pi Pico 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 “rpi-pico” with two variables labelled “tempC” and "tempF".

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

6. Get a variable's last value through TCP

To retrieve the last value of a variable 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 the user_agent (any ascii random string, 25 character recommended)

  2. Assign your Ubidots TOKEN

  3. Add the variable label to retrieve the data from

    from machine import UART, Pin
    import machine
    import time

    uart0 = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1)) # UART tx/rx

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


    USER_AGENT = "UbidotsESP8266" # Assign the user agent
    VERSION = "1.0" # Assign the version

    TOKEN = "..." # Assign your Ubidots TOKEN
    DEVICE_LABEL = "..." # Assign the device label


    #payload example
    #init#USER_AGENT/VERSION|LV|TOKEN|DEVICE_LABEL:variable_label|end#final

    ####### function definition #######

    def get_lv_payload_builder(variable_label):
    payload = f"init#{USER_AGENT}/{VERSION}|LV|{TOKEN}|{DEVICE_LABEL}:{variable_label}|end#final"
    return payload

    def send_message(msg):
    uart0.write(msg)
    return

    def read_get_response():
    rxData = bytes()
    while uart0.any() > 0:
    rxData += uart0.read(1)

    if len(rxData):
    rxData = rxData.decode('utf-8')
    if rxData[:2] == "OK": # if data begins with "OK", then it only returns the characters after "OK|"
    return rxData[3:]
    print(f"Server response: {rxData}") # if the data doesn't begin with "OK" then it returns the complete response
    return rxData
    else:
    return None

    ####### main code #######

    while True:

    get_command = get_lv_payload_builder("tempc")
    send_message(get_command)
    time.sleep (2) #allow for API to respond and for the ESP8266 to loop

    lv = read_get_response()
    print(lv)

    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.

From Thonny's Shell, we can check the value being retrieved from the variable "tempc"

7. Summary

We have now sent and retrieved data successfully to Ubidots via 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?