2024年寒假练 - 用带屏12指神探和传感器扩展板完成颜色识别及校准功能
该项目使用了带屏12指神探的传感器扩展板、MicroPython语言,实现了颜色识别及校准功能的设计,它的主要功能为:读出颜色传感器的数据,在LCD上显示当前识别的颜色信息,用色块显示识别的颜色。
标签
MicroPython
RP2040
颜色识别
参加活动
带屏12指神探
TetraPak
更新2024-03-29
184

项目背景

功能介绍

任务描述

  • 可识别至少五种颜色
  • 可在LCD上显示基本信息如当前识别颜色
  • 可在LCD上用色块显示识别的颜色并大致接近


硬件介绍

十二指神探引脚接口

颜色传感器

LTR-381RGB-01传感器内部集成了环境光传感器 (ALS) 和颜色传感器 (CS) ,可将光线(红、绿、蓝和红外)强度转换为数字输出信号。

设计思路

主要困难

此小节主要分析功能需求,实现该项目会面临的困难。

从任务描述中可以看出,实现该任务有两个核心功能:

  1. 获取颜色数据,所以需求是确定通信协议,读取传感器数据。
  2. LCD展示颜色,所以需求是确定通信协议,驱动LCD,绘制颜色文本信息和颜色色块。

解决思路

此小节针对面临的困难,提出解决方案(拟使用的传感器及通信协议)。

核心功能一

主要使用传感器:接近传感器、颜色传感器(LTR-381RGB-01)。

打开传感器扩展板的原理图,查阅颜色传感器与带屏12指神探的连接图。


可以看到,颜色传感器的通信方式是IIC,其中I2C0_SDA连接到IO20I2C0_SCL连接到IO21

在micropython中,类machine.I2C用于配置iic外设连接引脚,故实例化该类,使用类提供的方法编写颜色传感器的驱动。

  1. 基础功能

阅读颜色传感器数据手册的Principle of Operation章节,其支持两种读协议和两种写协议,故使用类库提供的I2C.writeto、I2C.writeto_mem、I2C.readfrom方法来驱动。

  1. 配置传感器

阅读Register Set章节,首先配置传感器功能,设置传感器内部寄存器的值。这里设置3个寄存器:MAIN_CTRL Register、ALS_CS_MEAS_RATE Register和ALS_CS_GAIN Register,分别用于使能传感器,测量分辨率、测量速率,增益。

  1. 获取颜色

其次在获取颜色测量值时,需要分别读取R、G、B数据寄存器。

  1. 白平衡校准

根据实际的光照环境,将白色光置于传感器上方,使其当前RGB三个通道的ADC值除以255得到3个比例因子,从而使得任意颜色的RGB值按比例因子缩放到0-255区间内。为了方便起见,会将比例因子存入文件,放到设备中,以便下次运行时直接读取,避免相同光环境下重复校准。

除此之外,还需配置重置功能,将缩放因子置为1(即不缩放),以凸显白平衡校准的有效性。

白平衡校准和重置功能通过按键触发。



核心功能二

驱动屏幕,例程已经写好st7789的驱动程序,不做赘述。

但仍需实现绘制颜色文本信息和颜色色块的功能。这两个功能d1实现,修改例程中'display.text()'和'display.fll()'这两个方法即可。

  1. 绘制颜色文本信息

拟展示当前校准比例因子,传感器ADC实测值,颜色rgb值。

  1. 绘制颜色色块

ST7789使用RGB565编码来表示颜色,在RGB565编码中:

    • 红色占 5 位,最大值为 0xF800(十六进制)。
    • 绿色占 6 位,最大值为 0x07E0(十六进制)。
    • 蓝色占 5 位,最大值为 0x001F(十六进制)。

所以需要将范围在0-255的RGB编码分别转换为RGB565编码,再显示颜色色块。


软件流程图

此小节主要描述解决方案的软件实现,提出实现项目功能的技术路线。


功能展示

核心代码片段及说明

配置传感器

