这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » Let'sdo2025年第3期——拾音器--总结贴

共2条 1/1 1 跳转至

Let'sdo2025年第3期——拾音器--总结贴

菜鸟
2025-12-13 00:16:33     打赏

Let'sdo3-拾色播放器DIY】拾音器总结贴

本次很荣幸参加了本次的拾音器的活动,本次完成了基本活动,

硬件介绍

Adafruit开发板1528-5691-ND的具体型号是Adafruit ESP32-S3 Reverse TFT Feather。这是一款功能丰富、设计精巧的开发板,特别适合嵌入式项目开发、物联网设备原型设计以及需要人机交互的可视化应用。

还购买了颜色传感器来实现本次的功能,本次也购买了扬声器,来完成此次的基础任务。

 907751a0c1cf11928539a5324fd1562f.jpg

图上就是本次活动使用到的硬件

开发过程帖子汇总

任务1:实现颜色传感器驱动,在串口显示颜色信息

Let'sdo2025年第3——拾音器-颜色传感器获取当前颜色-电子产品世界论坛

任务2:实现板载RGB全彩控制,实时显示当前的颜色

Let'sdo2025年第3——拾音器-板载RGB显示当前颜色-电子产品世界论坛

任务3:实现扬声器驱动,并播放八阶音符

Let'sdo2025年第3——拾音器-扬声器播放8阶音符-电子产品世界论坛

=_=发现图床的图片没有成功上传,稍后会更新帖子中的图片

系统框图

8799c8a5c05af7b333c46c417035d4e8.png


电路原理图

67f598dac022a775421d0fd81d87eeb5.png


