这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 任务一:TCS3200拾色传感器及显示色块(ai生成)

共1条 1/1 1 跳转至

任务一:TCS3200拾色传感器及显示色块(ai生成)

助工
2025-12-19 10:28:00     打赏

我参考了这位仁兄的代码

https://forum.eepw.com.cn/thread/397762/1

实现了拾色传感器的功能

因为之前做stm32搞C的,不大会python,所以用ai生成了一个识别颜色,显示色块的功能,但是显示的颜色有点问题。

代码如下


import board  

import digitalio  

import time  

import displayio  

import terminalio  

from adafruit_display_text import label  

# 定义按键变量

Button0_Value = 0

Button1_Value = 0

Button2_Value = 0

# 简单的移动平均平滑

class SimpleSmoother:

    """简单的移动平均平滑器,减少数值跳动"""

    def __init__(self, alpha=0.5):

        self.alpha = alpha  # 平滑系数 (0-1),越小越平滑

        self.r_smooth = 0

        self.g_smooth = 0

        self.b_smooth = 0

        self.initialized = False

   

    def smooth(self, r, g, b):

        """对RGB值进行平滑处理"""

        if not self.initialized:

            self.r_smooth = r

            self.g_smooth = g

            self.b_smooth = b

            self.initialized = True

        else:

            self.r_smooth = self.r_smooth * (1 - self.alpha) + r * self.alpha

            self.g_smooth = self.g_smooth * (1 - self.alpha) + g * self.alpha

            self.b_smooth = self.b_smooth * (1 - self.alpha) + b * self.alpha

       

        return int(self.r_smooth), int(self.g_smooth), int(self.b_smooth)

   

    def reset(self):

        """重置平滑器"""

        self.initialized = False

def rgb888_to_rgb565(r, g, b):

    """

    将24位RGB888格式转换为16位RGB565格式

    用于CircuitPython的displayio颜色显示

    """

    # 限制在0-255范围

    r = max(0, min(255, r))

    g = max(0, min(255, g))

    b = max(0, min(255, b))

   

    # 转换为RGB565

    r5 = (r >> 3) & 0x1F  # 取高5位

    g6 = (g >> 2) & 0x3F  # 取高6位

    b5 = (b >> 3) & 0x1F  # 取高5位

   

    return (r5 << 11) | (g6 << 5) | b5

