Once you've finished setting up your Feather ESP32-S2 with CircuitPython, you can download the project bundle to access the code and necessary libraries.
To do this, click the Download Project Bundle button in the window below. The file will download to your computer as a zipped folder.
Upload the Code and Libraries to the Feather ESP32
After downloading the Project Bundle, plug your Pico W into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the Feather's CIRCUITPY drive.
- lib folder
- code.py
Your Feather CIRCUITPY drive should look like this after copying the lib folder.
# SPDX-FileCopyrightText: 2024 Trevor Beaton for Adafruit Industries # # SPDX-License-Identifier: MIT '''This is a program for a color detection project using the APD-9960 and Feather ESP32-S2 & S3''' import os import ssl import time import wifi import board import busio import socketpool import adafruit_requests from adafruit_apds9960.apds9960 import APDS9960 from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # WiFi and Adafruit IO setup aio_username = os.getenv("aio_username") aio_key = os.getenv("aio_key") wifi.radio.connect( os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD") ) print(f"Connected to {os.getenv('CIRCUITPY_WIFI_SSID')}!") # Initialize network pool and Adafruit IO HTTP pool = socketpool.SocketPool(wifi.radio) requests = adafruit_requests.Session(pool, ssl.create_default_context()) io = IO_HTTP(aio_username, aio_key, requests) # Set up I2C connection and APDS9960 sensor i2c = busio.I2C(board.SCL, board.SDA) apds = APDS9960(i2c) apds.enable_proximity = True apds.enable_color = True # Adafruit IO feed setup try: hue_feed = io.get_feed("hue") except AdafruitIO_RequestError: hue_feed = io.create_new_feed("hue") # Function to convert RGB to Hue def rgb_to_hue(r: int, g: int, b: int) -> float: r_norm = r / 255.0 g_norm = g / 255.0 b_norm = b / 255.0 c_max = max(r_norm, g_norm, b_norm) c_min = min(r_norm, g_norm, b_norm) delta = c_max - c_min if delta == 0: calculated_hue = 0 elif c_max == r_norm: calculated_hue = (60 * ((g_norm - b_norm) / delta) + 360) % 360 elif c_max == g_norm: calculated_hue = (60 * ((b_norm - r_norm) / delta) + 120) % 360 elif c_max == b_norm: calculated_hue = (60 * ((r_norm - g_norm) / delta) + 240) % 360 else: calculated_hue = 0 # Fallback case return calculated_hue # Main loop while True: color_data = apds.color_data red_value, green_value, blue_value = color_data[0], color_data[1], color_data[2] hue_value = round(rgb_to_hue(red_value, green_value, blue_value)) print(f"Detected Hue: {hue_value}") try: io.send_data(hue_feed["key"], hue_value) print(f"Sent Hue value {hue_value} to Adafruit IO feed 'hue'") except AdafruitIO_RequestError as e: print(f"Error sending data: {e}") time.sleep(3)
Add Your settings.toml File
As of CircuitPython 8.0.0, there is support for Environment Variables. Environment variables are stored in a settings.toml file. Similar to secrets.py, the settings.toml file separates your sensitive information from your main code.py file. Add your settings.toml file as described in the Create Your settings.toml File page earlier in this guide. You'll need to include your CIRCUITPY_WIFI_SSID
and CIRCUITPY_WIFI_PASSWORD
.
CIRCUITPY_WIFI_SSID = "your-ssid-here" CIRCUITPY_WIFI_PASSWORD = "your-ssid-password-here"
Setting up Adafruit IO Connection
This code sets up a networking connection to Adafruit IO using the aio_username
and aio_key
. It also configures a "hue" data feed to send hue values calculated from the detected colors.
# Adafruit IO setup aio_username = os.getenv("aio_username") aio_key = os.getenv("aio_key") # Adafruit IO feed setup try: hue_feed = io.get_feed("hue") except AdafruitIO_RequestError: hue_feed = io.create_new_feed("hue")
I2C Sensor Initialization
This code initializes the APDS9960 color and proximity sensor over the I2C bus. it also enables proximity detection and color sensing features to gather RGB color data.
i2c = busio.I2C(board.SCL, board.SDA) apds = APDS9960(i2c) apds.enable_proximity = True apds.enable_color = True
RGB to Hue Conversion
This function rgb_to_hue
converts RGB values (red, green, blue) into a Hue value based on the HSB (Hue, Saturation, Brightness) color model.
def rgb_to_hue(r: int, g: int, b: int) -> float: r_norm = r / 255.0 g_norm = g / 255.0 b_norm = b / 255.0 c_max = max(r_norm, g_norm, b_norm) c_min = min(r_norm, g_norm, b_norm) delta = c_max - c_min if delta == 0: calculated_hue = 0 elif c_max == r_norm: calculated_hue = (60 * ((g_norm - b_norm) / delta) + 360) % 360 elif c_max == g_norm: calculated_hue = (60 * ((b_norm - r_norm) / delta) + 120) % 360 elif c_max == b_norm: calculated_hue = (60 * ((r_norm - g_norm) / delta) + 240) % 360 else: calculated_hue = 0 # Fallback case return calculated_hue
The Main Loop
The main loop captures color data, processes it, and sends the calculated hue value to Adafruit IO. It also adds a delay of 3 seconds between iterations to control update frequency.
while True: color_data = apds.color_data red_value, green_value, blue_value = color_data[0], color_data[1], color_data[2] hue_value = round(rgb_to_hue(red_value, green_value, blue_value)) print(f"Detected Hue: {hue_value}") try: io.send_data(hue_feed["key"], hue_value) print(f"Sent Hue value {hue_value} to Adafruit IO feed 'hue'") except AdafruitIO_RequestError as e: print(f"Error sending data: {e}") time.sleep(3)
Text editor powered by tinymce.