Setup RPi Pico W and ESP32

Setup RPi Pico W and ESP32

September 2, 2024

Last year I bough a couple of companions for my Raspberry Pi 4 2GB:

  1. ESP32
  2. Pi Pico W

And Recently, this new release got my attention:

  1. Raspberry Pi Pico 2 - A brand new model, with both ARM and RISC-V cores

Let me show you how to get started with MicroControllers

What you need to know:

  • They dont need an OS
  • They run in loop whatever logic is loaded
  • The are low consumption devices (much more than even SBC’s)

The ESP32

Connecting ESP32 to Linux - https://github.com/tio/tio IDE - Thonny

Testing ESP32

I have to say thanks to Tomasz and his great content that helped me get started with this: https://www.youtube.com/watch?v=tc3Qnf79Ny8&t=0s

To ‘upload’ the code to the ESP32, please make sure that you have the proper DATA cable (I was expending too many hours because of this).

ESP32 - Blinking Lights in Cpp 🚀
#include <Arduino.h>

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(921600);
  Serial.println("Hello from the setup");
}

void loop() {
  delay(1000);
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.println("Hello from the loop");
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
}
ℹ️
Find more C sample Codes for ESP32 MicroController here
Connecting ESP32 to WIFI 🚀

#define WIFI_SSID "wifi_network_name"
#define WIFI_PASSWORD "wifi_password"

void setup() {
  Serial.begin(921600);
  pinMode(LED_BUILTIN, OUTPUT);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  Serial.println("starting");
}

bool isConnected = false;

void loop() {
  if (WiFi.status() == WL_CONNECTED && !isConnected) {
    Serial.println("Connected");
    digitalWrite(LED_BUILTIN, HIGH);
    isConnected = true;
  }

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println(".");
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    delay(1000);
    isConnected = false;
  }
}

The Raspberry Pi Pico W

Ideas for Readme’s - https://github.com/STJRush/handycode/tree/master/Raspi%20Pico

you can visualize the pinout

https://picockpit.com/raspberry-pi/everything-about-the-raspberry-pi-pico/

The chip: RP2040

lsusb #Bus 003 Device 010: ID XYZ MicroPython Board in FS (File System) mode

#ls /dev/tty*

sudo apt-get install picocom
sudo picocom -b 115200 /dev/ttyACM0

The schema: https://docs.micropython.org/en/latest/rp2/quickref.html

W version (wifi): https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html#raspberry-pi-pico-w-and-pico-wh

Pico W and MicroPython

Thanks to core-electronics

  1. Hold the BOOTSEL button on the Pico W
  2. Connect the Pico W to your computer via the USB cable
  3. Release the BOOTSEL button -> you will see a new device in the PC.

Download a MicroPython Release and move it to the Pico folder:

import mip
mip.install(PACKAGE_NAME, index="https://USERNAME.github.io/micropython-lib/mip/BRANCH_NAME")

https://micropython.org/download/rp2-pico-w/rp2-pico-w-latest.uf2

unplug usb and plug

To install libraries, i have observed that recently upip has been depricated in favour of mip

Raspberry Pi Pico W - IDE Setup

Testing the Raspberry Pi Pico W

PicoW - Blinking Led Example with MicroPython 🚀

The led is the pin 25 as per the schema

https://www.youtube.com/watch?v=_ouzuI_ZPLs

Run -> Configure Interpreter -> Interpreter -> MicroPython (Raspberry Pi Pico)

View -> files

The Pico will look for a main.py to execute in loop View -> plotter

CTRL+D for soft reboot and load the program

from machine import Pin
from time import sleep

#led = Pin(25, Pin.OUT)
led = Pin("LED", Pin.OUT) #For Pico W: Thanks to Easy Learning Video https://www.youtube.com/watch?v=PvH_yKwtoEA

n=0

while True:
    led.toggle()
    print("13 times {} is {}".format(n,13))
    n = n+1
    sleep(0.5)
PicoW - Reading internal temp sensor with MicroPython 🚀

https://www.youtube.com/watch?v=PYOaO1yW0rY

https://pypi.org/project/machine/

import machine
import utime
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535) #pico's datasheet
while True:
    reading = sensor_temp.read_u16() * conversion_factor
    temperature = 27 - (reading - 0.706)/0.001721
    print(temperature)
    utime.sleep(2)
Connecting the Pico to Wifi 🚀

https://www.youtube.com/watch?v=GiT3MzRzG48

