×

Arduino Light Clapper使用声音检测器

消耗积分:0 | 格式:zip | 大小:0.11 MB | 2022-11-11

王强

分享资料个

描述

声音探测器感知声音。本教程中使用的声音检测器类型是数字声音检测器,当在环境中检测到一定级别的声音时,它会被激活。传感器板连接到一个小麦克风以拾取声音

本教程允许您学习如何创建一个带有声音检测器的系统,该系统允许您快速连续两次打开或关闭导联。它类似于名为 Clapper 的市售产品,这是一种声音电子开关,可以在用户拍手时激活或禁用与其连接的灯。

原理图,示意图

 

poYBAGNtnzGAK2_ZAAFEz-dB1LI357.png
Arduino 轻拍器
 

 

  • 将声音检测器上的 VCC 引脚连接到 Arduino 的 3.3-V 引脚。
  • 将声音探测器上的 GND 引脚连接到 Arduino 的 GND 引脚。
  • 将声音探测器上的输出引脚连接到 Arduino 的数字引脚 8。
  • 将 LED 的负极连接到 Arduino 的 GND 引脚。
  • 将 LED 的正极连接到 Arduino 的数字引脚 7

程序

int NumberSounds = 0;
int SoundPin = 8;
int RawValue = 0;
int NumberClaps = 0;
int LightOn = 0;
unsigned long SoundDetectedTime = 0;
unsigned long PreviousSoundDetectedTime = 0;
int UniqueClapMinTime = 100;
int LEDPin = 7;
unsigned long PreviousClapTime = 0;
unsigned long CurrentClapTime = 0;
unsigned long MaxTimeBetweenClaps = 2000;


void setup()
{
 pinMode(SoundPin, INPUT);
 pinMode(LEDPin, OUTPUT);
 Serial.begin(9600);
 Serial.println("The Light Clapper ...");
}


int IsSoundPartOfUniqueClap()
{
 int result = 0;
 unsigned long ElapsedTime = 
   SoundDetectedTime -  
   PreviousSoundDetectedTime;
 if (ElapsedTime >= UniqueClapMinTime)
 {
    result = 1;
 }
 return result;
}



int CheckTurnOnOffLight()
{
 int result = 0;
 unsigned long ElapsedTime =  
   CurrentClapTime - PreviousClapTime;
 if (ElapsedTime <= MaxTimeBetweenClaps)
 {
    if (NumberClaps == 2)
    {
       result = 1;
       NumberClaps = 0;
    }
 }
 else
 {
    NumberClaps = 1;
 }
 return result;
}


void loop()
{
 RawValue = digitalRead(SoundPin);
 if (RawValue == 0)
 {
    Serial.print("SOUND DETECTED ... ");
    Serial.print(", Sound Number: ");
    Serial.print(NumberSounds);
    Serial.print(", RawValue: ");
    Serial.println(RawValue);
    NumberSounds++;

    // Process raw data for claps
    PreviousSoundDetectedTime = 
      SoundDetectedTime;
    SoundDetectedTime = millis();
    if(IsSoundPartOfUniqueClap())
    {
       NumberClaps++;

       // Update Clap Times
       PreviousClapTime = 
         CurrentClapTime;
       CurrentClapTime = millis();

       // Turn Light ON/OFF as needed
       if (CheckTurnOnOffLight())
       {
          LightOn = ~LightOn;
          if (LightOn)
          {
             digitalWrite(LEDPin, HIGH);
          }
          else
          {
             digitalWrite(LEDPin, LOW);
          }
       }
    }
 }
}

 

程序分析

 

自程序启动并初始化为 0 以来,声音检测器检测到的声音数量是变量 NumberSounds:

int NumberSounds = 0;

声音探测器上的输出引脚分配给 Arduino 的数字引脚 8:

int SoundPin = 8;

RawValue 变量保存声音检测器的状态并初始化为 0:

int RawValue = 0;

NumberClaps 变量存储当前的掌声计数,以切换 LED 灯所需的两次。这是开始 0 拍手:

int NumberClaps = 0;

如果 LED 已打开,则 LightOn 变量为非零,否则为 0。这里初始化为0:

int LightOn = 0;

SoundDetectedTime 变量存储最后检测到的声音的时间,并用于计算不同拍手的数量,因为单个拍手可以生成多个正的声音检测器读数。此变量的初始值为 0:

unsigned long SoundDetectedTime = 0;

PreviousSoundDetectedTime 变量保存上一次检测到的声音的时间,并用于确定唯一拍手的数量:

unsigned long PreviousSoundDetectedTime = 0;

UniqueClapMinTime 变量存储检测到的声音之间的最小时间间隔(以毫秒为单位),程序必须将其识别为唯一的拍手:

int UniqueClapMinTime = 100;

