基础任务一:
实现颜色传感器驱动,按键获取当前颜色数据并可以通过串口或屏幕进行打印;
这个任务我们拆解一下就是我们要学习:
开发板按键使用与TCS3200颜色识别
板载按键功能与使用说明
在第20-22页有专门介绍D1、D2和D0按钮的章节。板子上有三个用户按钮:D0、D1和D2。
D0按钮具有双重功能:既可作为BOOT按钮进入ROM引导加载程序,也可在代码中作为输入使用。
在CircuitPython中,可通过 board.D0、board.BOOT0 和 board.BUTTON 访问;在Arduino中为引脚0。
默认为上拉高电平,按下时信号变低。进入ROM引导加载程序时,需要同时按住D0和Reset按钮。

作为普通输入使用。
默认下拉低电平,按下时信号变高。检测时需判断信号是否变高。

注意事项
D1/D2与D0在代码检测方式上有区别,因逻辑电平不同,需采用不同的检测代码。

硬件引脚映射与配置
在Arduino IDE中使用时,按键对应的数字引脚编号如下:
基本按键检测程序:
D0:按下为低电平
D1/D2:按下为高电平
//按键检测程序
#include <Arduino.h>
// 定义按键引脚
const int buttonD0 = 0; // BOOT键
const int buttonD1 = 1; // 注意:这两个“高电平有效”
const int buttonD2 = 2;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // 等待串口连接
Serial.println("\n 按键测试开始...");
// 关键配置:必须与硬件匹配
pinMode(buttonD0, INPUT_PULLUP); // D0 按下 = 低电平
pinMode(buttonD1, INPUT_PULLDOWN); // D1 按下 = 高电平
pinMode(buttonD2, INPUT_PULLDOWN); // D2 按下 = 高电平
Serial.println("配置完成: D0(上拉), D1/D2(下拉)");
Serial.println("按下按键,观察串口输出...\n");
}
void loop() {
// 读取三个引脚的状态
int stateD0 = digitalRead(buttonD0);
int stateD1 = digitalRead(buttonD1);
int stateD2 = digitalRead(buttonD2);
// 根据配置,判断按键是否被按下
bool d0Pressed = (stateD0 == LOW); // D0低电平表示按下
bool d1Pressed = (stateD1 == HIGH); // D1高电平表示按下
bool d2Pressed = (stateD2 == HIGH); // D2高电平表示按下
// 如果有任意按键被按下,则输出信息
if (d0Pressed || d1Pressed || d2Pressed) {
Serial.print("检测到按下: ");
if (d0Pressed) Serial.print("D0 ");
if (d1Pressed) Serial.print("D1 ");
if (d2Pressed) Serial.print("D2 ");
Serial.println(); // 换行
// 简单的防抖:等待按键释放
delay(200);
}
delay(10); // 短延时,减少CPU占用
}


常见问题:按键无响应
可能原因:上拉/下拉配置错误
引脚模式未正确设置
TCS3200颜色传感器:
什么是Color Sensor?
ColorSensor是一块静态识别物体颜色,不同颜色输出不同频率,采用TCS3200D,所有IO口均引出。TCS3200D是TAOS(TexasAdvancedOptoelectronicSolutions)公司推出的可编程彩色光到频率的转换器。它把可配置的硅光电二极管与电流频率转换器集成在一个单一的CMOS电路上,同时在单一芯片上还集成了红绿蓝(RGB)三种滤光器,是业界第一个有数字兼容接口的RGB彩色传感器。TCS3200D的输出信号是数字量,可以驱动标准的TTL或CMOS逻辑输入,因此可直接与微处理器或其它逻辑电路相连接。由于输出的是数字量,并且能够实现每个彩色信道10位以上的转换精度,因而不再需要A/D转换电路,使电路变得更简单。
性能描述
1.输出频率的占空比选择S0-S1。
2.颜色滤镜选择:S2~S3。
3.频率输出端口OUT。
4.频率输出使能引脚OE(低电平有效),模块已经置低,使用时可以悬空。
5.支持LED灯补光控制。
6.工作电压2.7-5.5V。
功能框图:

