-
Notifications
You must be signed in to change notification settings - Fork 1
Digital Lutherie ESP32 Micropython
This page serves as tutorial and code repository for those interested in learning how to design musical interfaces with ESP32 boards under micropython. Looking for Arduino code? Please check my other page here for a similar wiki with Arduino.
In this tutorial CircuitPython will be our programming language. It is a micro version of python, or a micropython wrap with plenty of sensor and hardware libraries already included in the main package for our creative use of microcontrollers and microprocessors.
If you want to know more, visit the CircuitPython Essentials Documentation.
The documentation of the core modules is here: https://docs.circuitpython.org/en/latest/docs/index.html
The reference of each core module can be found here: https://docs.circuitpython.org/en/latest/shared-bindings/index.html#modules
First time flashing? Your board needs to be enabled by pressing this combination of two buttons:
-
Press button "0" and do not release
-
Press button "RST" and release
-
Release button "0"
Your board will be now enabled to be flashed with Circuit Python.
If reflashing Circuit Python is needed open this page preferably with Chrome: https://circuitpython.org/downloads and look for your board. In the following sections links to particular boards we use are provided.
-
connect USB-C cable to the COM port of the ESP32-S3
-
Run the installer from the website clicking on "Open Installer"
-
In the first pop-up window, click on Connect and select your Serial Port (I selected the wchusb version)
-
Click Next and the process of erasing and flashing the board will begin. The installer first creates a boot drive called S3DKC1BOOT (or S2MINI or similar) but it can only be accessed when the USB cable is at the USB Port labelled "USB" (not at COM). When the installer asks for the S3DKC1BOOT Drive disconnect the cable to the USB Port or just unplug and plug it again, wait a few seconds, and the drive will appear in your Finder or Windows browser. Select it.
-
The installer will install the adafruit libraries and will rename the boot drive as CIRCUITPY. Please select it when a pop-up window requires it.
*Add the WIFI details if wanted and check if the board can be accessed with Thonny.
*If you are flashing many boards, the webpage sometimes needs to be reloaded to find the serial port.
Install Thonny for your platform: download
Connect the board to the USB labelled port (not COM) and check:
-
you see a new mass storage folder called "CIRCUITPY" at your files browser
-
Download this ZIP file, extract it and copy its contents (and not the zip file) to the folder /CIRCUITPY/lib in the ESP32.
-
at Thonny's preferences interpreter you see the ESP32 port. Also select "CircuitPython (generic)" as your interpreter.
If you are missing some module or external module, or want to install your own libraries, you can download libraries from https://circuitpython.org/libraries (also from the community bundle). You just have to copy the .mpy files to the /lib folder in the mass storage folder CIRCUITPY. You can also read a tutorial about libraries in circuit python: https://learn.adafruit.com/adafruit-pyportal/circuitpython-libraries
We are using two boards:
-
a ESP32-S3 WROOM-1 N8R2 with two USB-C ports. It has Wi-Fi + Bluetooth LE, 2 MB PSRAM and 8 MB SPI Flash.
-
a ESP32-S2 WROOM with one microUSB port
-
a ESP32-S2 with USB-C port
It is similar to the original Espressif ESP32-S3-DevKit-1
Pinout (although this is a different board, their pinouts are the same):
RGB LED | Addressable RGB LED, driven by GPIO48. |
---|---|
USB Port | ESP32-S3 full-speed USB OTG interface, compliant with the USB 1.1 specification. The interface is used for power supply to the board, for flashing applications to the chip, for communication with the chip using USB 1.1 protocols, as well as for JTAG debugging. |
Do Not Use (generally)
gpio.43 Used for USB/Serial U0TXD
gpio.44 Used for USB Serial U0RXD
gpio.19 Used for native USB D-
gpio.20 Used for native USB D+
Strapping Pins
Typically these can be used, but you need to make sure they are not in the wrong state during boot.
gpio.0 Boot Mode. Weak pullup during reset. (Boot Mode 0=Boot from Flash, 1=Download)
gpio.3 JTAG Mode. Weak pull down during reset. (JTAG Config)
gpio.45 SPI voltage. Weak pull down during reset. (SPI Voltage 0=3.3v 1=1.8v)
gpio.46 Boot mode. Weak pull down during reset. (Enabling/Disabling ROM Messages Print During Booting)
Reflashing this ESP32-S3
If reflashing is needed (only admin) open this page with chrome: https://circuitpython.org/board/espressif_esp32s3_devkitc_1_n8r2/
ESP32-S2FN4R2 WiFi SoC, 4 MB Flash (embedded) and 2 MB PSRAM (embedded)
Circut Python installation: https://circuitpython.org/board/lolin_s2_mini/
Circuit Python Install with https://circuitpython.org/board/lilygo_ttgo_t8_esp32_s2_wroom/
RGB LED: board.IO18
-
boot.py
(if it exists) runs only once on start up before workflows are initialized. This lays the ground work for configuring USB at startup rather than it being fixed. Since serial is not available, output is written to boot_out.txt. -
code.py
(or main.py) is run after every reload until it finishes or is interrupted. After it is done running, the vm and hardware is reinitialized.
A few pure data examples to practice mapping can be downloaded from here: https://github.com/tamlablinz/learn-esp32/tree/master/pd-patches
If you need to install Pure Data: https://puredata.info/downloads/pure-data
There are plenty specificities of Circuit Python for ESP32. Take a look: https://learn.adafruit.com/circuitpython-with-esp32-quick-start/
This is how you will call them in CircuitPython
import board
dir(board)
The pin names available through board
are not the same as the pins labelled on the microcontroller itself. The board pin names are aliases to the microcontroller pin names. If you look at the datasheet of your microcontroller, you'll likely find a pinout with a series of pin names, such as "PA18" or "GPIO5". If you want to get to the actual microcontroller pin name in CircuitPython:
import microcontroller
dir(microcontroller.pin)
Finally, get the list of available modules:
help("modules")
The RGB LED is accessible on pin 48, and it is programmable through the neopixel library. More info about neopixel usage can be found here.
import board
import neopixel
import time
from rainbowio import colorwheel
#print(board.NEOPIXEL)
led = neopixel.NeoPixel(board.NEOPIXEL, 1) # for S3 boards
#led = neopixel.NeoPixel(board.IO18, 1) # for S2 boards only
led.brightness = 0.3
while True:
led[0] = (255, 0, 0)
time.sleep(0.5)
led[0] = (0, 255, 0)
time.sleep(0.5)
led[0] = (0, 0, 255)
time.sleep(0.5)
Read and detect capacitive touch on one pin (here IO4)
# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries
#
# SPDX-License-Identifier: MIT
#CircuitPython Essentials Capacitive Touch example
import time
import board
import touchio
touch_pad = board.IO4
touch = touchio.TouchIn(touch_pad)
touch.threshold = 20000
while True:
print(touch.raw_value)
if touch.value:
print("Touched!")
time.sleep(0.05)
Connect a potentiometer to IO14.
import time
import board
from analogio import AnalogIn
analog_in = AnalogIn(board.IO14)
def get_voltage(pin):
return (pin.value * 3.3) / 65536 # max voltage and digital value
while True:
print((analog_in.value,get_voltage(analog_in)))
time.sleep(0.1)
import time
import board
import digitalio
#buttons definition
button1 = digitalio.DigitalInOut(board.IO13)
button1.switch_to_input(pull=digitalio.Pull.UP)
while True:
print(button1.value)
time.sleep(0.1)
import ipaddress
import wifi
ssid="xxxxx"
passwd="xxxxxxx"
print('Hello World!')
for network in wifi.radio.start_scanning_networks():
print(network, network.ssid, network.channel)
wifi.radio.stop_scanning_networks()
print("joining network...")
print(wifi.radio.connect(ssid=ssid,password=passwd))
# the above gives "ConnectionError: Unknown failure" if ssid/passwd is wrong
print("my IP addr:", wifi.radio.ipv4_address)
More info on the wifi
module: https://docs.circuitpython.org/en/latest/shared-bindings/wifi/index.html# or https://learn.adafruit.com/pico-w-wifi-with-circuitpython/pico-w-basic-wifi-test
# import wifi module
import wifi
# set access point credentials
ap_ssid = "myAP"
ap_password = "password123"
# You may also need to enable the wifi radio with wifi.radio.enabled(true)
# configure access point
wifi.radio.start_ap(ssid=ap_ssid, password=ap_password)
"""
start_ap arguments include: ssid, password, channel, authmode, and max_connections
"""
# print access point settings
print("Access point created with SSID: {}, password: {}".format(ap_ssid, ap_password))
# print IP address
print("My IP address is", wifi.radio.ipv4_address)
# import wifi module
import wifi
import time
import os
import socketpool
import microosc
import board
import touchio
# set access point credentials
ap_ssid = "myAP2"
ap_password = "password123"
# configure access point
wifi.radio.start_ap(ssid=ap_ssid, password=ap_password)
# print IP address
print("AP active: ", wifi.radio.ap_active)
print("Access point IP: ", wifi.radio.ipv4_address_ap) # esp32: 192.168.4.1
#Configure OSC
socket_pool = socketpool.SocketPool(wifi.radio)
osc_client = microosc.OSCClient(socket_pool, "192.168.4.2", 5000) # connected laptop: 192.168.4.2
msg = microosc.OscMsg( "/capacitive", [0,], ("f",) )
#capacitive touch pin definition
touch_pad = board.IO4
touch = touchio.TouchIn(touch_pad)
touch.threshold = 20000
while True:
try:
msg.args[0] = touch.raw_value
osc_client.send(msg)
time.sleep(0.1)
except Exception as e: #in case there is no client connected
print("Error: (no client connected)", e)
time.sleep(0.1)
OSC requires the library microosc
(https://circuitpython-microosc.readthedocs.io/en/latest/), which can be downloaded with the Circuit Python community bundle (https://circuitpython.org/libraries). We have also included it into our particular lib.zip bundle.
"""send capacitive touch value with OSC, assumes native `wifi` support"""
import time
import os
import wifi
import socketpool
import microosc
import board
import touchio
#capacitive touch pin definition
touch_pad = board.IO4
touch = touchio.TouchIn(touch_pad)
touch.threshold = 20000
#Connect to the network
wifi.radio.connect("xxxxx","xxxxxxxx")
print("my ip address:", wifi.radio.ipv4_address)
socket_pool = socketpool.SocketPool(wifi.radio)
osc_client = microosc.OSCClient(socket_pool, "192.168.1.34", 5000)
#message definition
msg = microosc.OscMsg( "/capacitive", [0,], ("f",) )
#msg = microosc.OscMsg( "/capacitive", [0.99, 3, ], ("f", "i", ) ) #for more
while True:
msg.args[0] = touch.raw_value
osc_client.send(msg)
time.sleep(0.1)
ESP S2 and S3 models provide USB Host capabilities. Therefore it is possible to implement the USB MIDI protocol (https://docs.circuitpython.org/en/latest/shared-bindings/usb_midi/index.html).
The general information about circuit python and USB can be found here: https://learn.adafruit.com/customizing-usb-devices-in-circuitpython/circuitpy-midi-serial
An important detail with USB MIDI is that it is only possible to configure USB devices in the boot.py file. If you try to configure or change the USB device after boot.py you will get an error. For this reason, it is mandatory to have a boot.py file (create this file if necessary) with the following:
import usb_midi
import usb_hid
usb_hid.disable()
usb_midi.enable()
Everytime you change the boot.py it is necessary to hard reset the board by presing RST button.
Once you have the boot.py file as it is explained in the previous section, you can create another .py file with:
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
# simple_test
# modified by enrique tomas
import time
import random
import usb_midi
import board
import touchio
import adafruit_midi
from adafruit_midi.control_change import ControlChange
#set MIDI ports
print(usb_midi.ports)
midi = adafruit_midi.MIDI(
midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0
)
# Prepare capacitive touch input
touch_pad = board.IO4
touch = touchio.TouchIn(touch_pad)
while True:
# note how a list of messages can be used
print(int(touch.raw_value/512))
midi.send(ControlChange(3,int(touch.raw_value/512))) #65536 ->128
time.sleep(0.1)
(do not forget the boot.py file)
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
# simple_test
# modified by enrique tomas
import time
import random
import usb_midi
import adafruit_midi
from adafruit_midi.control_change import ControlChange
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn
#set MIDI ports
print(usb_midi.ports)
midi = adafruit_midi.MIDI(
midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0
)
print("Midi test: send a note on/off")
# Convert channel numbers at the presentation layer to the ones musicians use
print("Default output channel:", midi.out_channel + 1)
print("Listening on input channel:", midi.in_channel + 1)
while True:
midi.send(NoteOn(44, 120)) # G sharp 2nd octave
time.sleep(0.5)
# note how a list of messages can be used
midi.send(NoteOff("G#2", 120))
time.sleep(0.5)
More information about usb_midi can be found here. More information about adafruit_midi can be found here.
Exercise 1: Program a monophonic midi instrument which triggers a random MIDI note after touching a pin
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
# simple_test
# modified by enrique tomas
import time
import random
import usb_midi
import adafruit_midi
from adafruit_midi.control_change import ControlChange
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn
#set MIDI ports
print(usb_midi.ports)
midi = adafruit_midi.MIDI(
midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0
)
print("Midi test: send a note on/off")
# Convert channel numbers at the presentation layer to the ones musicians use
print("Default output channel:", midi.out_channel + 1)
print("Listening on input channel:", midi.in_channel + 1)
notes_list = [60, 62, 63, 65, 67, 68, 70] #a scale
i = 0 #index to read the list
while True:
midi.send(NoteOn(notes_list[i], 120)) # G sharp 2nd octave
time.sleep(0.5)
# note how a list of messages can be used
midi.send(NoteOff(notes_list[i], 120))
time.sleep(0.5)
i = (i + 1) % 7 # run from 0 to 6
print(i)
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
# simple_test
# modified by enrique tomas
import time
import random
import usb_midi
import board
import touchio
import adafruit_midi
from adafruit_midi.control_change import ControlChange
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn
#set MIDI ports
print(usb_midi.ports)
midi = adafruit_midi.MIDI(
midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0
)
print("Midi test: send a note on/off")
# Convert channel numbers at the presentation layer to the ones musicians use
print("Default output channel:", midi.out_channel + 1)
print("Listening on input channel:", midi.in_channel + 1)
# Prepare capacitive touch input
touch_pad = board.IO4
touch = touchio.TouchIn(touch_pad)
while True:
# note how a list of messages can be used
print(int(touch.raw_value/512))
midi.send(ControlChange(3,int(touch.raw_value/512))) #65536 ->128
time.sleep(0.05)
# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# modified by enrique tomas
"""
Using time.monotonic() to blink the built-in LED.
"""
import time
import digitalio
import board
import neopixel
# How long we want the LED to stay on
BLINK_ON_DURATION = 0.5
# How long we want the LED to stay off
BLINK_OFF_DURATION = 0.5
# When we last changed the LED state
LAST_BLINK_TIME = -1
print(board.NEOPIXEL)
led = neopixel.NeoPixel(board.NEOPIXEL, 1)
led.brightness = 0.3
ledState = True
while True:
# Store the current time to refer to later.
now = time.monotonic()
if not ledState:
# Is it time to turn on?
if now >= LAST_BLINK_TIME + BLINK_OFF_DURATION:
led[0] = (255, 0, 0)
ledState = True
LAST_BLINK_TIME = now
if ledState:
# Is it time to turn off?
if now >= LAST_BLINK_TIME + BLINK_ON_DURATION:
led[0] = (0, 0, 0)
ledState = False
LAST_BLINK_TIME = now
# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# modified by enrique tomas
import time
import usb_midi
import adafruit_midi
from adafruit_midi.control_change import ControlChange
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn
# How long we want the note to stay on and off
NOTE_ON_DURATION = 1.5
NOTE_OFF_DURATION = 1.5
# Variable to store when we last played the last note
LAST_NOTE_TIME = -1
#set MIDI ports
print(usb_midi.ports)
midi = adafruit_midi.MIDI(
midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0
)
playing = False
while True:
# Store the current time to refer to later.
now = time.monotonic()
if not playing:
# Is it time to Note on?
if now >= LAST_NOTE_TIME + NOTE_OFF_DURATION:
midi.send(NoteOn(44, 120))
print("midi Note On")
playing = True
LAST_NOTE_TIME = now
if playing:
# Is it time to Note off?
if now > LAST_NOTE_TIME + NOTE_ON_DURATION:
midi.send(NoteOff(44, 120))
print("midi Note Off")
playing = False
LAST_NOTE_TIME = now
Exercise 2: Play a list of MIDI notes in loop using the non-blocking method and modify their pitch with capacitive touch
Program a NON-BLOCKING 16 step sequencer with three analog controllable inputs (potentiometers, capacitive touch, LDR, etc): tempo, timbre and volume AND use the RGB LED as indicator: sync blink to tempo per step. Add two buttons to start and stop the sequencer. By default the sequencer should not play at startup.
If possible -> explore more possibilities: arpegios, modulations, chords, etc. Add more and more controls.... an enclosure etc :)
## Piezo Sensor Trigger with FFT
Connect a Piezo disc to your Analog Input and GND, using a 1 MOhm resistor between both pins.
import array import board from analogio import AnalogIn import neopixel import time from ulab import numpy as np
#led led = neopixel.NeoPixel(board.IO18, 1) # for S2 boards only #led = neopixel.NeoPixel(board.NEOPIXEL, 1) # for S3 boards led.brightness = 0.3
analog_in = AnalogIn(board.IO17) #piezo pin
fft_size = 8 #array for the piezo readings samples_bit = array.array('H', [0] * (fft_size+3))
print("begin_________________")
while True: #read the piezo for x in range(fft_size): samples_bit[x] = analog_in.value
#put in numpy array
samples = np.array(samples_bit[3:])
real,b = np.fft.fft(samples)
print(real) #print fft real part
if real[0] > 5000.0 : #check over a threshold the first partial
led[0] = (255, 0, 0)
print("ON___________________________")
else:
led[0] = (0, 0, 0)
# to see elapsed time
print("time ", time.monotonic_ns())
## ESPNOW
We recommend using "espnow" instead of "OSC". More information here: https://docs.circuitpython.org/en/latest/shared-bindings/espnow/index.html
## Waveforms
https://learn.adafruit.com/cpx-midi-controller/basic-synthesizer
# More sensors
## MPU-6050 Accel and Gyro
Copy the adafruit_mpu6050 library to the lib folder.Connect the sensor to 3V, GND, SCL and SDA. Most ESP32s allow using any pin as SCL and SDL. In this case we use SCL->IO9 and SDA->IO8.
If you want to know more about how circuit python deals with I2C you can visit: https://docs.circuitpython.org/en/latest/shared-bindings/busio/#busio.I2C and https://learn.adafruit.com/circuitpython-basics-i2c-and-spi/i2c-devices
import time import busio import board import adafruit_mpu6050
i2c = busio.I2C(board.IO9, board.IO8)
mpu = adafruit_mpu6050.MPU6050(i2c)
while True: print("Acceleration: X:%.2f, Y: %.2f, Z: %.2f m/s^2" % (mpu.acceleration)) print("Gyro X:%.2f, Y: %.2f, Z: %.2f rad/s" % (mpu.gyro)) print("Temperature: %.2f C" % mpu.temperature) print("") time.sleep(1)
calculate inclination angles between X and Y
import time import busio import board from math import atan2, degrees import adafruit_mpu6050
i2c = busio.I2C(board.IO9, board.IO8)
sensor = adafruit_mpu6050.MPU6050(i2c)
def vector_2_degrees(x, y,l=False): if l: angle = degrees(atan2(y, x)) else: angle = degrees(atan2(y, x)) if angle < 0: angle += 360 return angle
def get_inclination(_sensor): x, y, z = _sensor.acceleration return vector_2_degrees(x, z,True), vector_2_degrees(y, z), int(x),int(y),int(z)
x,y,z=0,0,0
while True:
turn, ac,x,y,z = get_inclination(sensor)
turn=int(turn)
ac=int(ac)
print(turn,ac,x,y,z,sep=" : ")
time.sleep(0.1)
Orientation in MIDI
import time import busio import board from math import atan2, degrees import adafruit_mpu6050
import usb_midi import board import adafruit_midi from adafruit_midi.control_change import ControlChange
#set MIDI ports print(usb_midi.ports) midi = adafruit_midi.MIDI( midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0 )
i2c = busio.I2C(board.IO9, board.IO8)
sensor = adafruit_mpu6050.MPU6050(i2c)
def vector_2_degrees(x, y,l=False): if l: angle = degrees(atan2(y, x)) else: angle = degrees(atan2(y, x)) if angle < 0: angle += 360 return angle
def get_inclination(_sensor): x, y, z = _sensor.acceleration return vector_2_degrees(x, z,True), vector_2_degrees(y, z), int(x),int(y),int(z)
x,y,z=0,0,0
while True:
turn, ac,x,y,z = get_inclination(sensor)
turn=int(turn/360*128)
ac=int(ac)
print(turn,ac,x,y,z,sep=" : ")
midi.send(ControlChange(3,int(turn))) #65536 ->128
time.sleep(0.1)
## VL53LOx distance sensor
Copy the adafruit_vl53l0x library to the lib folder. Connect the sensor to 3V, GND, SCL and SDA. Most ESP32s allow using any pin as SCL and SDL. In this case we use SCL->IO9 and SDA->IO8.
More information about this library can be found here: https://github.com/adafruit/Adafruit_CircuitPython_VL53L0X
import time
import board import busio
import adafruit_vl53l0x
i2c = busio.I2C(board.IO9, board.IO8) vl53 = adafruit_vl53l0x.VL53L0X(i2c)
while True: print("Range: {0}mm".format(vl53.range)) time.sleep(1.0)
## Website Reading
import time import ipaddress import wifi import socketpool import ssl import adafruit_requests import adafruit_requests as requests
ssid="xxxxx" passwd="xxxxxx"
print('Hello World!')
for network in wifi.radio.start_scanning_networks(): print(network, network.ssid, network.channel) wifi.radio.stop_scanning_networks()
print("joining network...") print(wifi.radio.connect(ssid=ssid,password=passwd))
print("my IP addr:", wifi.radio.ipv4_address)
print("pinging 1.1.1.1...") ip1 = ipaddress.ip_address("1.1.1.1") print("ip1:",ip1) print("ping:", wifi.radio.ping(ip1))
pool = socketpool.SocketPool(wifi.radio) request = adafruit_requests.Session(pool, ssl.create_default_context())
print("Fetching wifitest.adafruit.com..."); response = request.get("http://wifitest.adafruit.com/testwifi/index.html") print(response.status_code) print(response.text)
print("Fetching http://www.elpais.com"); response = request.get("http://www.elpais.com") print(response.status_code) #print(response.json()) print(response.text[:2500])
# Internet of Things
## Connect to Adafruit IO via MQTT
import os import time import ssl import socketpool import wifi import adafruit_minimqtt.adafruit_minimqtt as MQTT
aio_username = os.getenv("aio_username") aio_key = os.getenv("aio_key")
print(f"Connecting to {os.getenv('CIRCUITPY_WIFI_SSID')}") wifi.radio.connect( os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD") ) print(f"Connected to {os.getenv('CIRCUITPY_WIFI_SSID')}!")
photocell_feed = aio_username + "/feeds/photocell"
onoff_feed = aio_username + "/feeds/onoff"
def connected(client, userdata, flags, rc): # This function will be called when the client is connected # successfully to the broker. print(f"Connected to Adafruit IO! Listening for topic changes on {onoff_feed}") # Subscribe to all changes on the onoff_feed. client.subscribe(onoff_feed)
def disconnected(client, userdata, rc): # This method is called when the client is disconnected print("Disconnected from Adafruit IO!")
def message(client, topic, message): # This method is called when a topic the client is subscribed to # has a new message. print(f"New message on topic {topic}: {message}")
pool = socketpool.SocketPool(wifi.radio) ssl_context = ssl.create_default_context()
mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, username=aio_username, password=aio_key, socket_pool=pool, ssl_context=ssl_context, )
mqtt_client.on_connect = connected mqtt_client.on_disconnect = disconnected mqtt_client.on_message = message
print("Connecting to Adafruit IO...") mqtt_client.connect()
photocell_val = 0 while True: # Poll the message queue mqtt_client.loop()
# Send a new message
print(f"Sending photocell value: {photocell_val}...")
mqtt_client.publish(photocell_feed, photocell_val)
print("Sent!")
photocell_val += 10
time.sleep(5)