硬件连接TCS34725颜色传感器连接

  • SDA: ESP32SDA引脚(通常为GPIO      21

  • SCL: ESP32SCL引脚(通常为GPIO      22

  • VCC: 3.3V

  • GND: GND

扬声器连接

  • 信号输入: GPIO 9

  • VCC: 3.3V5V

  • GND: GND

实现代码

#include "TCS34725.h"
#include <Adafruit_NeoPixel.h>
 
// 颜色传感器和LED配置
TCS34725 tcs;
#define PIN        33
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
 
// 颜色显示相关变量
unsigned long lastColorUpdate = 0;
const unsigned long colorUpdateInterval = 100; // 颜色更新间隔100ms
bool colorSensorInitialized = false;
 
const int buzzerPin = 9;      // 蜂鸣器引脚
const int buttonPin = 2;      // 按键引脚
 
// 定义音符频率数组 (中音C到高音C)
int melody[] = {262, 294, 330, 349, 392, 440, 494, 523};
String noteNames[] = {"C", "D", "E", "F", "G", "A", "B", "C5"};
 
int currentNote = 0;          // 当前音符索引
int buttonState = 0;           // 按键状态
int lastButtonState = 0;       // 上一次按键状态
unsigned long lastDebounceTime = 0;  // 消抖时间
unsigned long debounceDelay = 50;    // 消抖延迟时间
 
void setup() {
  pinMode(buzzerPin, OUTPUT);     // 设置蜂鸣器引脚为输出模式
  pinMode(buttonPin, INPUT_PULLUP); // 设置按键引脚为输入上拉模式
  
  Serial.begin(115200);           // 初始化串口通信
  Serial.println("ESP32 多功能系统启动");
  Serial.println("功能1: 按键控制八阶音符播放");
  Serial.println("功能2: 实时颜色检测与LED显示");
  
  // 初始化NeoPixel LED
  pixels.begin();
  pixels.clear();
  pixels.show();
  
  // 初始化颜色传感器
  Wire.begin();
  if (!tcs.attach(Wire)) {
    Serial.println("ERROR: TCS34725 NOT FOUND !!!");
    colorSensorInitialized = false;
  } else {
    Serial.println("TCS34725 颜色传感器初始化成功");
    tcs.integrationTime(33); // ms
    tcs.gain(TCS34725::Gain::X01);
    colorSensorInitialized = true;
  }
  
  Serial.println("当前音符: " + noteNames[currentNote] + " (" + String(melody[currentNote]) + "Hz)");
  Serial.println("系统初始化完成,开始运行...");
}
 
void loop() {
  // 处理按键检测
  handleButtonInput();
  
  // 处理颜色检测和LED显示
  handleColorDetection();
}
 
// 处理按键输入的函数
void handleButtonInput() {
  // 读取按键状态
  int reading = digitalRead(buttonPin);
  
  // 检测按键状态变化(消抖处理)
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // 如果按键状态确实改变了
    if (reading != buttonState) {
      buttonState = reading;
      
      // 检测按键按下(低电平,因为使用上拉电阻)
      if (buttonState == LOW) {
        playNote(melody[currentNote], 300); // 播放当前音符,持续300ms
        
        // 打印当前播放的音符信息
        Serial.print("播放音符: ");
        Serial.print(noteNames[currentNote]);
        Serial.print(" (");
        Serial.print(melody[currentNote]);
        Serial.println("Hz)");
        
        // 移动到下一个音符
        currentNote = (currentNote + 1) % 8; // 循环回到第一个音符
        
        // 显示下一个将要播放的音符
        Serial.print("下一个音符: ");
        Serial.print(noteNames[currentNote]);
        Serial.print(" (");
        Serial.print(melody[currentNote]);
        Serial.println("Hz)");
      }
    }
  }
  
  lastButtonState = reading;
}
 
// 处理颜色检测的函数
void handleColorDetection() {
  // 检查是否到了更新颜色的时间
  if (millis() - lastColorUpdate >= colorUpdateInterval) {
    lastColorUpdate = millis();
    
    // 如果颜色传感器已初始化且有新数据
    if (colorSensorInitialized && tcs.available()) {
      TCS34725::Color color = tcs.color();
      
      // 显示颜色信息(每秒显示一次完整信息)
      static unsigned long lastFullColorPrint = 0;
      if (millis() - lastFullColorPrint >= 1000) {
        lastFullColorPrint = millis();
        
        Serial.print("颜色检测 - 色温: ");
        Serial.print(tcs.colorTemperature());
        Serial.print("K, 光照: ");
        Serial.print(tcs.lux());
        Serial.print("lux, RGB: (");
        Serial.print(color.r);
        Serial.print(", ");
        Serial.print(color.g);
        Serial.print(", ");
        Serial.print(color.b);
        Serial.println(")");
      }
      
      // 更新NeoPixel LED颜色
      // RGB值缩放到0-255范围(TCS34725的值可能超过255
      uint8_t r = (color.r > 255) ? 255 : color.r;
      uint8_t g = (color.g > 255) ? 255 : color.g;
      uint8_t b = (color.b > 255) ? 255 : color.b;
      
      pixels.setPixelColor(0, pixels.Color(r, g, b));
      pixels.show();
    }
  }
}
 
// 播放单个音符的函数
void playNote(int frequency, int duration) {
  // 计算方波的半周期时间(微秒)
  long halfPeriod = 1000000L / frequency / 2; 
  // 计算在指定持续时间内需要多少个方波周期
  long cycles = (long)frequency * duration / 1000;
 
  // 通过循环生成指定数量的方波
  for (long j = 0; j < cycles; j++) {
    digitalWrite(buzzerPin, HIGH);
    delayMicroseconds(halfPeriod);
    digitalWrite(buzzerPin, LOW);
    delayMicroseconds(halfPeriod);
  }
}

功能介绍

通过按键我们可以播放八阶音符的声音,其中颜色还能实时采集,通过板载LED来显示我们当前的颜色

效果演示

通过b站的视频来展示我们的成果。



院士
2025-12-13 19:33:13     打赏
2楼

arduino的代码量还是挺少的


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]