class TCS3200:

    NUM_CYCLES = 10  # 测试多少个周期  

    def __init__(self, s0_pin, s1_pin, s2_pin, s3_pin, out_pin):  

        # 初始化控制引脚  

        self.s0 = digitalio.DigitalInOut(s0_pin)  

        self.s1 = digitalio.DigitalInOut(s1_pin)  

        self.s2 = digitalio.DigitalInOut(s2_pin)  

        self.s3 = digitalio.DigitalInOut(s3_pin)  

        self.out = digitalio.DigitalInOut(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  

        # 设置频率缩放比为100% (最高精度)  

        self.set_frequency_scaling(100)  

        # 白平衡校准系数 (初始值为1,需要实际校准)  

        self.r_scal = 1.0  

        self.g_scal = 1.0  

        self.b_scal = 1.0  

        print("TCS3200传感器初始化完成")  

    def set_frequency_scaling(self, scaling):  

        """  

        设置传感器的频率缩放比例  

        # s0  s1  

        # L   L   关闭  

        # L   H   2%  

        # H   L   20%  

        # H   H   100%  

        """  

        if scaling == 2:       # 2%  

            self.s0.value = False  

            self.s1.value = True  

            # print("TCS3200传感器设置频率缩放比为:%2 -> s0,s1[0,1]")  

        elif scaling == 20:    # 20%  

            self.s0.value = True  

            self.s1.value = False  

            # print("TCS3200传感器设置频率缩放比为:%20 -> s0,s1[1,0]")  

        elif scaling == 100:   # 100%  

            self.s0.value = True  

            self.s1.value = True  

            # print("TCS3200传感器设置频率缩放比为:%100 -> s0,s1[1,1]")  

        else:                  # 关闭  

            self.s0.value = False  

            self.s1.value = False  

            # print("TCS3200传感器设置频率缩放比为:%0 -> s0,s1[0,0]")  

        time.sleep(0.01)       # 短暂延时稳定频率缩放比例  

    def set_color_filter(self, filter_type):  

        """  

        设置传感器的颜色滤波器  

        # s2  s3  

        # L   L   Red  

        # H   H   Green  

        # L   H   Blue  

        # H   L   Clear(no filter)  

        """  

        if filter_type == "Red":  

            self.s2.value = False  

            self.s3.value = False  

            # print("TCS3200传感器设置颜色滤波器为:Red -> s2,s3[0,0]")  

        elif filter_type == "Green":  

            self.s2.value = True  

            self.s3.value = True  

            # print("TCS3200传感器设置颜色滤波器为:Green -> s2,s3[1,1]")  

        elif filter_type == "Blue":  

            self.s2.value = False  

            self.s3.value = True  

            # print("TCS3200传感器设置颜色滤波器为:Blue -> s2,s3[0,1]")  

        else:  # "Clear"  

            self.s2.value = True  

            self.s3.value = False  

            # print("TCS3200传感器设置颜色滤波器为:Clear -> s2,s3[1,0]")  

        time.sleep(0.01)       # 短暂延时稳定滤波器  

    def measure_frequency(self):  

        # 测量频率,并转换单位为Hz  

        timestamps = []  

        last_state = self.out.value  

        while len(timestamps) < self.NUM_CYCLES:  

            current_state = self.out.value  

            if current_state != last_state:  # 发生边缘变化  

                timestamps.append(time.monotonic_ns())  

                last_state = current_state  

        # 计数周期  

        periods = []  

        for i in range(2, len(timestamps), 2):  

            period_ns = timestamps[i] - timestamps[i - 2]  # 一个完整周期(两个边缘)  

            periods.append(period_ns)  

        avg_period_ns = sum(periods) / len(periods)  

        frequency = 1000000000 / avg_period_ns  # 转换为 Hz  

        # print(f"原始频率值 -> Frequency:{frequency:.3f}")  

        return frequency  

    def read_rgb_freq(self):  

        # 读取RGB三个通道的频率值  

        red_freq = 0  

        green_freq = 0  

        blue_freq = 0  

        # 读取红色分量 (S2=0, S3=0)  

        self.set_color_filter("Red")  

        red_freq = self.measure_frequency()  

        # 读取绿色分量 (S2=1, S3=1)  

        self.set_color_filter("Green")  

        green_freq = self.measure_frequency()  

        # 读取蓝色分量 (S2=0, S3=1)  

        self.set_color_filter("Blue")  

        blue_freq = self.measure_frequency()  

        # 清除绿色分量 (S2=1, S3=0)  

        # self.set_color_filter("Clear")  

        # print(f"原始频率值 -> R:{red_freq:.3f}, G:{green_freq:.3f}, B:{blue_freq:.3f}")  

        return red_freq, green_freq, blue_freq  

    def calibrate_white_balance(self):  

        # 白平衡校准 - 将传感器对准白色参考物后调用此方法  

        print("正在进行白平衡校准...")  

        print("请将传感器对准白色参考物")  

        # 读取白色参考物的原始频率  

        red, green, blue = self.read_rgb_freq()  

        # 换算为RGB值 (18000/255 = 70)  

        red = red / 70 if red > 0 else 1.0  

        green = green / 70 if green > 0 else 1.0  

        blue = blue / 70 if blue > 0 else 1.0  

        # 计算校准系数 (假设我们希望白色时RGB值接近255)  

        self.r_scal = 255.0 / red if red > 0 else 1.0  

        self.g_scal = 255.0 / green if green > 0 else 1.0  

        self.b_scal = 255.0 / blue if blue > 0 else 1.0  

        print(f"校准完成 -> R:{self.r_scal:.3f}, G:{self.g_scal:.3f}, B:{self.b_scal:.3f}")  

    def read_rgb(self):  

        # 读取RGB三个通道的频率值,应用白平衡,并转换为RGB  

        r = 0  

        g = 0  

        b = 0  

        # 读取RGB三个通道的频率值  

        red_freq, green_freq, blue_freq = self.read_rgb_freq()  

        # 应用白平衡校准 (18000/255 = 70)  

        r = int(red_freq / 70 * self.r_scal)  

        g = int(green_freq / 70 * self.g_scal)  

        b = int(blue_freq / 70 * self.b_scal)  

        # 限制在0-255范围  

        r = max(0, min(255, r))  

        g = max(0, min(255, g))  

        b = max(0, min(255, b))  

        return r, g, b  


 

# 初始化板载按键D0/BOOT0,按下接地  

button0 = digitalio.DigitalInOut(board.BUTTON)  

button0.switch_to_input(pull=digitalio.Pull.UP)  

# 初始化板载按键D1,按下接VCC  

button1 = digitalio.DigitalInOut(board.D1)  

button1.switch_to_input(pull=digitalio.Pull.DOWN)  

# 初始化板载按键D2,按下接VCC  

button2 = digitalio.DigitalInOut(board.D2)  

button2.switch_to_input(pull=digitalio.Pull.DOWN)  

# 初始化板载LED  

led0 = digitalio.DigitalInOut(board.LED)  

# led0 = digitalio.DigitalInOut(board.D13)  

led0.direction = digitalio.Direction.OUTPUT  

led0.value = True  

# 初始化颜色传感器LED补光灯  

led1 = digitalio.DigitalInOut(board.D5)  

led1.direction = digitalio.Direction.OUTPUT  

led1.value = True  

# 初始化显示屏

display = board.DISPLAY

# 创建显示组

splash = displayio.Group()

display.root_group = splash

# 创建DIY活动文本标签

textdo = "Let's do - EEPW DIY"

text_area_do = label.Label(terminalio.FONT, text=textdo, color=0xFFFF00, x=60, y=20)

# 创建文本标签用于显示RGB值

text_area_r = label.Label(terminalio.FONT, text="R: ---", color=0xFF0000, x=10, y=50)

text_area_g = label.Label(terminalio.FONT, text="G: ---", color=0x00FF00, x=10, y=70)

text_area_b = label.Label(terminalio.FONT, text="B: ---", color=0x0000FF, x=10, y=90)

text_area_h = label.Label(terminalio.FONT, text="#------", color=0xFFFFFF, x=10, y=120)

# 创建颜色色块显示区域(矩形)

# 位置在屏幕右侧,大小80x80像素

color_block = displayio.TileGrid(

    displayio.Bitmap(80, 80, 1),

    pixel_shader=displayio.Palette(1),

    x=150,  # 右侧位置

    y=40    # 垂直居中

)

color_block.pixel_shader[0] = rgb888_to_rgb565(0, 0, 0)  # 初始黑色

splash.append(color_block)

# 显示输出

for text_area in (text_area_do, text_area_r, text_area_g, text_area_b, text_area_h):

    splash.append(text_area)

# 创建颜色平滑器

color_smoother = SimpleSmoother(alpha=0.3)  # 适度的平滑

# 创建TCS3200颜色传感器实体

try:

    # 创建TCS3200对象

    color_sensor = TCS3200(

        s0_pin=board.D12,

        s1_pin=board.D11,

        s2_pin=board.D10,

        s3_pin=board.D9,

        out_pin=board.D6

    )

    print("TCS3200实例创建成功")

except Exception as e:

    print(f"初始化TCS3200失败: {e}")

    # 创建虚拟传感器用于测试

    color_sensor = None

# 主循环  

while True:  

    led0.value = True  

    time.sleep(0.05)  

    # 读取按键0  

    if not button0.value:  

        print("button0按下")  

        Button0_Value = 1  

        Button1_Value = 0  

        Button2_Value = 0  

    # 读取按键1  

    if button1.value:  

        print("button1按下")  

        Button0_Value = 0  

        Button1_Value = 1  

        Button2_Value = 0  

    # 读取按键2  

    if button2.value:  

        print("button2按下")  

        Button0_Value = 0  

        Button1_Value = 0  

        Button2_Value = 1  

    if Button0_Value:  

        Button0_Value = 0  

        # 调用白平衡校准  

        color_sensor.calibrate_white_balance()  

        # 更新显示  

        text_area_r.text = "R: {:.3f}".format(color_sensor.r_scal)  

        text_area_g.text = "G: {:.3f}".format(color_sensor.g_scal)  

        text_area_b.text = "B: {:.3f}".format(color_sensor.b_scal)  

        text_area_h.text = "#------"  

        # 将颜色色块重置为白色(使用正确的RGB565格式)

        color_block.pixel_shader[0] = rgb888_to_rgb565(255, 255, 255)

        # 重置平滑器

        color_smoother.reset()

    if Button1_Value:  

        # 读取并显示TCS3200颜色传感器的频率值  

        if color_sensor is not None:  

            try:  

                # 调用read_rgb_freq方法读取频率值  

                R_Val, G_Val, B_Val = color_sensor.read_rgb_freq()  

                # 更新显示  

                text_area_r.text = "R: {:.3f}".format(R_Val)  

                text_area_g.text = "G: {:.3f}".format(G_Val)  

                text_area_b.text = "B: {:.3f}".format(B_Val)  

                text_area_h.text = "#: {:.3f},{:.3f},{:.3f}".format(R_Val, G_Val, B_Val)  

                # 将频率值转换为0-255范围

                # 频率值通常在0-18000之间,我们将其映射到0-255

                r_color = int(min(255, max(0, R_Val / 70)))

                g_color = int(min(255, max(0, G_Val / 70)))

                b_color = int(min(255, max(0, B_Val / 70)))

               

                # 应用平滑处理

                r_smooth, g_smooth, b_smooth = color_smoother.smooth(r_color, g_color, b_color)

               

                # 转换为正确的RGB565格式并更新颜色色块

                color_value = rgb888_to_rgb565(r_smooth, g_smooth, b_smooth)

                color_block.pixel_shader[0] = color_value

                print("RGB: {:.3f},{:.3f},{:.3f}".format(R_Val, G_Val, B_Val))  

            except Exception as e:  

                print(f"读取颜色传感器错误: {e}")  

                R_Val = 128  

                G_Val = 128  

                B_Val = 128  

                # 更新颜色色块为灰色(使用正确的RGB565格式)

                color_block.pixel_shader[0] = rgb888_to_rgb565(128, 128, 128)

        else:  

            # 更新显示屏  

            text_area_r.text = "R: {:.3f}".format(R_Val)  

            text_area_g.text = "G: {:.3f}".format(G_Val)  

            text_area_b.text = "B: {:.3f}".format(B_Val)  

            text_area_h.text = "#: {:.3f},{:.3f},{:.3f}".format(R_Val, G_Val, B_Val)  

            # 更新颜色色块为灰色(使用正确的RGB565格式)

            color_block.pixel_shader[0] = rgb888_to_rgb565(128, 128, 128)

    if Button2_Value:  

        # 读取并显示TCS3200颜色传感器的RGB值  

        if color_sensor is not None:  

            try:  

                # 调用read_rgb方法读取颜色值  

                R_Val, G_Val, B_Val = color_sensor.read_rgb()  

                # 更新显示  

                text_area_r.text = "R: {:3d}".format(R_Val)  

                text_area_g.text = "G: {:3d}".format(G_Val)  

                text_area_b.text = "B: {:3d}".format(B_Val)  

                text_area_h.text = "#: {:02X}{:02X}{:02X}".format(R_Val, G_Val, B_Val)  

                # 应用平滑处理

                r_smooth, g_smooth, b_smooth = color_smoother.smooth(R_Val, G_Val, B_Val)

               

                # 转换为正确的RGB565格式并更新颜色色块

                color_value = rgb888_to_rgb565(r_smooth, g_smooth, b_smooth)

                color_block.pixel_shader[0] = color_value

                print("RGB: #{:02X}{:02X}{:02X}".format(R_Val, G_Val, B_Val))  

            except Exception as e:  

                print(f"读取颜色传感器错误: {e}")  

                R_Val = 128  

                G_Val = 128  

                B_Val = 128  

                # 更新颜色色块为灰色(使用正确的RGB565格式)

                color_block.pixel_shader[0] = rgb888_to_rgb565(128, 128, 128)

        else:  

            # 更新显示屏  

            text_area_r.text = "R: {:3d}".format(R_Val)  

            text_area_g.text = "G: {:3d}".format(G_Val)  

            text_area_b.text = "B: {:3d}".format(B_Val)  

            text_area_h.text = "#: {:02X}{:02X}{:02X}".format(R_Val, G_Val, B_Val)  

            # 更新颜色色块为灰色(使用正确的RGB565格式)

            color_block.pixel_shader[0] = rgb888_to_rgb565(128, 128, 128)

    led0.value = False

    time.sleep(0.05)

识别颜色显示色块.zip

c3af90223aba1205dc6393e1151b888f.jpg



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]