✔零知派(零知开源)是一个专为电子初学者/电子兴趣爱好者设计的开源软硬件平台,在硬件上提供超高性价比STM32系列开发板、物联网控制板。取消了Bootloader程序烧录,让开发重心从 "配置环境" 转移到 "创意实现",极大降低了技术门槛。零知开源编程软件,内置上千个覆盖多场景的示例代码,支持项目源码一键下载,项目文章在线浏览。零知派(零知开源)平台通过软硬件协同创新,让你的创意快速转化为实物,来动手试试吧!
✔访问零知实验室,获取更多实战项目和教程资源吧!
(1)项目概述
本项目基于零知派ESP32主控板、TCS3200颜色传感器和TFT显示屏,构建了一套高精度颜色识别系统。系统能够实时检测物体表面的RGB颜色值,在屏幕上以直观的UI界面展示检测结果,并输出标准的HEX颜色代码,适用于颜色分拣、智能照明、色差检测等应用场景。
(2)项目亮点
-
高精度颜色检测:采用多次采样取平均值算法,有效降低环境光干扰
-
双模式校准系统:支持黑白色标定,适应不同光照环境
-
直观的图形界面:实时显示RGB数值、HEX代码及颜色色块
-
一键式操作:独立按键触发检测,校准开关便捷切换
-
串口调试输出:实时输出检测数据,便于二次开发和调试
(3)项目难点及解决方案
| 难点 | 解决方案 |
|---|---|
| TCS3200输出频率受环境光影响大 | 增加黑/白双点校准机制,建立线性映射关系 |
| 颜色检测存在抖动 | 5次采样取平均,增加50ms采样间隔 |
| 传感器原始值与实际RGB值呈反比 | 在rgbToRGB565函数中进行取反处理 |
| 按钮/开关信号抖动 | 软件消抖延迟+状态确认双重处理 |
目录
[1.1 硬件清单](#1.1 硬件清单)
[1.2 接线方案](#1.2 接线方案)
[1.3 硬件连接图](#1.3 硬件连接图)
[2.1 系统初始化](#2.1 系统初始化)
[2.2 主循环逻辑](#2.2 主循环逻辑)
[2.3 颜色检测算法](#2.3 颜色检测算法)
[2.4 系统校准](#2.4 系统校准)
[2.5 颜色数据采集](#2.5 颜色数据采集)
[3.1 引脚定义与常量](#3.1 引脚定义与常量)
[3.2 RGB转RGB565(关键函数)](#3.2 RGB转RGB565(关键函数))
[3.3 UI绘制函数](#3.3 UI绘制函数)
[3.4 完整代码结构](#3.4 完整代码结构)
[4.1 硬件连接](#4.1 硬件连接)
[4.2 上传程序](#4.2 上传程序)
[4.3 系统校准](#4.3 系统校准)
[4.4 颜色检测](#4.4 颜色检测)
[4.5 数据输出](#4.5 数据输出)
[4.6 演示视频](#4.6 演示视频)
[5.1 工作原理](#5.1 工作原理)
[5.2 工作模式配置](#5.2 工作模式配置)
[Q1: 颜色显示部分输出的颜色对不上RGB值和HEX值](#Q1: 颜色显示部分输出的颜色对不上RGB值和HEX值)
一、硬件系统部分
1.1 硬件清单
| 组件 | 型号 | 数量 |
|---|---|---|
| 主控板 | 零知派ESP32 | 1 |
| 扩展板 | 零知派ESP32扩展板 | 1 |
| TFT显示屏 | ST7789 (240x240) | 1 |
| 颜色传感器 | TCS3200模块 | 1 |
| 杜邦线 | 母对母 | 若干 |
1.2 接线方案
把零知派ESP32和TFT显示屏插在零知ESP32扩展板对应的位置上。
TCS3200与零知派ESP32扩展板连接:
| TCS3200引脚 | 零知派ESP32扩展板引脚 | 说明 |
|---|---|---|
| VCC | 3.3V | 电源 |
| GND | GND | 地 |
| S0 | GPIO19 | 频率缩放控制 |
| S1 | GPIO21 | 频率缩放控制 |
| S2 | GPIO16 | 滤波器选择 |
| S3 | GPIO17 | 滤波器选择 |
| OUT | GPIO22 | 频率输出信号 |
| OE | GND | 使能(接地常开) |
1.3 硬件连接图

二、软件架构设计
2.1 系统初始化
void setup() {
Serial.begin(115200); // 串口初始化
tft.begin(); // 显示屏初始化
tft.setRotation(3); // 横屏模式
drawUI(); // 绘制静态界面
// 引脚模式配置
pinMode(S0, OUTPUT); pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT); pinMode(S3, OUTPUT);
pinMode(OUT_PIN, INPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(CAL_SWITCH_PIN, INPUT_PULLUP);
// TCS3200 频率设置为100%
digitalWrite(S0, HIGH);
digitalWrite(S1, HIGH);
}
2.2 主循环逻辑
void loop() {
// 1. 检测校准开关下降沿
if (下降沿触发) calibrate();
// 2. 检测按钮按下
if (按钮按下) detectColor();
delay(100); // 避免过度占用CPU
}
2.3 颜色检测算法
TCS3200通过不同滤波器组合输出对应颜色的频率信号。基本原理:
-
频率越高 = 该颜色分量越强
-
但传感器输出与RGB值呈反比关系
void readColor() {
// 红色: S2=LOW, S3=LOW
digitalWrite(S2, LOW); digitalWrite(S3, LOW);
red = pulseIn(OUT_PIN, LOW, 10000);// 蓝色: S2=LOW, S3=HIGH digitalWrite(S2, LOW); digitalWrite(S3, HIGH); blue = pulseIn(OUT_PIN, LOW, 10000); // 绿色: S2=HIGH, S3=HIGH digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); green = pulseIn(OUT_PIN, LOW, 10000);}
2.4 系统校准
校准流程:黑色标定 → 白色标定
黑色标定(最大值) 白色标定(最小值)
↓ ↓
cal_max_r/g/b ←── 映射 ──→ cal_min_r/g/b
映射公式:
output = 255 - map(raw_value, cal_min, cal_max, 0, 255)
校准代码核心:
// 黑色校准 - 记录最大值
cal_max_r = max(cal_max_r, red);
// 白色校准 - 记录最小值
cal_min_r = min(cal_min_r, red);
2.5 颜色数据采集
为提高稳定性,采用5次采样取平均:
for (int i = 0; i < 5; i++) {
readColor();
r_sum += red;
g_sum += green;
b_sum += blue;
delay(50);
}
red = r_sum / 5;
green = g_sum / 5;
blue = b_sum / 5;
三、代码拆分讲解
3.1 引脚定义与常量
// 传感器引脚
#define S0 19, S1 21, S2 16, S3 17, OUT_PIN 22
#define BUTTON_PIN 12 // 检测按钮(低电平有效)
#define CAL_SWITCH_PIN 27 // 校准开关(下降沿触发)
// UI颜色(RGB565格式)
#define BACKGROUND 0x2104 // 深灰色
#define HIGHLIGHT 0x07FF // 青色
#define WARNING_COLOR 0xF800 // 红色
#define SUCCESS_COLOR 0x07E0 // 绿色
3.2 RGB转RGB565(关键函数)
uint16_t rgbToRGB565(uint8_t r, uint8_t g, uint8_t b) {
// 取反!因为TCS3200输出与RGB值成反比
r = 255 - r;
g = 255 - g;
b = 255 - b;
// RGB888 → RGB565
return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
}
3.3 UI绘制函数
void drawUI() {
tft.fillScreen(BACKGROUND);
// 标题
tft.setTextColor(HIGHLIGHT);
tft.setCursor(20, 15);
tft.print("COLOR SENSOR");
// 信息面板
tft.fillRoundRect(0, 55, 1000, 265, 0, PANEL_COLOR);
// RGB标签
tft.setCursor(MARGIN + 10, 75); tft.print("RED:");
tft.setCursor(MARGIN + 10, 105); tft.print("GREEN:");
tft.setCursor(MARGIN + 10, 135); tft.print("BLUE:");
tft.setCursor(MARGIN + 10, 165); tft.print("HEX:");
// 校准按钮区域
tft.fillRoundRect(MARGIN + 10, 230, 110, 40, 5, HIGHLIGHT);
tft.setCursor(MARGIN + 32, 244);
tft.print("CALIBRATE");
// 颜色显示框
tft.fillRoundRect(SCREEN_WIDTH - COLOR_BOX_SIZE, 70,
COLOR_BOX_SIZE, COLOR_BOX_SIZE, 10, defaultColor);
}
3.4 完整代码结构
// === 头文件与定义 ===
#include <TFT_eSPI.h>
#define ...引脚定义...
// === 全局变量 ===
int red, green, blue;
int cal_min_r, cal_min_g, cal_min_b; // 白色校准值
int cal_max_r, cal_max_g, cal_max_b; // 黑色校准值
bool calibrated;
// === 函数声明 ===
void setup();
void loop();
void drawUI();
void readColor();
void detectColor();
void calibrate();
void updateDisplay();
void showMessage(const char* msg, uint16_t color);
uint16_t rgbToRGB565(uint8_t r, uint8_t g, uint8_t b);
// === 函数实现(按上述讲解) ===
四、操作过程及数据展示
4.1 硬件连接
-
将ESP32插到扩展板对应位置
-
把ST7789显示屏插到扩展板对应位置
-
将TCS3200连接至扩展板指定引脚
-
通过USB线给ESP32供电
4.2 上传程序
-
零知派 > 开源平台 > 搜索"零知派ESP32------TCS3200高精度RGB颜色识别系统教程" > 代码下载
-
选择开发板:零知-ESP32
-
编译并上传代码

4.3 系统校准
-
按下27 按钮,进入校准模式
-
按下12 按钮,进入检测模式 ,对准黑色物体,读取黑色值,等待进度条
-
按下12 按钮,进入检测模式 ,对准白色物体,读取白色值,等待进度条
-
显示"Cal Success!"表示校准完成
4.4 颜色检测
-
将传感器对准待测物体(距离约1-2cm)
-
按下检测按钮
-
屏幕显示:
RGB数值(0-255)
HEX颜色代码(如#FF8040)
颜色色块实时更新
4.5 数据输出
打开串口监视器(115200波特率),可看到:

4.6 演示视频
零知派ESP32------TCS3200高精度RGB颜色识别系统教
五、TCS230技术原理
5.1 工作原理
TCS3200是一款可编程彩色光频率转换器,内部集成:
-
光电二极管阵列:16组×4种滤波器(红、绿、蓝、全透)
-
电流频率转换器:将光电流转换为方波信号
-
输出使能控制:S0/S1控制输出频率缩放比例
5.2 工作模式配置
- 频率缩放(S0/S1):
| S0 | S1 | 输出频率缩放 |
|---|---|---|
| LOW | LOW | 断电模式 |
| LOW | HIGH | 2% |
| HIGH | LOW | 20% |
| HIGH | HIGH | 100% |
本程序使用 100% 模式以获得最佳灵敏度。
- 滤波器选择(S2/S3):
| S2 | S3 | 滤波器类型 |
|---|---|---|
| LOW | LOW | 红色 |
| LOW | HIGH | 蓝色 |
| HIGH | LOW | 无(全透) |
| HIGH | HIGH | 绿色 |
六、常见问题指引
Q1: 颜色显示部分输出的颜色对不上RGB值和HEX值
问题现象:检测红色物体,屏幕显示蓝色;或RGB数值与预期偏差大。
可能原因与解决方案:
| 原因 | 解决方案 |
|---|---|
| 未校准 | 执行完整的黑白校准流程,确保校准成功 |
| 校准顺序错误 | 必须先黑后白,不可颠倒 |
| 传感器距离不当 | 保持1-2cm检测距离,避免环境光干扰 |
| 接线错误 | 检查S2/S3引脚是否接反(红蓝通道互换) |
| 光源影响 | 使用LED补光或做遮光处理 |
快速排查步骤:
-
重新执行校准(确保黑色物体足够黑,白色物体为纯白)
-
打开串口监视器,观察原始值:
-
检测红色:原始值中红色应最小(频率最高)
-
如果红色原始值反而最大,检查S2/S3接线
-
-
确认rgbToRGB565中的取反逻辑正确
调试代码(添加到detectColor中):
Serial.print("Raw - R:"); Serial.print(red);
Serial.print(" G:"); Serial.print(green);
Serial.print(" B:"); Serial.println(blue);
Q2:屏幕无显示
**问题现象:**屏幕上电后没有任何显示(全黑或背光不亮);或者屏幕亮但不显示任何文字/图形
**解决方案:**检查ST7789接线,确认TFT_eSPI库引脚配置正确
Q3:按键无反应
**问题现象:**按下检测按钮后,屏幕没有"Detecting..."提示;或者颜色检测功能不触发
**解决方案:**检查是否启用INPUT_PULLUP,测量引脚电平
Q3:颜色检测卡顿
**问题现象:**按下按钮后,屏幕反应慢(超过1秒才显示结果);或者多次按下后有延迟累积
**解决方案:**减少主循环delay,或降低采样次数
Q4:校准超时
30秒内未按按钮会自动取消,重新触发校准
Q5:串口无输出
确认波特率115200,检查USB线数据功能
项目资源整合