const int MIC_PIN = 34; // Аналоговый вход
const int LED_PIN = 2; // Встроенный светодиод
const int SAMPLE_RATE = 2000; // Частота опроса (Гц)
const int SAMPLE_INTERVAL = 500; // Интервал между опросами (мкс)
const float FC = 250.0; // Частота среза 250 Гц по заданию
// Рассчитанный коэффициент для 250Гц при 2000Гц дискретизации
// alpha = (2*pi*dt*fc) / (2*pi*dt*fc + 1)
const float ALPHA = 0.44;
float filtered = 0.0;
float dc_offset = 0.0;
float rms_sum = 0.0;
int sample_count = 0;
unsigned long last_sample_time = 0;
unsigned long led_off_time = 0;
bool led_state = false;
// Порог срабатывания (подберите экспериментально под ваш микрофон)
const float THRESHOLD = 50.0;
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
// Калибровка нуля (DC Offset)
long sum = 0;
for (int i = 0; i < 1000; i++) {
sum += analogRead(MIC_PIN);
delayMicroseconds(500);
}
dc_offset = sum / 1000.0;
}
void loop() {
unsigned long now = micros();
// Чтение сигнала каждые 500 мкс (2000 Гц)
if (now - last_sample_time >= SAMPLE_INTERVAL) {
last_sample_time = now;
int raw = analogRead(MIC_PIN);
float signal = raw - dc_offset;
// ФНЧ первого порядка: отсекаем всё выше 250 Гц
// Формула: y[n] = alpha * x[n] + (1 - alpha) * y[n-1]
filtered = ALPHA * signal + (1.0 - ALPHA) * filtered;
// Считаем сумму квадратов для определения амплитуды (RMS)
rms_sum += filtered * filtered;
sample_count++;
// Анализируем каждые 100 мс (окно в 200 сэмплов) для быстрой реакции
if (sample_count >= 200) {
float rms = sqrt(rms_sum / 200);
// Если амплитуда НЧ выше порога — зажигаем светодиод
if (rms > THRESHOLD) {
digitalWrite(LED_PIN, HIGH);
led_state = true;
led_off_time = millis() + 200; // Горит минимум 200мс
}
rms_sum = 0;
sample_count = 0;
}
}
// Мягкое выключение светодиода
if (led_state && millis() > led_off_time) {
digitalWrite(LED_PIN, LOW);
led_state = false;
}
}