TCS3200核心内容总结为:
工作原理TCS3200通过四色滤光片阵列,将光强转换为频率信号输出。
控制逻辑
S0/S1:输出频率比例选择
S2/S3:滤光片类型选择
OE:输出使能(低电平有效)
颜色识别流程需白平衡校准,依次读取R/G/B通道频率,通过比较或映射识别颜色。

// 引脚定义 int s0 = 12, s1 = 11, s2 = 10, s3 = 9; int outPin = 6; // 频率测量变量 volatile unsigned long pulseCount = 0; unsigned long redFrequency = 0, greenFrequency = 0, blueFrequency = 0; // 中断函数 void IRAM_ATTR countPulse() { pulseCount++; } unsigned long readFrequency() { unsigned long count; noInterrupts(); // 禁用中断 count = pulseCount; pulseCount = 0; interrupts(); // 启用中断 delay(100); // 等待100ms noInterrupts(); count = pulseCount; // 获取100ms内的脉冲数 pulseCount = 0; interrupts(); return count; } void setup() { Serial.begin(115200); pinMode(s0, OUTPUT); pinMode(s1, OUTPUT); pinMode(s2, OUTPUT); pinMode(s3, OUTPUT); digitalWrite(s0, HIGH); digitalWrite(s1, LOW); pinMode(outPin, INPUT); attachInterrupt(digitalPinToInterrupt(outPin), countPulse, FALLING); Serial.println("TCS3200颜色传感器"); } void loop() { // 读取红色 digitalWrite(s2, LOW); digitalWrite(s3, LOW); delay(10); // 等待滤波器稳定 redFrequency = readFrequency(); // 读取绿色 digitalWrite(s2, HIGH); digitalWrite(s3, HIGH); delay(10); greenFrequency = readFrequency(); // 读取蓝色 digitalWrite(s2, LOW); digitalWrite(s3, HIGH); delay(10); blueFrequency = readFrequency(); // 简单的颜色判断 if (redFrequency > greenFrequency && redFrequency > blueFrequency) { Serial.println("红色"); } else if (greenFrequency > redFrequency && greenFrequency > blueFrequency) { Serial.println("绿色"); } else if (blueFrequency > redFrequency && blueFrequency > greenFrequency) { Serial.println("蓝色"); } else { Serial.println("其他颜色"); } delay(1000); }
下面就是将按键程序和颜色传感器融合起来:基于TCS3200的颜色识别系统:硬件与软件实现
项目背景与目标
本项目旨在实现基于TCS3200颜色传感器颜色识别系统,通过按键触发检测,并将结果通过串口输出。适用于分拣、智能家居等场景。
硬件组件与连接
所需硬件
ESP32开发板(主控)
TCS3200颜色传感器模块
按钮/开关(触发检测)
杜邦线(连接各组件)

