10浏览
查看: 10|回复: 2

[项目] 【Arduino 动手做】ESP32显示FFT波以识别音素、音符、节奏

[复制链接]
布线
ESP32C3
Oled GND Vcc 5v 引脚 7 SDA 和引脚 6 SCL。
声音传感器 GND Vcc 3.3v 引脚 2

傅里叶分析、相位跟踪、滤波和高级信号处理
音频处理:FFT 用于识别音素、音符、和弦和节奏 机器状态监测:FFT 用于监测机器和系统的状况 故障分析:FFT 用于分析机器和系统中的故障 质量控制:FFT 用于对带有 LCD 或 OLED 声音传感器的机器和系统进行质量控制 esp32 在这种情况下,我将它们用于声音。

硬件设置
• 声音传感器:捕获音频信号并将其转换为模拟电压电平。
• ESP32:读取来自声音传感器的模拟信号,对其进行处理,并驱动 OLED 显示屏。
• OLED 显示屏:可视化频谱或其他结果。
________________________________________
2. 采样音频
• 声音传感器连接到 ESP32 上的模拟引脚。
• ESP32 以固定的采样率(例如 8 kHz)读取模拟信号。
• 采样数据存储在两个数组中:
o vReal:存储信号的实部(实际采样值)。
o vImag:存储虚部(初始化为 0)。
________________________________________
3. 快速傅里叶变换 (FFT)
• FFT 算法将时域信号 (幅度与时间) 转换为频域 (幅度与频率)。
• fft() 函数执行以下步骤:
1. Bit-Reversal:重新排列输入数据,为 FFT 计算做准备。
2. 蝶形运算:以计算频率分量的方式组合数据。
3. Complex to Magnitude:将复数 FFT 输出转换为幅度值,该值表示每个频率分量的强度。
________________________________________
4. 显示结果
• 每个频率区间的幅值使用以下公式计算:
• 幅度 = sqrt(vReal * vReal + vImag * vImag);
• 量级值映射到条形高度,并以条形图的形式显示在 OLED 屏幕上。
• x 轴表示频率区间,y 轴表示每个频率的幅度。
________________________________________
5. 应用
• 音频处理:识别特定频率(例如,音素、音符)。
• 机器监控:检测指示故障或磨损的异常频率。
• 质量控制:确保机器在指定的频率范围内运行。
________________________________________
要点
• FFT 将信号从时域转换为频域。
• OLED 显示屏实时可视化频谱。
• ESP32 处理采样、FFT 计算和显示更新。
________________________________________
这是使用 ESP32 和 OLED 显示屏分析音频信号或振动的一种简单有效的方法!

【Arduino 动手做】ESP32显示FFT波以识别音素、音符、节奏图1

驴友花雕  中级技神
 楼主|

发表于 昨天 20:03

【Arduino 动手做】ESP32显示FFT波以识别音素、音符、节奏

项目代码

  1. #include <Adafruit_SSD1306.h>
  2. #include <Adafruit_GFX.h>
  3. #include <Wire.h>
  4. #include <algorithm> // Include this for std::swap
  5. // OLED setup
  6. #define SCREEN_WIDTH 128
  7. #define SCREEN_HEIGHT 64
  8. #define OLED_RESET    -1
  9. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  10. // Sound sensor setup
  11. #define SOUND_SENSOR_PIN 2
  12. #define SAMPLES 128              // Number of samples for FFT
  13. #define SAMPLING_FREQ 8000       // Sampling frequency (8 kHz)
  14. // FFT variables
  15. float vReal[SAMPLES];
  16. float vImag[SAMPLES];
  17. void setup() {
  18.   Serial.begin(115200);
  19.   Wire.begin(7, 6);
  20.   // Initialize OLED
  21.   if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  22.     Serial.println(F("SSD1306 allocation failed"));
  23.     for (;;);
  24.   }
  25.   display.clearDisplay();
  26.   display.setTextSize(1);
  27.   display.setTextColor(SSD1306_WHITE);
  28.   display.setCursor(0, 0);
  29.   display.println("FFT Audio Processing");
  30.   display.display();
  31.   delay(2000);
  32. }
  33. void loop() {
  34.   // Capture audio samples
  35.   for (int i = 0; i < SAMPLES; i++) {
  36.     vReal[i] = analogRead(SOUND_SENSOR_PIN);
  37.     vImag[i] = 0;
  38.     delayMicroseconds(1000000 / SAMPLING_FREQ);
  39.   }
  40.   // Perform FFT
  41.   fft(vReal, vImag, SAMPLES);
  42.   // Display FFT results on OLED
  43.   display.clearDisplay();
  44.   display.setCursor(0, 0);
  45.   display.println("Frequency Spectrum:");
  46.   for (int i = 0; i < SAMPLES / 2; i++) {
  47.     int magnitude = sqrt(vReal[i] * vReal[i] + vImag[i] * vImag[i]);
  48.     int barHeight = map(magnitude, 0, 500, 0, SCREEN_HEIGHT - 10);
  49.     display.drawLine(i * 2, SCREEN_HEIGHT, i * 2, SCREEN_HEIGHT - barHeight, SSD1306_WHITE);
  50.   }
  51.   display.display();
  52. }
  53. // Basic FFT implementation
  54. void fft(float* vReal, float* vImag, int n) {
  55.   int j = 0;
  56.   for (int i = 0; i < n; i++) {
  57.     if (j > i) {
  58.       std::swap(vReal[i], vReal[j]); // Use std::swap
  59.       std::swap(vImag[i], vImag[j]); // Use std::swap
  60.     }
  61.     int m = n >> 1;
  62.     while (j >= m && m > 0) {
  63.       j -= m;
  64.       m >>= 1;
  65.     }
  66.     j += m;
  67.   }
  68.   int mmax = 1;
  69.   while (n > mmax) {
  70.     int istep = mmax << 1;
  71.     float theta = -PI / mmax;
  72.     float wtemp = sin(0.5 * theta);
  73.     float wpr = -2.0 * wtemp * wtemp;
  74.     float wpi = sin(theta);
  75.     float wr = 1.0;
  76.     float wi = 0.0;
  77.     for (int m = 0; m < mmax; m++) {
  78.       for (int i = m; i < n; i += istep) {
  79.         j = i + mmax;
  80.         float tempr = wr * vReal[j] - wi * vImag[j];
  81.         float tempi = wr * vImag[j] + wi * vReal[j];
  82.         vReal[j] = vReal[i] - tempr;
  83.         vImag[j] = vImag[i] - tempi;
  84.         vReal[i] += tempr;
  85.         vImag[i] += tempi;
  86.       }
  87.       wtemp = wr;
  88.       wr += wr * wpr - wi * wpi;
  89.       wi += wi * wpr + wtemp * wpi;
  90.     }
  91.     mmax = istep;
  92.   }
  93. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 20:07

【Arduino 动手做】ESP32显示FFT波以识别音素、音符、节奏

【Arduino 动手做】ESP32显示FFT波以识别音素、音符、节奏
项目链接:https://www.youtube.com/watch?v=pwi9sBT3_-E
项目作者:Electricum

项目视频 :https://www.youtube.com/watch?v=pwi9sBT3_-E
项目代码:https://github.com/ukkokalevala/FFTThinBars


【Arduino 动手做】ESP32显示FFT波以识别音素、音符、节奏图2

【Arduino 动手做】ESP32显示FFT波以识别音素、音符、节奏图1

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail