布线
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[i] * vReal[i] + vImag[i] * vImag[i]);
• 量级值映射到条形高度,并以条形图的形式显示在 OLED 屏幕上。
• x 轴表示频率区间,y 轴表示每个频率的幅度。
________________________________________
5. 应用
• 音频处理:识别特定频率(例如,音素、音符)。
• 机器监控:检测指示故障或磨损的异常频率。
• 质量控制:确保机器在指定的频率范围内运行。
________________________________________
要点
• FFT 将信号从时域转换为频域。
• OLED 显示屏实时可视化频谱。
• ESP32 处理采样、FFT 计算和显示更新。
________________________________________
这是使用 ESP32 和 OLED 显示屏分析音频信号或振动的一种简单有效的方法!

项目代码
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Wire.h>
#include <algorithm> // Include this for std::swap
// OLED setup
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Sound sensor setup
#define SOUND_SENSOR_PIN 2
#define SAMPLES 128 // Number of samples for FFT
#define SAMPLING_FREQ 8000 // Sampling frequency (8 kHz)
// FFT variables
float vReal[SAMPLES];
float vImag[SAMPLES];
void setup() {
Serial.begin(115200);
Wire.begin(7, 6);
// Initialize OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("FFT Audio Processing");
display.display();
delay(2000);
}
void loop() {
// Capture audio samples
for (int i = 0; i < SAMPLES; i++) {
vReal[i] = analogRead(SOUND_SENSOR_PIN);
vImag[i] = 0;
delayMicroseconds(1000000 / SAMPLING_FREQ);
}
// Perform FFT
fft(vReal, vImag, SAMPLES);
// Display FFT results on OLED
display.clearDisplay();
display.setCursor(0, 0);
display.println("Frequency Spectrum:");
for (int i = 0; i < SAMPLES / 2; i++) {
int magnitude = sqrt(vReal[i] * vReal[i] + vImag[i] * vImag[i]);
int barHeight = map(magnitude, 0, 500, 0, SCREEN_HEIGHT - 10);
display.drawLine(i * 2, SCREEN_HEIGHT, i * 2, SCREEN_HEIGHT - barHeight, SSD1306_WHITE);
}
display.display();
}
// Basic FFT implementation
void fft(float* vReal, float* vImag, int n) {
int j = 0;
for (int i = 0; i < n; i++) {
if (j > i) {
std::swap(vReal[i], vReal[j]); // Use std::swap
std::swap(vImag[i], vImag[j]); // Use std::swap
}
int m = n >> 1;
while (j >= m && m > 0) {
j -= m;
m >>= 1;
}
j += m;
}
int mmax = 1;
while (n > mmax) {
int istep = mmax << 1;
float theta = -PI / mmax;
float wtemp = sin(0.5 * theta);
float wpr = -2.0 * wtemp * wtemp;
float wpi = sin(theta);
float wr = 1.0;
float wi = 0.0;
for (int m = 0; m < mmax; m++) {
for (int i = m; i < n; i += istep) {
j = i + mmax;
float tempr = wr * vReal[j] - wi * vImag[j];
float tempi = wr * vImag[j] + wi * vReal[j];
vReal[j] = vReal[i] - tempr;
vImag[j] = vImag[i] - tempi;
vReal[i] += tempr;
vImag[i] += tempi;
}
wtemp = wr;
wr += wr * wpr - wi * wpi;
wi += wi * wpr + wtemp * wpi;
}
mmax = istep;
}
}
【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
评论