# A simple example that:
# - Connects to a WiFi Network defined by "ssid" and "password"
# - Performs a GET request (loads a webpage)
# - Queries the current time from a server

import network   # handles connecting to WiFi
import urequests # handles making and servicing network requests

# Connect to network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)

# Fill in your network name (ssid) and password here:
ssid = 'HUAWEI P30'
password = 'mokradupa68' #Funny, isn't it?
wlan.connect(ssid, password)


# Example 1. Make a GET request for google.com and print HTML
# Print the html content from google.com
print("1. Querying the Web.com:")
r = urequests.get("https://fossengineer.com")
print(r.content)

r = urequests.get("http://date.jsontest.com/")
print(r.json())
print(r.json()['time'])
ℹ️
Name the file different than main.py to avoid the automatic execution.

Temperature Sensors with Pi Pico

https://www.youtube.com/watch?v=eNF3X3D0cH4

https://github.com/neeraj95575/Temperature-sensor-connect-to-raspberry-pi-pico


MQTT With MicroControllers

Setup Eclipse Mosquitto and NodeRed 🚀

Open a web browser and navigate to http://raspberry_pi_ip:1880 (replace raspberry_pi_ip with your Raspberry Pi’s IP address).

You should see the Node-RED user interface.

version: '3'
services:
  mosquitto:
    image: eclipse-mosquitto
    container_name: mosquitto
    ports:
      - "1883:1883"
      - "9001:9001"
    restart: always
    volumes:
      - /path/to/mosquitto/config:/mosquitto/config

  nodered:
    image: nodered/node-red
    container_name: nodered
    ports:
      - "1880:1880"
    restart: always
    volumes:
      - /path/to/nodered/data:/data
    environment:
      - TZ=your_time_zone

MQTT with the RPi and ESP32

Let’s setup MosquiTTO and make sure that we understand how Pub/Sub works with a dummy example:

https://www.youtube.com/watch?v=ebsXSCKsHeQ&t=302s https://helloworld.co.in/article/mqtt-raspberry-pi-esp32

sudo apt install -y mosquitto
sudo apt install -y mosquitto-clients

#sudo apt install python3-pip
sudo pip3 install paho-mqtt

sudo systemctl status mosquitto.service

Publish sample data (from the RPi to the Rpi): https://github.com/jiteshsaini/mqtt-demo/blob/main/rpi_mqtt_clients/client_pub.py

import time
import paho.mqtt.client as mqtt


def on_publish(client, userdata, mid):
    print("message published")


client = mqtt.Client("rpi_client2") #this name should be unique
client.on_publish = on_publish
client.connect('127.0.0.1',1883)
# start a new thread
client.loop_start()

k=0
while True:
    k=k+1
    if(k>20):
        k=1 
        
    try:
        msg =str(k)
        pubMsg = client.publish(
            topic='rpi/broadcast',
            payload=msg.encode('utf-8'),
            qos=0,
        )
        pubMsg.wait_for_publish()
        print(pubMsg.is_published())
    
    except Exception as e:
        print(e)
        
    time.sleep(2)

This will receive the sample data when both scripts are running - (in the RPi): https://github.com/jiteshsaini/mqtt-demo/blob/main/rpi_mqtt_clients/client_sub.py

import paho.mqtt.client as mqtt
import time

def on_connect(client, userdata, flags, rc):
   global flag_connected
   flag_connected = 1
   client_subscriptions(client)
   print("Connected to MQTT server")

def on_disconnect(client, userdata, rc):
   global flag_connected
   flag_connected = 0
   print("Disconnected from MQTT server")
   
# a callback functions 
def callback_esp32_sensor1(client, userdata, msg):
    print('ESP sensor1 data: ', msg.payload.decode('utf-8'))


def callback_esp32_sensor2(client, userdata, msg):
    print('ESP sensor2 data: ', str(msg.payload.decode('utf-8')))

def callback_rpi_broadcast(client, userdata, msg):
    print('RPi Broadcast message:  ', str(msg.payload.decode('utf-8')))

def client_subscriptions(client):
    client.subscribe("esp32/#")
    client.subscribe("rpi/broadcast")

client = mqtt.Client("rpi_client1") #this should be a unique name
flag_connected = 0

client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.message_callback_add('esp32/sensor1', callback_esp32_sensor1)
client.message_callback_add('esp32/sensor2', callback_esp32_sensor2)
client.message_callback_add('rpi/broadcast', callback_rpi_broadcast)
client.connect('127.0.0.1',1883)
# start a new thread
client.loop_start()
client_subscriptions(client)
print("......client setup complete............")


