2024寒假练—基于十二指神探实现颜色识别及校准
该项目使用了Micropython语言、Thonny软件,实现了基于十二指神探的颜色识别系统的设计,它的主要功能为:进行白平衡校准和颜色识别,在LCD屏上显示识别颜色的基本信息和颜色相近的色块。
标签
嵌入式系统
树莓派RP2040
十二指神探
2024寒假练
echu
更新2024-03-29
119

1 项目要求

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

2 完成的功能介绍

2.1 LCD驱动

屏上可显示识别颜色的信息、与识别颜色大致相近的色块。如图,是初始界面。

image.png

2.2 白平衡校准

按下左边按键可开始白平衡校准,使用白色物体放在传感器前,以此减少光线对颜色识别的影响。

image.png

校准结果

image.png

2.3 颜色识别

按下右边按键可进行颜色识别,传感器获取RGB分量,RP2040对这些分量进行分析和合成,显示在LCD上。本项目可识别6种颜色,分别是白、橙、绿、蓝、黄、红,使用一个魔方来进行验证。以下是例子。

image.pngimage.pngimage.png

image.pngimage.pngimage.png

3 整体思路

整个项目可以分成以下几部分:

  • PR2040通过SPI驱动​LCD
  • PR2040通过IIC驱动颜色传感器LTR-381RGB-01
  • 按键中断事件设置

软硬件流程图

image.png

4 实现过程

4.1 LCD驱动

为实现SPI驱动LCD并显示信息,项目参考了B站王铭东老师的教程,在反复调试后发现在教程的基础上需要再加上一句对SPI的配置

SPI(id=0, baudrate=40_000_000, polarity=0, phase=0, sck=Pin(2,Pin.OUT), mosi=Pin(3,Pin.OUT), bits=8, firstbit=SPI.MSB)

​在这之后即可采用st7789py库进行驱动

4.2 颜色传感器的驱动

本项目​用IIC通信实现PR2040与LTR381之间的沟通,首先要配置IIC引脚信息

i2c = machine.I2C(0,scl=machine.Pin(21),sda=machine.Pin(20),freq=400000)

之后根据数据手册对LTR381进行配置,设置分辨率为16bits、增益为18、模式为CS模式(RGB通道均激活),并编写颜色信息读取函数

def read_color(self):
#读颜色
data_g_0=self.reg_read(self.i2c,LTR381_ADDR,REG_CS_DATA_GREEN_0)
data_g_1=self.reg_read(self.i2c,LTR381_ADDR,REG_CS_DATA_GREEN_1)
data_g_2=self.reg_read(self.i2c,LTR381_ADDR,REG_CS_DATA_GREEN_2)
data_g=int.from_bytes(data_g_0+data_g_1+data_g_2,'little')

data_b_0=self.reg_read(self.i2c,LTR381_ADDR,REG_CS_DATA_BLUE_0)
data_b_1=self.reg_read(self.i2c,LTR381_ADDR,REG_CS_DATA_BLUE_1)
data_b_2=self.reg_read(self.i2c,LTR381_ADDR,REG_CS_DATA_BLUE_2)
data_b=int.from_bytes(data_b_0+data_b_1+data_b_2,'little')

data_r_0=self.reg_read(self.i2c,LTR381_ADDR,REG_CS_DATA_RED_0)
data_r_1=self.reg_read(self.i2c,LTR381_ADDR,REG_CS_DATA_RED_1)
data_r_2=self.reg_read(self.i2c,LTR381_ADDR,REG_CS_DATA_RED_2)
data_r=int.from_bytes(data_r_0+data_r_1+data_r_2,'little')

data_r=int(data_r/self.gain)
data_g=int(data_g/self.gain)
data_b=int(data_b/self.gain)

return data_r,data_g,data_b

4.3 按键中断事件设置

本项目中,左键控制白平衡校准,即通过识别一次白色物体,校正光源带色对颜色识别造成的影响。

def calibrate_button_handler(pin):
tft.fill(0)
tft.text(font, "calibrating", 30, 100, st7789py.color565(255, 0, 0), st7789py.color565(0, 0, 0))
global max_r,max_g,max_b
for i in range(3):
sleep_ms(3000)
r,g,b=color.read_color()
max_r=(max_r+r)/2
max_g=(max_g+g)/2
max_b=(max_b+b)/2
print(max_r,max_g,max_b)
tft.fill(0)
tft.text(font, "ok", 100, 100, st7789py.color565(255, 0, 0), st7789py.color565(0, 0, 0))

按下左边按键后,需将白色物体一直固定在传感器附近,直到屏幕显示"ok"。传感器采集三次白色物体RGB分量并取平均值。

​右键控制颜色识别,传感器读取RGB分量后,与上述获得的值做比例并转化为0~255的RGB分量,合成色块显示在LCD上,并根据RGB分量占比辨认颜色。

def color_button_handler(pin):
global max_r,max_g,max_b,cnt
sleep_ms(1000)
r,g,b=color.read_color()
h,s,v=i2c_ltr381.rgb2hsv(r,g,b)
r,g,b=[int(r/max_r*255),int(g/max_g*255),int(b/max_b*255)]
r,g,b=[min(r,255),min(g,255),min(b,255)]
c=color_define(r,g,b)
rgb=str(r)+" "+str(g)+" "+str(b)
#屏幕显示
tft.fill(0)
tft.text(font, "r", 40, 20, st7789py.color565(255, 0, 0), st7789py.color565(0, 0, 0))
tft.text(font, "g", 104, 20, st7789py.color565(0, 255, 0), st7789py.color565(0, 0, 0))
tft.text(font, "b", 168, 20, st7789py.color565(0, 0, 255), st7789py.color565(0, 0, 0))
tft.text(font, str(r), 40, 60, st7789py.color565(255, 0, 0), st7789py.color565(0, 0, 0))
tft.text(font, str(g), 104, 60, st7789py.color565(0, 255, 0), st7789py.color565(0, 0, 0))
tft.text(font, str(b), 168, 60, st7789py.color565(0, 0, 255), st7789py.color565(0, 0, 0))
tft.fill_rect(80,110,80,80,st7789py.color565(r,g,b))
if len(c)>6:
tft.text(font, c, 30, 200, st7789py.color565(255, 255, 255), st7789py.color565(0, 0, 0))
else:
tft.text(font, c, 80, 200, st7789py.color565(255, 255, 255), st7789py.color565(0, 0, 0))

5 困难和还可以优化的问题

  • ​对红色的识别较差,可以再优化识别算法。
  • 本项目中的光源用了手机手电筒,可以在板子上加焊一个LED灯,更方便,结果也能更准确。
附件下载
项目代码.zip
团队介绍
生物医学工程 大四
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号