1 前言
本章测试色彩识别传感器TCS34725。
模块官网介绍及代码:https://doc.openluat.com/wiki/21?wiki_page_id=2746
参考文章:STM32读取TCS34725源代码,RGB转HSL代码,已通过实际测试
2 色彩介绍
以下是结合部分资料整合的个人理解,如果有错误欢迎指正。
2.1 传感器数据
传感器获取的数值为RGBC,其中的c表示clear,即所有色彩都通过。其他的三个就是红绿蓝三色。
原理大概是有传感器加上了红、绿、蓝三个偏光板,然后获取三个颜色的强度,然后clear就是不加,直接获取全部色彩。
最终传感器得到四个数值,R,G,B,C
根据参考文章的理解,使用R/G/B三色数据除以C得到一个比值。
这个比值再乘以255得到确定数值,也就是255:255:255的色彩数据格式。
2.2 lcd屏幕数据
我使用的是合宙的st7735驱动的lcd屏幕
下图为介绍。
其中提到色彩为16位。
16位分为5:6:5,由于对于绿色较为敏感,所以绿色位6位,这样绿色的数值范围就大一倍,分的更细致。
16位高5位为红色,低5位为蓝色,中间的6位为绿色。
我们可以尝试在lcd上显示如下代码,其中2048,32,1表示的偏移,二进制转换分别是右移11位,右移6位,不右移。
lcd.fill(0,129,128,160,0xFFFF) --白色
-- 显示蓝色
R,G,B = 0,0,31
temp_rgb16 = R* 2048+G* 32+B * 1
lcd.fill(0,129,128,160,temp_rgb16 )
-- 显示绿色
R,G,B = 0,61,0
temp_rgb16 = R* 2048+G* 32+B * 1
lcd.fill(0,129,128,160,temp_rgb16 )
-- 显示红色
R,G,B = 31,0,0
temp_rgb16 = R* 2048+G* 32+B * 1
lcd.fill(0,129,128,160,temp_rgb16 )
至此我们可以把色彩对应到lcd屏幕上。
获取到传感器的原始数据rgb
然后除以c得到比例
再乘以31,61,31,得到16位真彩色的实际数值
使用lcd显示对应的色彩
3 硬件连接
由于改传感器也是i2c,所以连线相同。
只连接红色的这三个引脚就可以正常工作了,其他三个后续有空再看。
4 代码
-- main.lua
PROJECT = "sensor"
VERSION = "1.0.0"
-- require "log"
-- require "sys"
-- require "misc"
local sys = require("sys")
require("sen_TCS34725")
-- i2c ID
i2cid = 2
-- i2c 速率
speed = 100000
sys.taskInit(function()
sys.wait(3000)
TCS34725_init(i2cid,0x29,speed) -- TCS34725地址默认为0x29
while true do
TCS34725_get()
sys.wait(1000)
end
end)
sys.init(0, 0)
sys.run()
--sen_TCS34725.lua
-- 色彩传感器
-- 初始化spi
function TCS34725_init_spi(t_spi_id,t_addr,t_speed)
if i2c.setup(t_spi_id, t_speed, -1, 1) ~= t_speed then
log.error("i2c", "setup fail", addr_TCS34725)
return
end
addr_TCS34725 = t_addr
end
-- 读取数据
function TCS34725_send(...)
sys.wait(10)
if not addr_TCS34725 then
log.info("i2c", "addr_TCS34725 err")
return
end
local t = {...}
if i2c.send(i2cid, addr_TCS34725, t) ~= #t then
log.error("i2c", "send fail", #t)
return
end
return true
end
-- 发送数据
function TCS34725_read(n)
sys.wait(10)
if not addr_TCS34725 then
log.info("i2c", "addr_TCS34725 err")
return "\x00"
end
val = i2c.recv(i2cid, addr_TCS34725, n)
if val and #val>0 then
return val
end
return "\x00"
end
-- 初始化
function TCS34725_init(t_spi_id,addr,t_speed)
TCS34725_init_spi(t_spi_id,0x29,t_speed) -- addr默认为0x29
TCS34725_send(0x83, 0xff)
TCS34725_send(0x81, 0x00)
TCS34725_send(0x8f, 0x00)
TCS34725_send(0x80, 0x03)
end
-- 颜色识别传感器
function TCS34725_get()
-- 发送命令
TCS34725_send(0x94)
-- 接收数据
_, c, red, green, blue = pack.unpack(TCS34725_read(8), "<HHHH")
-- 判定结果
if red and green and blue then
lux = (-0.32466 * red) + (1.57837 * green) + (-0.73191 * blue)
log.info("red", red)
log.info("green", green)
log.info("blue", blue)
log.info("c, lux", c, lux)
else
log.info("TCS34725", "err")
end
return lux
end
5 结果
当然,由于色彩信息阈值为0-31、61,所以他们的数值变化对实际效果显示的较大,不够精细,如果是24位(8,8,8),实际效果会更好。
目前测试的话针对红绿蓝三色效果最好,其他的颜色通过lcd显示和人眼看到的偏差较大。