Так мыслишки, вроде где то уже идейку писал но вот еще разок. Надо сделать звуковой радар против дронов. А то какую то куйню в новосятх пишут, вдруг откуда ни возьмись повяилася в ... взорвал НПЗ никто не заметил как дрон пролетел через всю страну )) Пока идея, но вроде вполне реализиуема. Кому интересно может продолжить.
Или: как из «говна и палок» сделать систему раннего обнаружения летающих штук с ДВС — без радаров, без RF, без разрешений.
Если вы слышали, как скутер без глушителя переключает передачи за 5 км — вы уже наполовину звуковой радар. Осталось автоматизировать.
Задача: пассивно слушать, понимать — «это не птица», и хотя бы знать, откуда пришёл звук.
Почему INMP441? Он цифровой, малошумный, хорошо ловит низкие частоты (50–500 Гц), и его легко подключить по шине I2S к Pi.
Мы используем метод Time Difference of Arrival (TDOA):
Формула упрощённо:
Δt = (d * sin(θ)) / v → θ = arcsin((Δt * v) / d)
Где:
Δt — разница во времени,d — расстояние между микрофонами (например, 0.3 м),v — скорость звука (~343 м/с),θ — угол от перпендикуляра к базе.INMP441 — I2S-микрофон. Подключаем так:
INMP441 #1 → Raspberry Pi -------------------------------- LRCLK (WS) → GPIO18 (PIN12) BCLK (SCK) → GPIO19 (PIN35) DOUT (SD) → GPIO20 (PIN38) GND → GND 3.3V → 3.3V L/R → GND (левый) / 3.3V (правый)
То же самое — для второго микрофона, но L/R наоборот.
Включаем I2S в /boot/config.txt:
dtparam=i2s=on dtoverlay=i2s-mmap
Проверяем:
arecord -l # Должен появиться «audioinjector-pi-soundcard» или подобное
Устанавливаем зависимости:
sudo apt install python3-pip libatlas-base-dev pip3 install numpy pyaudio
Код (упрощённая версия):
import pyaudio
import numpy as np
# Настройки
RATE = 48000
CHUNK = 4096
FORMAT = pyaudio.paInt16
CHANNELS = 2
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
def cross_correlation(sig1, sig2):
corr = np.correlate(sig1 - np.mean(sig1), sig2 - np.mean(sig2), mode='full')
return corr.argmax() - (len(sig2) - 1)
while True:
data = np.frombuffer(stream.read(CHUNK), dtype=np.int16)
left = data[0::2]
right = data[1::2]
delay = cross_correlation(left, right)
# Переводим в микросекунды
dt = delay / RATE * 1e6 # мкс
print(f"Задержка: {dt:.1f} мкс")
# Пример: если |dt| > 200 мкс → есть направление
if abs(dt) > 200:
print("⚠️ Обнаружен направленный звук!")
Это база. Дальше можно:
А теоретические 20 км? Ну… если поставить такой пост в тайге ночью при инверсии — и объект с мощным мотором летит низко… почему бы и нет? Главное — **слушать первым**.
Чтобы ESP32 не тратил заряд на «прослушку вхолостую», мы добавим аналоговый звуковой сторож — простую схему, которая будит микроконтроллер только при громком звуке (например, двигателе без глушителя).
Теперь узел спит месяцами, а просыпается — только когда действительно что-то услышал.
Подключаем выход компаратора («DO» модуля KY-038 или самодельной схемы) к GPIO34 ESP32.
[Аналоговый звуковой модуль]
DO → GPIO34 (EXT0 wake-up pin)
GND → GND
VCC → 3.3V
⚠️ Только GPIO32–39 поддерживают EXT0 wake-up из deep sleep. GPIO34–39 — входы только, но этого достаточно.
Потребление: - Сторож: 0.3 мА (постоянно) - ESP32 в сне: 0.01 мА - ESP32 активен: ~80 мА, но только 2–3 сек после события Если событий мало (1–2 раза в день): → Средний ток ≈ 0.31 мА Батарея 3000 мА·ч: T = 3000 / 0.31 ≈ 9677 ч ≈ 13 месяцев!
Даже без солнца — такой узел проработает **почти год**. А с солнечной панелью — **вечно**.
Установи библиотеки: LoRa, I2S.
#include <I2S.h>
#include <LoRa.h>
#include <driver/rtc_io.h>
#define WAKEUP_PIN 34 // EXT0 pin (только 32-39)
// Настройки аудио
#define SAMPLE_RATE 16000
#define BUFFER_SIZE 1024
#define MIC_LEFT 0
void setup() {
Serial.begin(115200);
// Проверяем причину пробуждения
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
if (wakeup_reason == ESP_SLEEP_WAKEUP_EXT0) {
Serial.println("Пробуждение: громкий звук!");
// Инициализация I2S
I2S.setAllPins(25, 26, 27); // BCK, DIN, LRCK
I2S.begin(I2S_PHILIPS_MODE, SAMPLE_RATE, 16);
// Инициализация LoRa
SPI.begin(18, 19, 23, 5);
LoRa.setPins(5, 14, 2);
LoRa.begin(868E6);
LoRa.setTxPower(17);
// Анализ звука (можно улучшить)
if (detectEngine()) {
sendData(estimateAzimuth());
}
delay(1000); // дать всем завершиться
} else {
Serial.println("Холодный старт — засыпаю.");
}
// Готовимся к глубокому сну
esp_sleep_enable_ext0_wakeup((gpio_num_t)WAKEUP_PIN, 1); // HIGH = пробуждение
esp_deep_sleep_start();
}
bool detectEngine() {
int16_t samples[BUFFER_SIZE];
I2S.read(samples, BUFFER_SIZE * sizeof(int16_t));
long sum = 0;
for (int i = 0; i < BUFFER_SIZE; i += 2) {
int16_t val = samples[i + MIC_LEFT];
sum += (long)val * val;
}
float rms = sqrt((float)sum / (BUFFER_SIZE / 2));
return (rms > 1500); // порог подбирается
}
float estimateAzimuth() {
// Упрощённо: можно расширить позже
return 180.0; // заглушка
}
void sendData(float azimuth) {
LoRa.beginPacket();
LoRa.write(0xAA);
LoRa.write((uint8_t)azimuth);
LoRa.write(0x55);
LoRa.endPacket();
Serial.println("LoRa: данные отправлены");
}
Это не фантастика. Это — IoT-радар настоящего самоделкина.
Звуковой радар — это не магия. Это:
И иногда — это единственное, что замечает, что «что-то не так в небе».
Автор: самоделкин с дачи.
Лицензия: делай, копируй, улучшай — но не продавай как своё.
Обновлено: ноябрь 2025.
Блог только запустил, все статьи генерирую через нейросеть т.к. лень, возможны ошибки. Просто чтобы вы знали и не запускали ядерный реактор по моим статьям ))
Если у вас есть вопросы, или Нашли неточность? пишите в коментах — вместе поправим и сделаем статью более качественной. Я лично объясню нюансы из практики.
Комментарии
Пока нет комментариев. Будьте первым!