物联网开发122 - Micropython ESP32 C3连接TCS3200颜色识别传感器模块

本文介绍了如何利用ESP32C3开发板和TCS3200颜色识别传感器模块进行颜色识别。通过MicroPython编程,设置分频器、校准和读取颜色数据,并将识别的颜色显示在NeoPixel彩色LED灯上。文章提供了详细的代码示例和TCS3200驱动程序,以及黑白校准的步骤。
摘要由CSDN通过智能技术生成

一、目的

        这一节我们来学习如何使用合宙ESP32 C3,连接TCS3200颜色识别传感器模块,识别颜色。下面我们一起来学习一下吧!

二、环境

        ESP32 C3开发板(MicroPython v1.19.1 on 2022-06-18)+ TCS3200颜色识别传感器模块 + WS2812彩色灯珠模块 + 几根杜邦线 + Win10商业版

        ESP32 C3和TCS3200模块接线方法:

三、代码

example.py

from machine import Pin
from tcs3200 import TCS3200
from neopixel import NeoPixel
import time

# 创建彩色LED灯对象
npp = NeoPixel(Pin(4,Pin.OUT),64)
# 创建颜色传感器对象
tcs = TCS3200(OUT = 7,S2 = 10,S3 = 6,S0 = 2, S1 = 3,LED = 5)

# 颜色传感器初始换函数
def Tcs3200_Init():
    # 定义颜色传感器上的LED灯的状态
    tcs.led = tcs.ON
    
    '''设置分频器并且读回打印'''
    tcs.freq_divider = tcs.TWO_PERCENT
    print(tcs.freq_divider)
    # 判断获取到的分频器的值
    if tcs.freq_divider == tcs.TWO_PERCENT:
        print("Frequency divider is set to 2%")
    else:
        print("Something went wrong when setting the frequency divider")
        
    '''设置校准循环次数'''
    tcs.cycles = 100
    '''开始准备校准'''
    tcs.calibrate()
    
    '''返回黑白校准频率值'''
    print("\nBlack calibration frequency:%s"%tcs.calib(tcs.BLACK))
    print("White calibration frequency:%s"%tcs.calib(tcs.WHITE))
    
