🥬Arduino生物波反馈和环境检测外套

关键词

Arduino | 声音 | 信号 | 乐器 | MIDI协议 | 和弦 | 音器 | 琴 | 气鼓 | 逻辑门 | 电机 | 生物波 | 远程 | 射频 | 吉他 | 信号 | 音效 | 傅里叶 | 滤波 | 混沌摆 | 算法 | 瓦特 | 驻波比 | 频率 | 波束 | 天线 | 航向 | 变频振荡器 | 数字合成 | 点对点 | RESTful | MQTT | 服务器 | 跟踪 | 蓝牙 | 无线网络 | 健康 | 外套 | 高频语音

🏈page指点迷津 | Brief

🎯要点

  1. 声音和信号处理:🎯乐器数字接口MIDI协议:🖊输入输出 | 🖊双重和三重跟踪 🖊自动生成三和弦 🖊琶音器 🖊循环踏板 | 🖊特雷门琴 | 🖊气鼓 | 🖊灯光秀控制 | 🖊逻辑门控制电机供电顺序 | 🖊MIDI 信号驱动播放器 | 🖊MIDI吉他 | 🖊Arduino开源声音控制音乐多媒体 | 🖊MIDI 混沌摆 | 🖊MIDI 脚踏开关键盘或控制器。🎯信号:🖊声音取样和播放 | 🖊音效 | 🖊傅里叶滤波 | 🖊Karplus强算法数字信号处理。🎯射频控制:🖊制作通用继电器控制的音序器 | 🖊制作波束控制器,设置天线波束并将其旋转到特定航向 | 🖊定向瓦特和驻波比表 | 🖊频率计数器测量并显示变频振荡器频率 | 🖊直接数字合成变频振荡器 |​ 🖊LoRa点对点通讯、网关、连接RESTful 和MQTT 服务器、 GPS跟踪。

  2. 🎯项目:🖊无线网络和蓝牙监控生物波反馈身体健康 | 🖊可穿戴身体和环境状态检测外套 | 🖊高频语音收发

🍇Arduino使用算法频谱分析语音信号

大多数处理数字信号的设备都使用离散傅里叶变换。 当我们谈论数字信号时,指的是音频信号、图像信号等。因此,这意味着您的电视、计算机和收音机在幕后进行离散傅里叶变换。

现在你知道了这件事的重要性,让我们看看它是如何运作的。请记住,这里提出的概念是基本概念,它只能被视为傅里叶理论的一般概述。

在数字信号处理中,我们处理的所有信号都是模拟信号。 我们的世界是一个模拟世界。 模拟信号就是时间连续信号,但是,计算机却是数字的。 因此,如果我们要处理所有模拟信号,就必须将其转换为数字信号。 这就是离散傅里叶变换发挥作用的时候,它将模拟信号转换为数字信号。

我不会太深入地讨论这个主题,因为它非常难以理解,所以让我们保持简单。 可以这么说,离散傅里叶变换可以将模拟信号(A)转换为数字信号(B),然后我们可以使用计算机或DSP对其进行处理(C),最后重建原始信号(D) 。

此算法是一种极其有效的离散傅里叶变换方法。 这种计算方法与其他离散傅里叶变换方法的主要区别在于,它在每次迭代中使用单个实值系数。 该分析的缺点是与快速傅里叶变换相比,其复杂度更高。 然而,对于少数频率,该算法在效率方面优于同类算法。 请记住,我们是在 Arduino 中实现该软件,因此硬件限制是一个重要问题。

我不会解释该算法背后的所有数学原理。我们将看看它在实际应用中是如何工作的。为了使用该算法,我们需要首先执行以下步骤:

  • 确定采样率。

  • 选择块大小N。

  • 预先计算一个余弦项和一个正弦项。

  • 预先计算一个系数。

我们需要计算对模拟信号进行采样的频率。 为此,我们需要将微控制器的时钟除以 2 以获得最大采样频率,因为这是奈奎斯特-香农采样定理中规定的。 我们需要实现的公式如下:

ω0=2πkNk{0,1,2,,N1}y[N]=n=0Nx[n]ej2πnkN\begin{aligned} & \omega_0=2 \pi \frac{k}{N} \\ & k \in\{0,1,2, \ldots, N-1\} \\ & y[N]=\sum_{n=0}^N x[n] e^{-j 2 \pi \frac{n k}{N}} \end{aligned}

请记住,您可以修改此项目,以便它也可以识别特定的音频模式甚至单词。所以,该函数将如下所示:

 void inico(){
   while(true){
     Goel gl = Goel(4000, N, SAMPLING_FREQUENCY);
     gl.sample(A0); 
     float ligar = gl.detect();  
     if(ligar>900){
       digitalWrite(led2, LOW);
        for (int i = 0; i < 8; i++)  
          {
         lc.setRow(0,i,invader1a[i]);
         }
         delay(3000);
         ligarAudio();
       break;
     }
   }
 }
 void ResetGoel(void)
 {
   Q2 = 0;
   Q1 = 0;
 }
 ​
 void ProcessSample(byte sample)
 {
   float Q0;
   Q0 = coeff * Q1 - Q2 + (float) sample;
   Q2 = Q1;
   Q1 = Q0;
 }
 ​
 void GetRealImag(float *realPart, float *imagPart)
 {
   *realPart = (Q1 - Q2 * cosine);
   *imagPart = (Q2 * sine);
 }
 ​
 ​
 void sample(int sensorPin)
 {
   for (int index = 0; index < N; index++)
   {
     testData[index] = (byte) analogRead(0);
   }
 }
 ​
 ​
 float detect()
 {
 ​
   int index;
 ​
   float magnitudeSquared;
   float magnitude;
   float real;
   float imag;
 ​
   for (index = 0; index < N; index++)
   {
     ProcessSample(testData[index]);
   }
 ​
   GetRealImag(&real, &imag);
 ​
   magnitudeSquared = real*real + imag*imag;
   magnitude = (sqrt(magnitudeSquared)/2);
 ​
   ResetGoertzel();
   return magnitude;
 }
 ​
 ​
 void setup(){
   pinMode(led2, OUTPUT); 
   pinMode(relay, OUTPUT); 
   pinMode(A0, INPUT);    
   //Serial.begin(9600); 
   lc.shutdown(0,false);  
   lc.setIntensity(0,5);  
   lc.clearDisplay(0);  
   digitalWrite(led2, HIGH);
   digitalWrite(relay, LOW);
   inicio();
 }
 char normalizacao(float valor){
   char retorno = 0;
   if(valor>200){
     retorno += 1;
   }
   if(valor>210){
     retorno += 2;
   }
   if(valor>220){
     retorno += 4;
   }
   if(valor>260){
     retorno += 8;
   }
   if(valor>300){
     retorno += 16;
   }
   if(valor>350){
     retorno += 32;
   }
   if(valor>380){
     retorno += 64;
   }
   if(valor>400){
     retorno += 128;
   }
   return retorno;
 }

Last updated