Text Editor
Adafruit recommends using the Mu editor for editing your CircuitPython code. You can get more info in this guide.
Alternatively, you can use any text editor that saves simple text files.
Download the Project Bundle
Your project will use a specific set of CircuitPython libraries and the code.py file. To get everything you need, click on the Download Project Bundle link below, and uncompress the .zip file.
Drag the contents of the uncompressed bundle directory onto your board's CIRCUITPY drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.
# SPDX-FileCopyrightText: 2024 johnpark for Adafruit Industries # # SPDX-License-Identifier: MIT ''' BLE BBQ Thermometer to WiFi to Adafruit IO Dashboard Feather ESP32-S3 8MB No PSRAM ''' import os import time import adafruit_connection_manager import wifi import adafruit_minimqtt.adafruit_minimqtt as MQTT import adafruit_ble from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble_ibbq import IBBQService 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')}") ### Feeds ### feeds = [aio_username + f"/feeds/bbq{i}" for i in range(1, 7)] battery_feed = aio_username + "/feeds/bbq_battery" # Define callback methods which are called when events occur # pylint: disable=unused-argument, redefined-outer-name def connected(client, userdata, flags, rc): print("Connected to Adafruit IO") def disconnected(client, userdata, rc): print("Disconnected from Adafruit IO") # Create a socket pool pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio) ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio) connection_manager = adafruit_connection_manager.get_connection_manager(pool) # Set up a MiniMQTT Client mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, username=aio_username, password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) # Setup the callback methods above mqtt_client.on_connect = connected mqtt_client.on_disconnect = disconnected # Connect the client to the MQTT broker. print("Connecting to Adafruit IO...") mqtt_client.connect() # PyLint can't find BLERadio for some reason so special case it here. ble = adafruit_ble.BLERadio() # pylint: disable=no-member ibbq_connection = None battery_percentage = 100 def c_to_f(temp_c): return (temp_c * 9/5) + 32 def volt_to_percent(voltage, max_voltage): return (voltage / max_voltage) * 100 def probe_check(temp): # if value is wildly high no probe is connected return temp if temp <= 11000 else 0 battery_val = 3.3 while True: print("Scanning...") for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=5): if IBBQService in adv.services: print("found an IBBq advertisement") ibbq_connection = ble.connect(adv) print("Connected") break # Stop scanning whether or not we are connected. ble.stop_scan() if ibbq_connection and ibbq_connection.connected: ibbq_service = ibbq_connection[IBBQService] ibbq_service.init() while ibbq_connection.connected: print( "Temperatures:", ibbq_service.temperatures, "; Battery:", ibbq_service.battery_level, ) grill_vals = [probe_check(c_to_f(temp)) for temp in ibbq_service.temperatures] battery_val, battery_max = ibbq_service.battery_level battery_percentage = (volt_to_percent(battery_val, 3.3)) mqtt_client.loop(timeout=1) for feed, val in zip(feeds, grill_vals): print(f"Sending grill value: {val} to {feed}...") mqtt_client.publish(feed, val) mqtt_client.publish(battery_feed, battery_percentage) print("Sent") time.sleep(5)
How It Works
The code does two key things -- connect to a Bluetooth iBBQ device to receive data and connect to the Internet via WiFi to send data via MQTT to AIO feeds.
Libraries
Import necessary libraries for WiFi connection, BLE communication, and MQTT for data transfer.
import os import time import adafruit_connection_manager import wifi import adafruit_minimqtt.adafruit_minimqtt as MQTT import adafruit_ble from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble_ibbq import IBBQService
Environment Variables for Adafruit IO
Retrieve Adafruit IO username and key from environment variables from the settings.toml file.
aio_username = os.getenv("aio_username") aio_key = os.getenv("aio_key")
Connect to WiFi
Connect to WiFi using the SSID and password stored in settings.toml file.
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')}")
Setup MQTT Feeds
Define functions to handle connection and disconnection events with the MQTT broker.
feeds = [aio_username + f"/feeds/bbq{i}" for i in range(1, 7)] battery_feed = aio_username + "/feeds/bbq_battery"
MQTT Callback Functions
Define functions to handle connection and disconnection events with the MQTT broker.
def connected(client, userdata, flags, rc): print("Connected to Adafruit IO") def disconnected(client, userdata, rc): print("Disconnected from Adafruit IO")
Create Socket Pool and SSL Context
Set up the socket pool and SSL context for secure MQTT communication.
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio) ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio) connection_manager = adafruit_connection_manager.get_connection_manager(pool)
Setup MQTT Client
Configure the MQTT client and connect it to the Adafruit IO broker.
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 print("Connecting to Adafruit IO...") mqtt_client.connect()
Initialize BLE Radio
Initialize the BLE radio for scanning and connecting to the BBQ thermometer.
ble = adafruit_ble.BLERadio()
Helper Functions
There are three functions created here. One to convert Celsius to Fahrenheit, another to convert voltage to percentage, and one to check if a temperature probe is connected.
def c_to_f(temp_c): return (temp_c * 9/5) + 32 def volt_to_percent(voltage, max_voltage): return (voltage / max_voltage) * 100 def probe_check(temp): return temp if temp <= 11000 else 0
Main Loop
The main loop first scans for the BBQ thermometer, and then connects to it.
Next, it reads temperature and battery data, converts them to Farenheit and Voltage, respectively.
Then, it sends this data to Adafruit IO using MQTT, and repeats the process in a loop every five seconds.
while True: print("Scanning...") for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=5): if IBBQService in adv.services: print("found an IBBq advertisement") ibbq_connection = ble.connect(adv) print("Connected") break ble.stop_scan() if ibbq_connection and ibbq_connection.connected: ibbq_service = ibbq_connection[IBBQService] ibbq_service.init() while ibbq_connection.connected: print("Temperatures:", ibbq_service.temperatures, "; Battery:", ibbq_service.battery_level) grill_vals = [probe_check(c_to_f(temp)) for temp in ibbq_service.temperatures] battery_val, battery_max = ibbq_service.battery_level battery_percentage = volt_to_percent(battery_val, 3.3) mqtt_client.loop(timeout=1) for feed, val in zip(feeds, grill_vals): print(f"Sending grill value: {val} to {feed}...") mqtt_client.publish(feed, val) mqtt_client.publish(battery_feed, battery_percentage) print("Sent") time.sleep(5)
On the next page follow the MQTT in CircuitPython guide to get your Adafruit IO account and feed set up.
Text editor powered by tinymce.