# 彩色LED灯初始化函数
def ws28l2b_Init():
    for i in range(0,64,1):
        npp[i]=(255,255//4,i*4)
        npp.write()
        time.sleep(0.1)

# 颜色函数
def Colour():
    red,green,blue,colour = tcs.rgb
    
    try:
        npp.fill((red // 8,green // 8,blue // 8))
        npp.write()
    except:
        RuntimeError
    
def main():
    ws28l2b_Init()
    Tcs3200_Init()
    
    while True:
        Colour()
        
        
if __name__ == "__main__":
    main()

演示效果:

按照提示,进行黑白校准。然后颜色识别模块对着红色纸张后,LED灯就会亮红色。对着蓝色纸张,LED灯就会亮蓝色。

四、TCS3200驱动

tcs3200.py

# tcs3200.py: a driver for the TCS3200 color sensor
#
# Copyright (c) U. Raich
# Written for the course on the Internet of Things at the
# University of Cape Coast, Ghana
# The program is released under the MIT licence

from machine import Pin,Timer
import utime as time

class TCS3200(object):
    """
    This class reads RGB values from a TCS3200 colour sensor.

    GND   Ground.
    VDD   Supply Voltage (2.7-5.5V)
    LED   1: LEDs on, 0: LEDs off
    /OE   Output enable, active low. When OE is high OUT is disabled
         allowing multiple sensors to share the same OUT line.
    OUT   Output frequency square wave.
    S0/S1 Output frequency scale selection.
    S2/S3 Colour filter selection.
    
    OUT is a square wave whose frequency is proprtional to the
    intensity of the selected filter colour.
    
    S2/S3 selects between red, green, blue, and no filter.
    
    S0/S1 scales the frequency at 100%, 20%, 2% or off.
    
    To take a reading the colour filters are selected in turn for a
    fraction of a second and the frequency is read and converted to
    Hz.

    """
    # class variables
    
    ON  = True  # on for debugging and the leds
    OFF = False # off

    RED   = (0,0) # S2 and S3 low
    BLUE  = (0,1) # S2 low, S3 high
    GREEN = (1,1) # S2 and S3 high
    CLEAR = (1,0) # S2 high and S3 low

    RED_COMP   = 0 # the color components
    GREEN_COMP = 1
    BLUE_COMP  = 2
    CLEAR_COMP = 3
    
    POWER_OFF       = (0,0) # S0 and S1 low
    TWO_PERCENT     = (0,1) # S0 low, S1 high
    TWENTY_PERCENT  = (1,0) # S0 high, S1 low
    HUNDRED_PERCENT = (1,1) # S0 and S1 high

    WHITE = True
    BLACK = False
    
    def __init__(self, OUT=None, S2=None, S3=None, S0=None, S1=None, LED=None,OE=None):
        """
        The gpios connected to the sensor OUT, S2, and S3 pins must
        be specified.  The S0, S1 (frequency) and LED and OE (output enable) 
        gpios are optional.
        The OE pin is missing on some TCS3200 boards
        """
        
        self._OUT = Pin(OUT,Pin.IN,Pin.PULL_UP)
        
        self._S2 = Pin(S2,Pin.OUT)
        self._S3 = Pin(S3,Pin.OUT)
        
        self._S0  = S0
        self._S1  = S1
        self._OE  = OE
        self._LED = LED
        
        if S0 and S1 :
            self._S0 = Pin(S0,Pin.OUT)
            self._S1 = Pin(S1,Pin.OUT)
            
        if LED :
            self._LED = Pin(LED,Pin.OUT)
            self._LED.on()
                
        if OE :
            self._OE =  Pin(OE,Pin.OUT)

        self._tim = Timer(0) # timer generating a timeout if the measurement takes to long
        self._timeout = 5000   # timeout in ms
        
        self._debug = self.OFF
        self._cycles = 100    # the number of cycles of the out signal for which the time is measured
        self._cycle = 0
        self._freq_div = self.POWER_OFF
        self._start_tick = 0
        self._end_tick = 0
        meas_finished = False
        # variables containing the calibration
        self._freq_black = [None]*4
        self._freq_white = [None]*4
        self._max_comp=255
        
    @property
    def debugging(self) :
        return self._debug
        
    @debugging.setter
    def debugging(self,onOff) :
        if onOff:
            print("Debugging switched on")
        else :
            print("Debugging switched off")
        self._debug = onOff

    # controls the illumination LEDs
    @property
    def led(self):
        # get the current state of the illumination leds
        return self._LED.value()
    
    @led.setter
    def led(self,onOff):
        if onOff:
            self._LED.on()
        else:
            self._LED.off()
            
    # sets the filters
    @property
    def filter(self):
        current_setting = (self._S2.value(),self._S3.value())
        if self._debug:
            if current_setting == self.RED:
                print("Red filter is set")
            elif current_setting == self.GREEN:
                print("Green filter is set")
            elif current_setting == self.BLUE :
                print("Blue filter is set")
            else:
                print("No filters are set. The filter setting is clear")
        return current_setting      
    
    @filter.setter
    def filter(self,filter_setting):
        if self._debug:
            print("Setting S2 to {:d} and S3 to {:d}".format(filter_setting[0],filter_setting[1]))
        self._S2.value(filter_setting[0])
        self._S3.value(filter_setting[1])

    @property
    def freq_divider(self):
        if not self._S0 or not self._S1:
            print("S0 or S1 signal is not connected. The frequency divider is therefore fixed")
            return
        current_freq_div = (self._S0.value(),self._S1.value())
        if self._debug:
            if current_freq_div == self.POWER_OFF:
                print("Device set to sleep mode")
            elif current_freq_div == self.TWO_PERCENT:
                print("Frequency divided by a factor 50")
            elif current_freq_div == self.TWENTY_PERCENT:
                print("Frequency divided by a factor 5")
            else:
                print("Frequency at 100%")

        return current_freq_div
    
    @freq_divider.setter
    def freq_divider(self,freq_div):
        if not self._S0 or not self._S1:
            print("S0 or S1 signal is not connected. The frequency divider is therefore fixed and cannot be set")
            return
        
        if self._debug:
            print("Setting S0 to {:d} and S1 to {:d}".format(freq_div[0],freq_div[1]))
        self._S0.value(freq_div[0])
        self._S1.value(freq_div[1])

    def power_off(self):
        self.freq_divider = self.POWER_OFF
        
    @property
    def cycles(self):
        return self._cycles

    @cycles.setter
    def cycles(self,no_of_cycles):
        if no_of_cycles < 1:
            print("The number of cycles must be at least 1")
            return
        self._cycles = no_of_cycles
        if self._debug:
            print("No of cycles to be measured was set to {:d}".format(self._cycles))

    @property
    def meas(self):
        if self._debug:
            if self._meas:
                print("Measurement is started")
            else:
                print("Measurement is stopped")
        return self._meas
    
    @meas.setter
    def meas(self,startStop):
        if startStop:
            self._meas = True
            self._cycle = 0
            self._start_tick = 0
            self._end_tick = 0
            if self._debug:
                print("Measurement handler started")
            self._OUT.irq(trigger=Pin.IRQ_RISING,handler=self._cbf)
            # start the timeout counter
            self._tim.init(period=self._timeout, mode=Timer.ONE_SHOT, callback=self._timeout_handler)
        else:
            self._meas=False
            self._OUT.irq(trigger=Pin.IRQ_RISING,handler=None)
            if self._debug:
                print("Measurement handler stopped")
            # disarm the timeout
            self._tim.deinit()
            
    def calib(self,black_or_white):
        if black_or_white == self.BLACK:
            return self._freq_black
        else:
            return self._freq_white

    @property
    # measure the frequencies for the 3 rgb color componenent and for the clear filter
    def meas_freqs(self):
        filter_settings = (self.RED,self.GREEN,self.BLUE,self.CLEAR)
        freqs = [None]*4

        for i in range(self.CLEAR_COMP+1):
            # set the filter
            self.filter = filter_settings[i]
            self.meas = self.ON       # start the measurement
            while self._end_tick == 0:
                time.sleep_ms(10)
            freqs[i] = self.measured_freq
            
        return freqs
    
    def calibrate(self):
        print("\nBlack calibration preparation!")
        self.wait_for_return()
        self._freq_black = self.meas_freqs
        print("\nWhite calibration preparation!")
        self.wait_for_return()
        self._freq_white = self.meas_freqs

    def wait_for_return(self):
        
        for i in range(10,-1,-1):
            time.sleep(0.5)
            print("count backwards: %.2d 秒"%(i))
            
            #return i
        
    @property
    def timeout(self):
        return self._timeout

    @timeout.setter
    def timeout(self,timeout_ms):
        self._timeout = timeout_ms
    
    @property
    def measured_freq(self):
        duration = self._end_tick - self._start_tick  # measurement duration
        frequency = 1000000 * self._cycles/duration   # duration is measured in us
        return frequency
    
    def calc_rgb_comp(self,comp,freq):
        return  (freq - self._freq_black[comp]) / (self._freq_white[comp] - self._freq_black[comp])

    @property
    # gets the maximum value for a color component
    def max_comp(self):
        return self._max_comp
    
    @max_comp.setter
    # sets the maximum value for a color component
    def max_comp(self,value):
        self._max_comp = value
        
    @property
    # Measure the rgb values as well as the intensity value (no filter)
    def rgb(self):
        if not self._freq_black[0] or not  self._freq_white[0]:
            print("Missing calibration. Please calibrate the device before attempting to measure colored targets")
            return

        freqs = self.meas_freqs
        if self._debug:
            print("Measured Frequencies: red: {:f}, green: {:f}, blue: {:f}, intensity: {:f}".format(
                freqs[0],freqs[1],freqs[2],freqs[3]))
        argb = [None]*4
        for i in range(4):
            argb[i]=int(self._max_comp*self.calc_rgb_comp(i,freqs[i]))
            if argb[i] < 0:
                argb[i] = 0
        if self._debug:
            print("rgb array:",argb)
        return argb
                        
        
    # This is the callback function that measures the time taken by a predefined no of cycles of the out signal
    def _cbf(self,src):
        t = time.ticks_us()
        if self._cycle == 0:
            self._start_tick = t
        if self._cycle >= self._cycles: # the number of cycles has been reached
            self._end_tick = t
            self.meas=self.OFF
            return
        self._cycle += 1
        
    # The timeout handler raises a timeout exception
    def _timeout_handler(self,src):
        # stop the measurement
        self._OUT.irq(trigger=Pin.IRQ_RISING,handler=None)
        # raise the timeour exception
        raise Exception("Measurement Timeout!")
    
    # callback to stop data taking 
    def setStopFlag(self,t):
        self.stopFlag=True
        
    # This is a test function that reads the OUT signal for 100 ms at a sampling frequency of 10 samples per ms
    # It prints the current state of the OUT signal such that you can plot the signal
    def testOut(self):
        self.values = []
        self.stopFlag = False
        # start a timer for 100 ms
        self._tim.init(period=100, mode=Timer.ONE_SHOT, callback=self.setStopFlag)
        while not self.stopFlag:
            self.values.append(self._OUT.value())
            time.sleep_us(100)
        return self.values

五、TCS3200颜色传感器模块购买

https://detail.tmall.com/item.htm?_u=bp01rch420a&id=41332889169&skuId=4391165763828&spm=a1z09.2.0.0.2df52e8doCoFgQicon-default.png?t=N6B9https://detail.tmall.com/item.htm?_u=bp01rch420a&id=41332889169&skuId=4391165763828&spm=a1z09.2.0.0.2df52e8doCoFgQ

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔都飘雪

您的1毛奖励是我创作的源源动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值