Setup RPi Pico W and ESP32
Last year I bough a couple of companions for my Raspberry Pi 4 2GB:
And Recently, this new release got my attention:
- 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)
Raspberry Pi and MLX90614 Temp Sensor
Raspberry Pi together with Infrared Sensors [Grafanaand InfluxDB]
Simulate IoT Projects
Tool to simulate these projects in the browser
Raspberry Pi and DHT11/22 Sensors
Using a Raspberry Pi 4 with DHT Temperature Sensors [MongoDB and MetaBase]
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);
}
Connecting ESP32 to WIFI 🚀
- https://www.youtube.com/watch?v=aAG0bp0Q-y4
- https://github.com/ttarnowski/esp32-wifi-connect
- https://github.com/ttarnowski/esp32-wifi-connect/blob/nonblocking/src/main.cpp
#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
Consumption: ~50-150mA and can be powered via a PC usb
- Compared to the RPi 4b 2gb: 5v3A which idles at 5V0.6A ~2/3w
Codes - https://github.com/JAlcocerT/RPi/tree/main/Z_MicroControllers/RPiPicoW
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
- Hold the BOOTSEL button on the Pico W
- Connect the Pico W to your computer via the USB cable
- Release the BOOTSEL button -> you will see a new device in the PC.
Download a MicroPython Release and move it to the Pico folder:
- Mip: https://github.com/micropython/micropython-lib
- installing from fork:
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
- PicoW + VSCode - https://www.youtube.com/watch?v=Q1Kfg8k54jM
- Pico in Arduino IDE
- Tools -> Board -> Boards Manager -> Install Arduino MBed OS RP2040 Boards - https://www.youtube.com/watch?v=5YOEauk9bLo
- Pico with Thony
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'])
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, 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.
}
}
FAQ
Interesting IoT Resources
- https://maps.sensor.community/#16/51.1295/16.9902
- https://opensensemap.org/explore/5fe22454c31ca0001caa780f
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