while True:
    time.sleep(4)
    if (flag_connected != 1):
        print("trying to connect MQTT server..")
ℹ️
Now we are ready for the cool stuff

Now, to publish data from the ESP32: https://github.com/jiteshsaini/mqtt-demo/blob/main/esp32_clients/esp_mqtt_client1/esp_mqtt_client1.ino

You will need https://registry.platformio.org/libraries/knolleary/PubSubClient/installation in the platformio.ini as

lib_deps = knolleary/PubSubClient@^2.8

PubSub from ESP32 to Raspberry Pi
/*********
  Author: Jitesh Saini
  This code is built upon the example code in pubsubclient library 
  Complete project details at https://helloworld.co.in
*********/

#include <WiFi.h>
#include <PubSubClient.h>

// Replace the SSID/Password details as per your wifi router
const char* ssid = "yourSSID";
const char* password = "yourPassword";

// Replace your MQTT Broker IP address here:
const char* mqtt_server = "192.168.1.45";

WiFiClient espClient;
PubSubClient client(espClient);

long lastMsg = 0;

#define ledPin 2

void blink_led(unsigned int times, unsigned int duration){
  for (int i = 0; i < times; i++) {
    digitalWrite(ledPin, HIGH);
    delay(duration);
    digitalWrite(ledPin, LOW); 
    delay(200);
  }
}

void setup_wifi() {
  delay(50);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  int c=0;
  while (WiFi.status() != WL_CONNECTED) {
    blink_led(2,200); //blink LED twice (for 200ms ON time) to indicate that wifi not connected
    delay(1000); //
    Serial.print(".");
    c=c+1;
    if(c>10){
        ESP.restart(); //restart ESP after 10 seconds
    }
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
}

void connect_mqttServer() {
  // Loop until we're reconnected
  while (!client.connected()) {

        //first check if connected to wifi
        if(WiFi.status() != WL_CONNECTED){
          //if not connected, then first connect to wifi
          setup_wifi();
        }

        //now attemt to connect to MQTT server
        Serial.print("Attempting MQTT connection...");
        // Attempt to connect
        if (client.connect("ESP32_client1")) { // Change the name of client here if multiple ESP32 are connected
          //attempt successful
          Serial.println("connected");
          // Subscribe to topics here
          client.subscribe("rpi/broadcast");
          //client.subscribe("rpi/xyz"); //subscribe more topics here
          
        } 
        else {
          //attempt not successful
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" trying again in 2 seconds");
    
          blink_led(3,200); //blink LED three times (200ms on duration) to show that MQTT server connection attempt failed
          // Wait 2 seconds before retrying
          delay(2000);
        }
  }
  
}

//this function will be executed whenever there is data available on subscribed topics
void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Check if a message is received on the topic "rpi/broadcast"
  if (String(topic) == "rpi/broadcast") {
      if(messageTemp == "10"){
        Serial.println("Action: blink LED");
        blink_led(1,1250); //blink LED once (for 1250ms ON time)
      }
  }

  //Similarly add more if statements to check for other subscribed topics 
}

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(115200);

  setup_wifi();
  client.setServer(mqtt_server,1883);//1883 is the default port for MQTT server
  client.setCallback(callback);
}

void loop() {
  
  if (!client.connected()) {
    connect_mqttServer();
  }

  client.loop();
  
  long now = millis();
  if (now - lastMsg > 4000) {
    lastMsg = now;

    client.publish("esp32/sensor1", "88"); //topic name (to which this ESP32 publishes its data). 88 is the dummy value.
    
  }
  
}

https://www.youtube.com/watch?v=Q2HL8rwZ20A


FAQ

Interesting IoT Resources

ESP32 with AWS

ESP32 GPIO pins in real-time with AWS API Gateway WebSockets

https://www.youtube.com/watch?v=z53MkVFOnIo

  • PlatformIO project with ESP32 WebSocket Client (C/C++)
  • Serverless Framework project utilizing AWS API Gateway WebSockets, AWS Lambda, and AWS DynamoDB to handle the communication between clients (TypeScript)
  • Web Application to control ESP32 from the browser (ReactJS)

ESP32 as WebServer

pico w web server

pico w web server c - https://www.youtube.com/watch?v=C_O0MXGBHsw