LEDPin 变量代表数字引脚 7,它连接到 LED 的正极端子:

int LEDPin = 7;

PreviousClapTime 变量保存上一次拍手发生的时间(以毫秒为单位)并初始化为 0:

unsigned long PreviousClapTime = 0;

CurrentClapTime 变量保存当前拍手发生的时间(以毫秒为单位)并初始化为 0:

unsigned long CurrentClapTime = 0;

MaxTimeBetweenClaps 变量指定可用于切换 LED 灯的两次连续拍手之间的最长时间。默认情况下,超时值设置为 2、000 毫秒或 2 秒。

unsigned long MaxTimeBetweenClaps = 2000;

setup() 函数初始化程序并:

1. 将连接到声音检测器输出引脚的 Arduino 引脚设置为输入引脚,以便可以测量电压。

2. 将连接到 LED 正极端子的 Arduino 引脚设置为输出引脚,它可以向 LED 提供电压并驱动 LED。

3. 初始化串行监视器并将通信速度设置为 9、600 波特。

4. 向串行监视器打印一条指示程序已启动的文本消息。

void setup()
{
1.pinMode(SoundPin, INPUT);
2. pinMode(LEDPin, OUTPUT);
3. Serial.begin(9600);
3. Serial.println("The Light Clapper ...");
}

IsSoundPartOfUniqueClap() 函数确定声音检测器检测到的声音是新的唯一拍手的开始还是当前拍手的继续。这是通过以下方式实现的:

计算自检测到上一个声音以来经过的时间。

如果此时间大于或等于识别唯一拍手所需的最短时间,则该函数返回 1。

否则,函数返回 0。

int IsSoundPartOfUniqueClap()
{
int result = 0;
unsigned long ElapsedTime =
SoundDetectedTime -
PreviousSoundDetectedTime;
if (ElapsedTime >= UniqueClapMinTime)
{
result = 1;
}
return result;
}

CheckTurnOnOffLight() 函数通过在两秒内检测到两次连续拍手来确定是否应切换 LED。这是通过以下方式实现的:

计算当前检测到的拍手和之前检测到的拍手之间的经过时间。

如果经过的时间小于或等于拍手之间的最大允许时间,则如果检测到的拍手次数为 2,则将返回值设置为 1,这意味着应切换 LED 开/关状态,并重置检测到的拍手次数为 0。

如果经过的时间大于拍手之间的最大允许时间,则将检测到的拍手数设置为 1,以指示当前检测到的拍手是两次拍手打开/关闭序列的唯一有效拍手。

如果应该切换 LED,则返回 1,否则返回 0。

int CheckTurnOnOffLight()
{
int result = 0;
unsigned long ElapsedTime =
CurrentClapTime - PreviousClapTime;
if (ElapsedTime <= MaxTimeBetweenClaps)
{
if (NumberClaps == 2)
{
result = 1;
NumberClaps = 0;
}
}
else
{
NumberClaps = 1;
}
return result;
}

loop() 函数读取声音检测器的输出,确定检测到的声音是唯一的拍手还是先前拍手的延续,确定是否检测到两次拍手序列,如果是,则切换 LED 灯。这是通过以下方式实现的:

读取声音检测器的状态。

如果读取的值等于 0,表示检测到声音,则函数:

将一些调试信息打印到串行监视器。

更新跟踪当前声音检测事件和先前声音检测事件的时间的变量。

如果此声音检测事件是新的独特鼓掌的一部分,则函数:

将检测到的拍手次数增加 1。

更新前一次拍手和当前拍手的时间。

如果在 2 秒内发生了两次连续拍手,则函数:

通过对 LightOn 变量执行按位非运算来切换 LED 状态变量。

如果 LightOn 变量的计算结果为真(非零),则打开 LED。

如果 LightOn 变量的计算结果为假(零),则关闭 LED。

void loop()
{
RawValue = digitalRead(SoundPin);
if (RawValue == 0)
{
Serial.print("SOUND DETECTED ... ");
Serial.print(", Sound Number: ");
Serial.print(NumberSounds);
Serial.print(", RawValue: ");
Serial.println(RawValue);
NumberSounds++;
// Process raw data for claps
PreviousSoundDetectedTime =
SoundDetectedTime;
SoundDetectedTime = millis();
if(IsSoundPartOfUniqueClap())
{
NumberClaps++;
// Update Clap Times
PreviousClapTime =
CurrentClapTime;
CurrentClapTime = millis();
// Turn Light ON/OFF as needed
if (CheckTurnOnOffLight())
{
LightOn = ~LightOn;
if (LightOn)
{
digitalWrite(LEDPin, HIGH);
}
else
{
digitalWrite(LEDPin, LOW);
}
}
}
}
} 

 


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !