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

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

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

基本按键检测程序:
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占用
}


上拉/下拉配置错误
引脚模式未正确设置
什么是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通过四色滤光片阵列,将光强转换为频率信号输出。
控制逻辑
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);
}ESP32开发板(主控)
TCS3200颜色传感器模块
按钮/开关(触发检测)
杜邦线(连接各组件)
// 关键配置:必须与硬件匹配 pinMode(buttonD0, INPUT_PULLUP); // D0 按下 = 低电平 pinMode(buttonD1, INPUT_PULLDOWN); // D1 按下 = 高电平 pinMode(buttonD2, INPUT_PULLDOWN); // D2 按下 = 高电平提示
BOOT按钮(D0)为上拉设计,按下为低电平
D1/D2为下拉设计,按下为高电平
检测代码需与硬件逻辑一致
volatile unsigned long pulseCount = 0;
// 中断服务函数
void IRAM_ATTR countPulse() {
pulseCount++;
}中断保护操作共享变量时需临界区保护,确保数据一致性:
volatile unsigned long pulseCount = 0;
// 中断服务函数
void IRAM_ATTR countPulse() {
pulseCount++;
}经验教训添加中断保护后系统稳定性显著提升
依次切换滤波器,读取不同颜色分量:
// 读取红色分量 digitalWrite(s2, LOW); digitalWrite(s3, LOW); redFrequency = readFrequency(); // 读取绿色分量 digitalWrite(s2, HIGH); digitalWrite(s3, HIGH); greenFrequency = readFrequency(); // 读取蓝色分量 digitalWrite(s2, LOW); digitalWrite(s3, HIGH); blueFrequency = readFrequency();
unsigned long readFrequency() {
unsigned long count;
// 第一次保护:重置计数器
noInterrupts();
pulseCount = 0;
interrupts();
delay(100); // 采集100ms的脉冲
// 第二次保护:读取计数值
noInterrupts();
count = pulseCount;
pulseCount = 0; // 可选:为下次测量准备
interrupts();
return count;
}串口输出示例系统运行时输出格式: