这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » Let'sdo-2025年第3期-02任务1和任务2:TCS3200驱动设计

共2条 1/1 1 跳转至

Let'sdo-2025年第3期-02任务1和任务2:TCS3200驱动设计

高工
2025-12-01 11:00:19     打赏

        本次活动最主要的一个任务就是对TCS3200的驱动,做任务的小伙伴们要注意,CircuitPython并没有对TCS3200传感器的直接驱动的固件,有能力的喜欢探索的小伙伴可以尝试mpy或者arduino的方式进行开发,实际主控是ESP32-S3,可能大家都很熟悉了。

        言归正传,我们对TCS3200进行一下学习,我们通过原理图查看可以了解很多基本信息:        

        实际上这个板卡上的传感器可能是TCS230D或者TCS3200,二者pinout及电气性能一样,传感器的控制主要是S2, S3选择颜色通道,S0, S1对应的是输出缩放选择,相关的配置选择如下:

        这四个引脚是直接IO口的输出控制,我们在cpy中需要配置为输出:
led = digitalio.DigitalInOut(board.D12)
led.direction = digitalio.Direction.OUTPUT
led.value = True

s0_pin = digitalio.DigitalInOut(board.D5)
s1_pin = digitalio.DigitalInOut(board.D6)
s2_pin = digitalio.DigitalInOut(board.D9)
s3_pin = digitalio.DigitalInOut(board.D10)

这里我们选择的数字输出的引脚,同时配置LED打开,具体引脚可参考如下:

        


        对于TCS3200来说还要一个输出引脚,这里我们使用的是D11进行输入采集:

out_pin = digitalio.DigitalInOut(board.D11)
        接下来就是TCS3200的驱动配置函数了,这里我们单独写了一个py:
import time

import digitalio
import board


class TCS3200:
    def __init__(self, s0, s1, s2, s3, out_pin):
        # 初始化TCS3200的控制引脚
        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.set_frequency(2)

    def set_frequency(self, freq_mode):
        """
        设置传感器的频率控制(S0和S1)。
        0: 2%频率
        1: 20%频率
        2: 100%频率
        """
        if freq_mode == 0:
            self.s0.value = False
            self.s1.value = False
        elif freq_mode == 1:
            self.s0.value = False
            self.s1.value = True
        elif freq_mode == 2:
            self.s0.value = True
            self.s1.value = False
        else:
            self.s0.value = True
            self.s1.value = True

    def set_color_channel(self, color):
        """
        设置S2和S3引脚来选择颜色通道
        'R': Red
        'G': Green
        'B': Blue
        """
        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
        这里基本上只有S0-S3的配置控制,实际上还应该包括PWM的采集,不过并没有找到对PWM频率采集的支持,一般我们通过pulseio可以获取的,不过这个板子用pulseio输出可以,输入采集没有成功,所以我们使用了一个笨方法进行采集:
# 配置采样次数
NUM_CYCLES = 10  # 测多少个周期

def measure_frequency():
    timestamps = []
    last_state = out_pin.value

    while len(timestamps) < NUM_CYCLES:
        current_state = out_pin.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 = 1_000_000_000 / avg_period_ns  # 转换成 Hz
    return frequency

        大家也可以进一步优化一下,我们配置一个通道后调用这个函数采集一下频率就可以获得原始数据,我们看一下几种颜色的频率输出(这里都是以纸上的颜色作为基本色进行采集)。

白色:

蓝色:

绿色:

红色:


褐色:

黄色:

橙色:

紫色:

黑色:

1.jpg

        我们可以看到数值上还是有明显的差异的,不过这里只是基本的输出,实际输出每个人可能都不一样,比如LED不开启的时候,受环境光的影响导致技术处差异非常大,我们建议开启LED,还要把握好距离,这里的所有注意事项都因为实际影响的参数是单通道的进光量。

        接下来我们还要进行一下频率与RGB值的转化,这里就需要注意了,实现开始之前,如果能固定环境光和发光等因素,可以通过采集白色作为各通道最高值(实际上白纸的白色并不是纯正的白色,并且表面也不光滑,仅作为参考),进行白平衡调整,我们目前来看采集的值只能说是趋势是一定的。

        我们大致将18000作为三原色256对应的值,进行算法的转化:

RGB = frequency/(18000/256)
if int(RGB) >= 255:
   RGB = 255

        效果:黄色主要是有红和绿组成,不过实际环境中还是存在蓝色分量的

        接下来可以通过对板载的RGB灯进行控制,使其输出颜色和采集颜色保持一致,这里用的主要是NeoPixel库,这个库还是非常常见使用的,我们直接配置使用个就可以了:

import neopixel

pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
pixel.brightness = 0.3

pixel.fill((r, g, b))

        由于我们纸上画的都是比较混合,我们使用屏幕进行一下反馈,注意关闭LED辅助,屏幕本省光强就比较大:



菜鸟
2025-12-01 15:37:36     打赏
2楼

一共有几个文件?是不是class  放到lib中去?

  1. led = digitalio.DigitalInOut(board.D12)  

  2. led.direction = digitalio.Direction.OUTPUT  

  3. led.value = True  

  4.   

  5. s0_pin = digitalio.DigitalInOut(board.D5)  

  6. s1_pin = digitalio.DigitalInOut(board.D6)  

  7. s2_pin = digitalio.DigitalInOut(board.D9)  

  8. s3_pin = digitalio.DigitalInOut(board.D10) 

放到执行的文件中

程序执行过程是怎么样的?



共2条 1/1 1 跳转至

回复

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