def __init__(self):
...
self._i2cwrite(_ALS_CS_MEAS_RATE, 0x22) # default ALS/CS Resolution: 18 Bit, Conversion time = 100ms, ALS/CS Measurement Rate: 100ms
self._i2cwrite(_ALS_CS_GAIN, 0x01)  # ALS/CS Gain Range, Gain Range: 3 (default)
self._i2cwrite(_MAIN_CTRL, 0x06) # 0x06 ALS active, CS mode
...


获取颜色ADC值

... 
def red(self):
        Rlsb = self._i2cread(_DATA_RED_0)
        Rnorm = self._i2cread(_DATA_RED_1)
        Rmsb = self._i2cread(_DATA_RED_2)
        return (Rmsb << 16) | (Rnorm << 8) | Rlsb

    def blue(self):
        Blsb = self._i2cread(_DATA_BLUE_0)
        Bnorm = self._i2cread(_DATA_BLUE_1)
        Bmsb = self._i2cread(_DATA_BLUE_2)
        return (Bmsb << 16) | (Bnorm << 8) | Blsb

    def green(self):
        Glsb = self._i2cread(_DATA_GREEN_0)
        Gnorm = self._i2cread(_DATA_GREEN_1)
        Gmsb = self._i2cread(_DATA_GREEN_2)
        return (Gmsb << 16) | (Gnorm << 8) | Glsb
...


白平衡校准及重置

		if buttonValueS == 0:  # 开始白平衡校准
        print("start white balance calibration...")
        time.sleep_ms(5)
        r = sensor.red()
        time.sleep_ms(5)
        g = sensor.green()
        time.sleep_ms(5)
        b = sensor.blue()
        sensor.R_factor = 255 / r
        sensor.G_factor = 255 / g
        sensor.B_factor = 255 / b
        sensor.write_file(sensor.R_factor, sensor.G_factor, sensor.B_factor)
        print("R_factor = {}, G_factor = {}, B_factor = {}".format(sensor.R_factor, sensor.G_factor, sensor.B_factor))
        display.text(font1, "Calibrating", 10, 160)

    elif buttonValueM == 0: # 重置
        sensor.R_factor = 1.00
        sensor.G_factor = 1.00
        sensor.B_factor = 1.00
        display.text(font1, "Restore", 10, 160)


读写颜色校准配置文件

... 
def write_file(self, *factors):
        combined_floats = ','.join(map(str, factors))
        with open('color_factor.txt', 'w') as f:
            f.write(combined_floats)

    def _read_file(self):
        try:
            with open('color_factor.txt', 'r') as file:
                data_read = file.read()
            print("loading...success")
            return list(map(float, data_read.split(',')))
        except OSError:
            print("loading...fail")
            return (1.00, 1.00, 1.00)
...


将标准RGB编码转换为RGB565编码

		def convert_rgb565(red, green, blue):
        red = int(red / 255 * _ST7789_R)
        green = int(green / 255 * _ST7789_G)
        blue = int(blue / 255 * _ST7789_B)

        red = max(0, min(red, _ST7789_R))
        green = max(0, min(green, _ST7789_G))
        blue = max(0, min(blue, _ST7789_B))

        res_rgb565 = (red << 11) + (green << 5) + blue
        return res_rgb565


在LCD上展示颜色文本信息和色块

display.text(font2, "#%02X%02X%02X" % (r, g, b), 10, 200)
display.fill_rect(150, 180, 50, 50, display_sensor_color)

实现效果

OLED的显示布局效果如下图所示。


屏幕中显示了以下关键信息

  1. 电子森林的网址
  2. RGB各个颜色分量的经过白平衡校准后的缩放比例
  3. 颜色传感器读取到的RGB各个颜色分量的ADC大小
  4. 十六进制的颜色表示
  5. 当前识别颜色的可视化正方形显示色块

共实现了10种颜色的识别,具体测试效果可观看演示视频。

总结

本项目依托12指神探和传感器扩展板平台,完成白平衡校准功能及颜色识别功能。在此过程中阅读传感器数据手册和平台驱动代码,学习白平衡校准原理和颜色传感器的驱动方法,最终顺利完成任务。

附件下载
color_code.zip
micropython设备代码
团队介绍
电子爱好者
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号