目录
1.1.3 白平衡具体过程解析二(TCS230传感器工作方式)
1.1.3 白平衡具体过程解析三(WS2812灯珠驱动方式)
前言
看下文前,主编先问问大家,什么是颜色识别?颜色识别的本质是什么?为什么颜色识别绕不开白平衡?通过这些问题,我相信能帮助到你解决思维上的部分困惑。
一个个回答:
什么是颜色识别?:颜色传感器检测被测物体的颜色,检测结果体现在某个设备上。我们能通过这个设备,知道被测物体为什么颜色。这就是颜色识别。
颜色识别的本质是什么?:颜色传感器并不知道被测物体的颜色!!!传感器检测到的,是物体反射回的波长或光强等,关于“光的数据”。传感器会把“光的数据”转化为电信号输出。
为什么颜色识别绕不开白平衡?:我们需要知道,FPGA(或其他处理系统)并不知道什么是白色!!他只能接收来自传感器发送的被测物体的RGB值!!白平衡,则是告诉FPGA(或其他处理系统)什么是白色。从而便于我们识别其他颜色。如下图(图片来源已标出):
当FPGA理解的白色偏暖色调时,实际检测到的结果会偏冷色调,反之亦如此。
一、颜色传感器与灯珠驱动
1.1 白平衡
1.1.1 白平衡的几种方法 及 本项目使用何种方法
白平衡一般使用两种方法:(若有遗漏,请大佬们在评论区补充)
方法1.内置因子,因子不会产生变化,固定RGB值缩放。
方法2.开机或复位后白平衡,每次开机或复位后因子变化一次。
补充一:因子的意思为:RGB值缩放比例。具体的请看下文。
补充二:本项目使用 方法2
1.1.2 白平衡具体过程解析一(RGB值)
众所周知,三原色为“绿、红、蓝”。理论上所有颜色都能通过三原色的不同配比得到,由此,衍生出了“RGB值”。在显示某一颜色时,会有对应的“RGB”值被读取。
R、G、B的最大值为:255。
R、G、B的最小值为:0。
R、G、B皆为整数。
表示任何一种颜色时,都能通过R、G、B的大小知道对应颜色的配比。
如下图:
颜色 | R值 | G值 | B值 | 16进制 | |
白色 | 255 | 255 | 255 | FFFFFF | |
淡紫色 | 234 | 63 | 247 | EA3FF7 | |
纯红色 | 255 | 0 | 0 | FF0000 | |
纯绿色 | 0 | 255 | 0 | 00FF00 | |
纯蓝色 | 0 | 0 | 255 | 0000FF |
所以我们要做的,就是想方法知道被测物体的RGB值。
1.1.3 白平衡具体过程解析二(TCS230传感器工作方式)
TCS230颜色传感器共有8个引脚,大致内容如下面两张图:
引脚名字 | 接口类型(对传感器而言) | 功能介绍 | 补充 |
S0 | IN | 输出频率选择 | H为高电平,L为低电平 |
S1 | IN | 输出频率选择 | H为高电平,L为低电平 |
S2 | IN | 滤波器类型选择 | H为高电平,L为低电平 |
S3 | IN | 滤波器类型选择 | H为高电平,L为低电平 |
OUT | OUT | 占空比50%的方波脉冲输出 | 输出频率: 2Hz~500kHZ |
VCC | 电源 | 无 | |
GND | 地 | 无 | |
led | IN | 四个灯的亮灭 | 一般为悬空状态, 悬空时默认一直开灯。 |
(传感器的输入是FPGA的输出,传感器的输出是FPGA的输入) |
先从S0、S1入手。
当你的开发板为低速板时(系统时钟频率比较慢,低于500kHz或只快一点点),建议选择20%输出频率。虽然会降低效率,但更稳定,数据接收时不容易丢。
当你的开发板为高速板时(系统时钟频率远大于500kHz,主编的开发板频率为33.33MHz),建议选择100%输出频率。数据接收更快,处理也更快。
再谈S2、S3。
滤波器类型的选择也很重要,这代表着只能通过哪一种光颜色的波长。比如我们选择了红色滤波器类型,那在选中的时间段内,只有红色的光能通过滤波器,其他的光都不能通过。
这代表着,我们能只接收三原色中,我们选中的颜色的数据。这对白平衡而言,非常重要。
最后了解OUT
我们需要知道OUT的输出方式,才能知道我们要怎么接收数据。如下图:
这一小节仅为了解,具体操作请看下面的 1.2 TCS230颜色传感器驱动 章节
1.1.3 白平衡具体过程解析三(WS2812灯珠驱动方式)
首先得了解 0码 与 1码
类似于编码器,主机输入满足0码的波形,WS2812接收后编译成“0”类似于“低电平”的概念。
1码如上。
比如主机想要WS2812理解“1001_0110”,主机就需要从高位到低位的分别传输“1码、0码、0码、1码、0码、1码、1码、0码”。
补充一:0码 要求与 1码 要求已在如上图片上写出(0码要求:满足T0H、T0L。1码要求:满足T1H、T1L)
补充二:0码 与 1码 的发送周期在下面称为1码元
其次了解,怎么传输?
我们使用的WS2812灯带通常具有多个灯珠,我们想点亮n个灯珠就发送n组数据,发送结束后发送RESET码 (示意WS2812,该周期已结束)。
1组数据有24码元,每8码元为1小组,共计3个小组。3个小组从高位到低位分别属于G、R、B。如下图:
图片中的 bit 是官方为了便于理解而写的,实际上因该为 码元!!!!
1.2 TCS230颜色传感器驱动
理论上 每一个颜色的最大值应该为255。但实际中总有不可避免的客观误差,所以实际检测到的值总是低于255的。所以我们需要进行一次缩放,把检测到的白色值,缩放为255。如下图
根据 1.1.1 中的 方法2 (开机或复位后白平衡,每次开机或复位后因子变化一次。)可以延伸出如上图的两种因子计算方法。
方法1:先放一张白色不透光的卡纸(任意都行,只要不透光且是白色,但不能太光滑)在传感器1cm范围内。上电后,选通各个颜色的滤波通道,使用计数器计数方波个数从0到255所用去的时间,并存储这三个时间。
白平衡理论上就结束了,但是只检测一次很不稳定,建议1s内多次选通检测,然后取平均值。其他方法也可以,只要能更加稳定都是可以的。
方法2:先放一张白色不透光的卡纸(任意都行,只要不透光且是白色,但不能太光滑)在传感器1cm范围内。上电后,规定一个时间(主编规定的是10ms),然后依次选通各个颜色的滤波通道,在规定时间内计数方波个数。
不管方波个数是 小于255 还是 大于255,算出能使你变成255的因子(如上图),后续检测其他颜色时,乘上这个因子即可。
补充一:(方波个数可以通过 系统时钟频率 及 选中的输出频率 预估一下方波个数范围)补充二:需要注意的是,veirlog会自动消除小数,类似于只有整形数据,而没有浮点型数据。所以,当你的数据因为消除了小数而导致误差过大时,建议去学习下“定点小数”,可以有效提升数据精度。
1.3 WS2812灯珠驱动
接收来自TCS230驱动模块传输的数据,并存储。
我们可以编写一个三输入码元输出模块,它的功能是接收1bit数据,如果是0,就输出“0码”。如果是1,就输出“1码”。如果是“RST码使能信号”,就输出“RST码”
我们就只需要在“三输入码元输出模块”输出完毕后,给他输入下一位数据,直到n组数据传输完毕,打开“RST码使能信号”就完成了一次驱动。
二、颜色识别模块开发
本小节会列出模块开发思路,若要获取模块资料请联系本主编。
顶层连接:
module system_230(
sys_clk,
rst_n,
DI_TCS230,
S0,
S1,
S2,
S3,
DO_TCS2812);
input sys_clk;
input rst_n;
input DI_TCS230;
output S0;
output S1;
output S2;
output S3;
output DO_TCS2812;
wire sys_clk;
wire rst_n;
wire DI_TCS230;
wire S0;
wire S1;
wire S2;
wire S3;
wire DO_TCS2812;
wire [7:0] TCS2302_R;
wire [7:0] TCS2302_G;
wire [7:0] TCS2302_B;
TCS230 TCS2302(
.sys_clk(sys_clk),
.rst_n(rst_n),
.DI_TCS230(DI_TCS230),
.S0(S0),
.S1(S1),
.S2(S2),
.S3(S3),
.G(TCS2302_G),
.R(TCS2302_R),
.B(TCS2302_B));
WS2812 WS28122(
.clk(sys_clk),
.rst_n(rst_n),
.r(TCS2302_R),
.g(TCS2302_G),
.b(TCS2302_B),
.DO(DO_TCS2812));
endmodule
2.1 TCS230颜色传感器
下图为驱动思路:
引脚定义:
//引脚定义
input sys_clk;
input rst_n;
input DI_TCS230;
output S0;
output S1;
output S2;
output S3;
output [7:0] G;
output [7:0] R;
output [7:0] B;
wire sys_clk;
wire rst_n;
wire DI_TCS230;
reg S0;
reg S1;
reg S2;
reg S3;
reg [7:0] G;
reg [7:0] R;
reg [7:0] B;
2.2 WS2812灯珠
下图为驱动思路:
引脚定义:
//引脚定义
input clk;
input rst_n;
input [7:0] r;
input [7:0] g;
input [7:0] b;
output DO;
wire clk;
wire rst_n;
wire [7:0] r;
wire [7:0] g;
wire [7:0] b;
reg DO;
三、FPGA实战
如果烧录时出现了问题,网上有很多问题解析,我这里就不多赘述。
但我会列出如何找到问题的方法,这适用于绝大部份情况。
方法一:vivado中打ila探针。(本项目的TCS230模块适用)
方法二:编写测试文件,查看测试波形(适用于不需要从机应答的情况,比如本项目的WS2812模块就适用这种方法。而TCS230模块就不使用)