完成开发环境的搭建,下面开始第一个实验,具体详细步骤如下:
首先是硬件的连接,开发板的硬件引脚带有芯片模块一面的图片如下所示:

带有显示屏幕一面的引脚图如下所示:

颜色传感器模块的硬件介绍如下:

开发板和颜色传感器的连接为:
颜色传感器 开发板
VDD---------------- 3.3V
GND---------------- GND
S0------------------- D3
S1------------------- D4
S2------------------- D5
S3------------------- D6
OUT----------------- D9
连接效果如下所示:

确认连接没有问题,特别注意电源的正负极要正确之后,完成硬件的连接,即可连接到电脑供电进行后续的程序开发。
由于程序中需要引用到库文件adafruit_display_text,因此需要首先准备好次库文件。
首先,需要官网下载官方的库,下载地址如下:
https://circuitpython.org/libraries
我下载的库是adafruit-circuitpython-bundle-10.x-mpy-20251004,
下载之后解压,找到里面lib文件夹下的adafruit_display_text文件夹,把这个这个文件夹复制到开发板在电脑上显示的盘符下的lib文件加下,效果如下:

至此,完成程序中用到的库文件的安装。
然后,打开Mu编辑器,点击顶部的有向上箭头的“加载”按钮,打开了一个文件打开的对话框,找到开发板在电脑上对应的盘符,并打开,选中里面的“code.py”,并点击选择打开,可打开开发板的编程文件,里面有“Hello World”入门简单程序,删除此程序,然后把下面的程序复制到里面:
import time
import board
import digitalio
import displayio
import terminalio
from adafruit_display_text import label
import neopixel
# -----------------------
# TCS3200 传感器类
# -----------------------
class TCS3200:
def __init__(self, s0, s1, s2, s3, out_pin):
self.s0 = s0
self.s1 = s1
self.s2 = s2
self.s3 = s3
self.out = out_pin
self.s0.direction = digitalio.Direction.OUTPUT
self.s1.direction = digitalio.Direction.OUTPUT
self.s2.direction = digitalio.Direction.OUTPUT
self.s3.direction = digitalio.Direction.OUTPUT
self.out.direction = digitalio.Direction.INPUT
# 白平衡校准值
self.white_r = 1.0
self.white_g = 1.0
self.white_b = 1.0
# 颜色校正参数
self.color_threshold = 0.15 # 颜色阈值,低于此值的颜色分量将被设为0
self.calibration_mode = False # 校准模式标志
def set_frequency(self, freq_mode):
if freq_mode == 0: # 2%
self.s0.value = False
self.s1.value = False
elif freq_mode == 1: # 20%
self.s0.value = False
self.s1.value = True
elif freq_mode == 2: # 100%
self.s0.value = True
self.s1.value = False
else:
self.s0.value = True
self.s1.value = True
def set_color_channel(self, color):
if color == 'R':
self.s2.value = False
self.s3.value = False
elif color == 'G':
self.s2.value = True
self.s3.value = True
elif color == 'B':
self.s2.value = False
self.s3.value = True
def calibrate_white(self, out_pin):
"""执行白平衡校准,获取白色表面的RGB频率值"""
text_label.text = "White balance calibration...\nPoint sensor at white surface"
display.refresh()
time.sleep(2)
# 测量白色表面的RGB频率
self.set_color_channel('R')
time.sleep(0.2)
self.white_r = measure_frequency(out_pin)
self.set_color_channel('G')
time.sleep(0.2)
self.white_g = measure_frequency(out_pin)
self.set_color_channel('B')
time.sleep(0.2)
self.white_b = measure_frequency(out_pin)
print(f"White balance calibration complete: R={self.white_r}, G={self.white_g}, B={self.white_b}")
def frequency_to_rgb(self, freq_r, freq_g, freq_b):
"""将频率值转换为RGB(0-255)值"""
# 避免除以0
if self.white_r <= 0: self.white_r = 1
if self.white_g <= 0: self.white_g = 1
if self.white_b <= 0: self.white_b = 1
# 计算相对值并转换为0-255范围
r = min(255, int(255 * freq_r / self.white_r))
g = min(255, int(255 * freq_g / self.white_g))
b = min(255, int(255 * freq_b / self.white_b))
# 颜色校正:增强颜色饱和度,减少偏色
# 找出最大值
max_val = max(r, g, b)
if max_val > 0:
# 计算阈值,低于阈值的颜色分量设为0
threshold = max_val * self.color_threshold
if g < threshold: g = 0
if b < threshold: b = 0
if r < threshold: r = 0
return (r, g, b)
def adjust_color_threshold(self, delta):
"""调整颜色阈值参数"""
self.color_threshold = max(0.05, min(0.5, self.color_threshold + delta))
print(f"Color threshold adjusted to: {self.color_threshold:.2f}")
return self.color_threshold
# -----------------------
# 频率测量
# -----------------------
NUM_CYCLES = 10
def measure_frequency(out_pin):
timestamps = []
last = out_pin.value
while len(timestamps) < NUM_CYCLES:
current = out_pin.value
if current != last:
timestamps.append(time.monotonic_ns())
last = current
periods = []
for i in range(2, len(timestamps), 2):
period = timestamps[i] - timestamps[i-2]
periods.append(period)
avg_period = sum(periods) / len(periods)
return 1_000_000_000 / avg_period
# -----------------------
# TFT 显示设置
# -----------------------
display = board.DISPLAY
splash = displayio.Group()
display.root_group = splash
text_label = label.Label(
font=terminalio.FONT,
text="Initializing...",
color=0xFFFFFF,
scale=1,
x=10,
y=30
)
splash.append(text_label)
# 用于显示颜色的矩形块
color_bitmap = displayio.Bitmap(60, 60, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x000000 # 初始黑色
color_tilegrid = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=150, y=20)
splash.append(color_tilegrid)
# -----------------------
# 硬件引脚分配
# -----------------------
s0 = digitalio.DigitalInOut(board.D3)
s1 = digitalio.DigitalInOut(board.D4)
s2 = digitalio.DigitalInOut(board.D5)
s3 = digitalio.DigitalInOut(board.D6)
out_pin = digitalio.DigitalInOut(board.D9)
# 校准按键 (D1) - 按下时为高电平
calibrate_button = digitalio.DigitalInOut(board.D1)
calibrate_button.direction = digitalio.Direction.INPUT
# 不需要上拉电阻,因为按键按下时为高电平
# 调整颜色阈值按键 (D2) - 按下时为高电平
adjust_button = digitalio.DigitalInOut(board.D2)
adjust_button.direction = digitalio.Direction.INPUT
# 不需要上拉电阻,因为按键按下时为高电平
sensor = TCS3200(s0, s1, s2, s3, out_pin)
sensor.set_frequency(2) # 100% 模式
# 初始化NeoPixel
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
pixel.brightness = 0.3
# -----------------------
# 主循环
# -----------------------
# 启动时执行白平衡校准
sensor.calibrate_white(out_pin)
text_label.text = "Calibration complete\nStarting color recognition...\nPress D1 (HIGH) to recalibrate\nPress D2 (HIGH) to adjust color"
display.refresh()
time.sleep(1)
# 主循环
while True:
# 检查是否需要重新校准(带消抖)
if calibrate_button.value:
# 简单消抖:等待一小段时间确认按键仍然被按下
time.sleep(0.05)
if calibrate_button.value:
sensor.calibrate_white(out_pin)
text_label.text = "Calibration complete\nStarting color recognition...\nPress D1 (HIGH) to recalibrate\nPress D2 (HIGH) to adjust color"
display.refresh()
# 等待按键释放
while calibrate_button.value:
time.sleep(0.01)
time.sleep(0.5) # 额外延迟防止重复触发
# 检查是否需要调整颜色阈值(带消抖)
if adjust_button.value:
# 简单消抖:等待一小段时间确认按键仍然被按下
time.sleep(0.05)
if adjust_button.value:
# 每次按下增加0.05的阈值
sensor.adjust_color_threshold(0.05)
# 等待按键释放
while adjust_button.value:
time.sleep(0.01)
time.sleep(0.5) # 额外延迟防止重复触发
sensor.set_color_channel('R')
time.sleep(0.05)
freq_r = measure_frequency(out_pin)
sensor.set_color_channel('G')
time.sleep(0.05)
freq_g = measure_frequency(out_pin)
sensor.set_color_channel('B')
time.sleep(0.05)
freq_b = measure_frequency(out_pin)
# 将频率转换为RGB值
r, g, b = sensor.frequency_to_rgb(freq_r, freq_g, freq_b)
# 更新 TFT 色块为当前颜色
color_palette[0] = (r << 16) | (g << 8) | b
# 更新NeoPixel颜色
pixel.fill((r, g, b))
text_label.text = (
f"Frequency: RGB Value\n"
f"R: {freq_r:6.1f} {r:3}\n"
f"G: {freq_g:6.1f} {g:3}\n"
f"B: {freq_b:6.1f} {b:3}\n"
f"Threshold: {sensor.color_threshold:.2f}\n"
f"D1(HIGH):cal D2(HIGH):adj"
)
display.refresh()
time.sleep(0.1)
这里要注意,由于要用到的板载的Neo颜色LED需要安装对应的驱动才能驱动起来,在这里可以在官网下载对应的例程,参考链接:https://learn.adafruit.com/esp32-s2-reverse-tft-feather/neopixel-led
把例程里面的库文件复制到开发板的程序库里面,完成后的效果如下:

完成Neo驱动库的添加。
完成后,点击顶部菜单里含有向下箭头的“保存”按钮,程序就自动下载到开发板了。
程序运行之后初始界面显示如下:

提示按下D1进行自适应矫正,按下D2调整颜色阈值,在白光环境下按下D1进行自适应矫正,按下D2调整颜色阈值。
矫正之后的效果如下:

用一个带有颜色物体放置到颜色传感器前面,效果如下:

可以看到屏幕显示的颜色和物体颜色一致,开发板背面的颜色传感器也变换显示对应的颜色。
我要赚赏金
