【Follow me第二季第4期】通过响指开/关板载 LED
[复制链接]
功能介绍
利用麦克风传感器,实现打响指来控制板载 LED 绿灯的开或关。
此任务参考了 Arduino 官方教程示例 Reading Microphone Data on Nano RP2040 Connect。
流程图
演示视频
示例代码
#include <WiFiNINA.h>
#include <PDM.h>
// 声道数量(单通道)
static const char channels = 1;
// PDM 数据的采样率(单位:Hz)
static const int frequency = 20000;
// 用于存储音频样本的缓冲区,每个样本是 16 位
short sampleBuffer[512];
// 读取到的音频样本数量,使用 volatile 修饰以确保线程安全
volatile int samplesRead;
// 用于控制 LED 开关状态的布尔变量
bool LED_SWITCH = false;
// 样本值的阈值(绝对值大于该值时切换 LED 状态)
const int THRESHOLD = 10000;
void setup() {
// 初始化串口,用于调试和打印信息
Serial.begin(9600);
// 设置 LED 引脚为输出模式
pinMode(LEDG, OUTPUT);
// 等待串口连接(仅用于调试模式)
while (!Serial);
// 配置 PDM 麦克风的数据接收回调函数
PDM.onReceive(onPDMdata);
// 初始化 PDM 麦克风
if (!PDM.begin(channels, frequency)) {
Serial.println("PDM 初始化失败!");
while (1); // 如果初始化失败,则进入死循环
}
}
void loop() {
// 检查是否有新的音频样本
if (samplesRead) {
// 遍历读取到的样本数据
for (int i = 0; i < samplesRead; i++) {
// 打印当前样本值到串口监视器(用于调试)
Serial.println(sampleBuffer[i]);
// 如果样本值超过阈值(绝对值大于 THRESHOLD),切换 LED 状态
if (abs(sampleBuffer[i]) > THRESHOLD) {
LED_SWITCH = !LED_SWITCH; // 切换 LED 状态
if (LED_SWITCH) {
digitalWrite(LEDG, HIGH); // 打开绿灯
Serial.println("绿灯已开启!");
} else {
digitalWrite(LEDG, LOW); // 关闭绿灯
Serial.println("绿灯已关闭!");
}
delay(1000); // 延迟 1 秒,避免过于频繁的切换
}
}
// 清除样本读取计数
samplesRead = 0;
}
}
/**
* 回调函数,用于处理 PDM 麦克风采集的数据。
*/
void onPDMdata() {
// 查询缓冲区中可用字节数
int bytesAvailable = PDM.available();
// 从缓冲区读取音频数据到样本缓冲区
PDM.read(sampleBuffer, bytesAvailable);
// 每个样本为 16 位(2 字节),计算样本数量
samplesRead = bytesAvailable / 2;
}
|