引脚连接表
软件实现详解
1. 按键检测模块
// 关键配置:必须与硬件匹配 pinMode(buttonD0, INPUT_PULLUP); // D0 按下 = 低电平 pinMode(buttonD1, INPUT_PULLDOWN); // D1 按下 = 高电平 pinMode(buttonD2, INPUT_PULLDOWN); // D2 按下 = 高电平提示
BOOT按钮(D0)为上拉设计,按下为低电平
D1/D2为下拉设计,按下为高电平
检测代码需与硬件逻辑一致
2. 颜色传感器驱动核心频率测量机制
TCS3200输出方波频率表示颜色强度,采用中断计数实现:volatile unsigned long pulseCount = 0;
// 中断服务函数
void IRAM_ATTR countPulse() {
pulseCount++;
}中断保护
操作共享变量时需临界区保护,确保数据一致性:
volatile unsigned long pulseCount = 0;
// 中断服务函数
void IRAM_ATTR countPulse() {
pulseCount++;
}经验教训添加中断保护后系统稳定性显著提升
3. 颜色读取流程
依次切换滤波器,读取不同颜色分量:
// 读取红色分量 digitalWrite(s2, LOW); digitalWrite(s3, LOW); redFrequency = readFrequency(); // 读取绿色分量 digitalWrite(s2, HIGH); digitalWrite(s3, HIGH); greenFrequency = readFrequency(); // 读取蓝色分量 digitalWrite(s2, LOW); digitalWrite(s3, HIGH); blueFrequency = readFrequency();
4. 优化后的 readFrequency 函数
unsigned long readFrequency() {
unsigned long count;
// 第一次保护:重置计数器
noInterrupts();
pulseCount = 0;
interrupts();
delay(100); // 采集100ms的脉冲
// 第二次保护:读取计数值
noInterrupts();
count = pulseCount;
pulseCount = 0; // 可选:为下次测量准备
interrupts();
return count;
}5.完整代码:
#include <Arduino.h>
// 颜色传感器引脚定义
const int s0 = 12, s1 = 11, s2 = 10, s3 = 9;
const int outPin = 6;
// 按键引脚 - 只保留D1
const int buttonD1 = 1; // 按下为高电平
// 频率测量变量
volatile unsigned long pulseCount = 0;
unsigned long redFrequency = 0, greenFrequency = 0, blueFrequency = 0;
// 中断函数
void IRAM_ATTR countPulse() {
pulseCount++;
}
void setup() {
Serial.begin(115200);
// 颜色传感器初始化
pinMode(s0, OUTPUT);
pinMode(s1, OUTPUT);
pinMode(s2, OUTPUT);
pinMode(s3, OUTPUT);
digitalWrite(s0, HIGH);
digitalWrite(s1, LOW);
pinMode(outPin, INPUT);
attachInterrupt(digitalPinToInterrupt(outPin), countPulse, FALLING);
// 按键初始化
pinMode(buttonD1, INPUT_PULLDOWN); // D1按下=高电平
Serial.println("就绪: 按下D1读取颜色");
}
void readColor() {
// 读取红色
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);
delay(10);
noInterrupts();
pulseCount = 0;
interrupts();
delay(100);
noInterrupts();
redFrequency = pulseCount;
interrupts();
// 读取绿色
digitalWrite(s2, HIGH);
digitalWrite(s3, HIGH);
delay(10);
noInterrupts();
pulseCount = 0;
interrupts();
delay(100);
noInterrupts();
greenFrequency = pulseCount;
interrupts();
// 读取蓝色
digitalWrite(s2, LOW);
digitalWrite(s3, HIGH);
delay(10);
noInterrupts();
pulseCount = 0;
interrupts();
delay(100);
noInterrupts();
blueFrequency = pulseCount;
interrupts();
// 显示频率值
Serial.print("R:");
Serial.print(redFrequency);
Serial.print(" G:");
Serial.print(greenFrequency);
Serial.print(" B:");
Serial.print(blueFrequency);
Serial.print(" - ");
// 颜色判断逻辑
if (redFrequency > greenFrequency && redFrequency > blueFrequency) {
Serial.println("红色");
} else if (greenFrequency > redFrequency && greenFrequency > blueFrequency) {
Serial.println("绿色");
} else if (blueFrequency > redFrequency && blueFrequency > greenFrequency) {
Serial.println("蓝色");
} else {
Serial.println("其他颜色");
}
}
void loop() {
// 检测D1按键
if (digitalRead(buttonD1) == HIGH) {
Serial.print("检测到按键D1,");
readColor();
delay(200); // 防抖延时
}
delay(10);
}此处我才用的是电脑屏幕上展示红绿蓝纯色图片,让ESP32+模块在按键按下时识别颜色。
串口输出:
系统运行时输出格式:


我要赚赏金
