一、项目简介
基于 ESP32-S3 的互动音频视觉项目。只需将磁铁靠近设备,系统即可通过 TCS3200 颜色传感器 读取物体颜色,并实现以下互动:
板载 RGB LED(NeoPixel):同步显示识别到的颜色;
蜂鸣器模块:演奏与该颜色对应的音符或旋律。
二、硬件清单

三、核心功能与代码整合
本项目代码集成了四大核心功能:
颜色识别(TCS3200)
RGB视觉反馈(NeoPixel)
声音输出(蜂鸣器与音阶映射)
磁控开关(接近传感器)
磁铁靠近接近传感器时,启动检测;
TCS3200 读取 R、G、B 三通道频率;
判断主色,点亮对应颜色 LED;
按颜色索引(0-7)从 C 大调音阶中选取频率,驱动蜂鸣器发声;
磁铁离开后,停止发声并关闭 LED。
#include <Adafruit_NeoPixel.h>
// ===== 1. 引脚定义 =====
// TCS3200颜色传感器引脚
#define S0_PIN 12
#define S1_PIN 11
#define S2_PIN 10
#define S3_PIN 9
#define OUT_PIN 6
// 蜂鸣器引脚
#define SPEAKER_PIN 13
// 接近传感器引脚
#define PROXIMITY_PIN 5
// 板载RGB LED (固定引脚)
#define RGB_PIN 33
#define NUMPIXELS 1
// ===== 2. 全局变量与对象初始化 =====
// 颜色传感器变量
volatile unsigned long pulseCount = 0;
unsigned long redFreq = 0, greenFreq = 0, blueFreq = 0;
// RGB LED对象
Adafruit_NeoPixel pixels(NUMPIXELS, RGB_PIN, NEO_GRB + NEO_KHZ800);
// 音阶频率定义 (C大调)
int musicalScale[] = {262, 294, 330, 349, 392, 440, 494, 523}; // C4到C5
const char* noteNames[] = {"C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5"};
// ===== 3. 中断函数:用于计数颜色传感器输出的脉冲 =====
void IRAM_ATTR countPulse() {
pulseCount++;
}
// ===== 4. 关键功能函数 =====
/**
* 读取颜色传感器某一通道的频率值
*/
unsigned long readFrequency() {
unsigned long count;
noInterrupts(); // 进入临界区
pulseCount = 0;
interrupts();
delay(100); // 采样100ms
noInterrupts();
count = pulseCount; // 获取脉冲数
interrupts();
return count;
}
/**
* 识别颜色并更新RGB LED
* @return 返回识别到的颜色索引 (0-7对应音阶)
*/
int detectColorAndShow() {
// 读取红色分量
digitalWrite(S2_PIN, LOW);
digitalWrite(S3_PIN, LOW);
redFreq = readFrequency();
// 读取绿色分量
digitalWrite(S2_PIN, HIGH);
digitalWrite(S3_PIN, HIGH);
greenFreq = readFrequency();
// 读取蓝色分量
digitalWrite(S2_PIN, LOW);
digitalWrite(S3_PIN, HIGH);
blueFreq = readFrequency();
// 简单判断主色并显示
int colorIndex = 7; // 默认其他颜色,对应最高音
if (redFreq > greenFreq && redFreq > blueFreq) {
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // 红色
colorIndex = 0; // 可映射为低音
Serial.println("识别: 红色");
} else if (greenFreq > redFreq && greenFreq > blueFreq) {
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // 绿色
colorIndex = 2;
Serial.println("识别: 绿色");
} else if (blueFreq > redFreq && blueFreq > greenFreq) {
pixels.setPixelColor(0, pixels.Color(0, 0, 255)); // 蓝色
colorIndex = 4;
Serial.println("识别: 蓝色");
} else {
pixels.setPixelColor(0, pixels.Color(255, 255, 255)); // 白色
Serial.println("识别: 其他/白色");
}
pixels.show(); // 更新LED显示
return colorIndex;
}
/**
* 播放与颜色对应的音符
*/
void playCorrespondingNote(int colorIndex) {
// 确保索引在音阶范围内
int noteIndex = colorIndex % 8;
Serial.print("播放音符: ");
Serial.println(noteNames[noteIndex]);
tone(SPEAKER_PIN, musicalScale[noteIndex], 500); // 播放500ms
delay(600); // 留一点间隔
}
// ===== 5. Arduino标准 setup() 和 loop() =====
void setup() {
Serial.begin(115200);
// 初始化颜色传感器
pinMode(S0_PIN, OUTPUT);
pinMode(S1_PIN, OUTPUT);
pinMode(S2_PIN, OUTPUT);
pinMode(S3_PIN, OUTPUT);
digitalWrite(S0_PIN, HIGH);
digitalWrite(S1_PIN, LOW); // 设置频率缩放为20%
pinMode(OUT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(OUT_PIN), countPulse, FALLING);
// 初始化RGB LED
pixels.begin();
pixels.setBrightness(30); // 设置适中亮度
// 初始化蜂鸣器引脚
pinMode(SPEAKER_PIN, OUTPUT);
// 初始化接近传感器引脚
pinMode(PROXIMITY_PIN, INPUT_PULLUP); // 假设传感器常态断开
Serial.println("拾色播放器就绪!");
Serial.println("将磁铁靠近接近传感器以开始/停止播放...");
}
void loop() {
// 检测接近传感器状态(磁铁是否靠近)
bool isMagnetNear = (digitalRead(PROXIMITY_PIN) == LOW); // 根据实际接线调整逻辑
if (isMagnetNear) {
Serial.println("--- 检测到磁铁,开始工作 ---");
// 1. 识别颜色
int detectedColorIndex = detectColorAndShow();
// 2. 播放对应音符
playCorrespondingNote(detectedColorIndex);
delay(1000); // 循环间隔
} else {
// 磁铁远离时,可以停止声音或进入低功耗模式
noTone(SPEAKER_PIN); // 停止发声
pixels.clear(); // 关闭RGB LED
pixels.show();
delay(200); // 检测间隔
}
} 四、注意事项 & 调试建议
TCS3200 校准:不同光照环境下,颜色频率基准会变化。建议先打印 redFreq, greenFreq, blueFreq 到串口,根据实际情况调整判断阈值。
传感器干扰:TCS3200 对光源敏感,建议在稳定光源下测试,避免阴影或反光影响识别。
蜂鸣器类型:本项目需使用无源蜂鸣器(可通过频率发声)。如使用有源蜂鸣器,只能发出固定音调,需更改驱动方式。
接近传感器逻辑:根据实际模块常开/常闭特性,可能需要调整 digitalRead(PROXIMITY_PIN) 的判断逻辑(示例假定磁铁靠近时为低电平)。
扩展建议:
可将颜色映射为一段旋律,而非单音;
加入 Wi-Fi,将识别颜色上传服务器或手机;
用舵机制作“颜色转盘”,自动转到对应颜色位置。
五、实际效果
实测时,用红、绿、蓝三色卡片分别触发了 C4、E4、G4 三个音符,LED 同步显示颜色,效果直观。磁控开关的加入让操作更有“仪式感”,仿佛启动一个音乐盒。


本项目涵盖了 GPIO 控制、外部中断、脉冲计数、PWM 发声、NeoPixel 驱动 等多个基础知识点,非常适合作为 ESP32-S3 的综合练习。
视频请查收~
【【Let'sdo第3期-拾色播放器DIY】成果贴:ESP32-S3制作会“唱歌”的拾色播放器】 https://www.bilibili.com/video/BV1PzqWBvE8M/?share_source=copy_web&vd_source=0c8eb7b44ac841939fb3482cf31385a9

我要赚赏金
