В этой статье мы рассмотрим создание на основе платы Arduino компактного устройства для записи голоса, которое при желании можно использовать в качестве подслушивающего устройства (шпионского "жучка)" или диктофона. Наше устройство будет содержать небольшой микрофон для записи голоса и последующего сохранения его на SD карту. Оно будет способно записывать фрагменты звука длительностью до 2 минут, эти фрагменты будут иметь последовательную нумерацию. Запись звука будет производиться до тех пор пока не закончится заряд батареи или не закончится место на SD карте. Для индикации того, что начался процесс записи, мы подключили к плате Arduino светодиод.
Примечание: этот проект рассматривается на нашем сайте исключительно в образовательных целях, его применение для незаконного подслушивания других людей может преследоваться по закону.
Необходимые компоненты
- Плата Arduino Nano (купить на AliExpress).
- MAX9814 Amplifier board (плата усиления, плата микрофона) (купить на AliExpress).
- Модуль чтения SD карт (купить на AliExpress).
- SD карта.
- Источник питания с напряжением 5 В (power bank, батарейка или что-нибудь подобное).
Внешний вид используемых в проекте компонентов показан на следующем рисунке.
Схема проекта
Схема шпионского подслушивающего устройства на Arduino представлена на следующем рисунке.
Основным компонентом нашего проекта является модуль MAX9814, который представляет собой высокопроизводительный микрофонный усилитель с автоматической регулировкой усиления (automatic gain control, AGC) и низким уровнем вносимых шумов, отличающийся низкой стоимостью. Модуль содержит малошумящий входной (front-end) усилитель, усилитель с изменяющимся коэффициентом усиления (variable gain amplifier, VGA), выходной усилитель, генератор напряжения смещения для микрофона и схему автоматической регулировки усиления – и все это на одном чипе.
Модуль MAX9814 будет записывать звук и передавать его в плату Arduino, которая будет преобразовывать его в .wav формат и сохранять его на MicroSD карту с помощью модуля чтения/записи SD карт, подключенного к плате Arduino.
Модуль MAX9814 содержит достаточно много различных контактов, но мы из них будем использовать всего 3: VCC, GND и выходной контакт. Также модуль содержит контакт усиления (gain pin), который можно подключить к GND или VDD для контролируемого усиления 50dB и 40dB. Но в нашем проекте мы не будем использовать управление усилением модуля, по умолчанию модуль MAX9814 обеспечивает коэффициент усиления равный 60dB.
Для взаимодействия с модулем SD карт мы будем использовать интерфейс SPI, для этого мы задействовали контакты интерфейса SPI платы Arduino.
Контакты платы Arduino | Контакты модуля SD карт |
5V | VCC |
GND | GND |
D10 | CS |
D11 | MOSI |
D12 | MISO |
D13 | SCK |
Контакты подключения модуля MAX9814 к плате Arduino представлены в следующей таблице.
Контакты платы Arduino | Контакты модуля MAX9814 |
3.3V | VDD |
GND | GND |
A0 | OUT |
Аудио сигнал будет сохраняться фрагментами по 2 минуты, после окончания этого интервала будет создаваться новый файл для записи очередного фрагмента.
Объяснение программы для Arduino
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
В начале кода программы подключим заголовочные файлы используемых библиотек.
1 2 3 |
#include <TMRpcm.h> #include <SD.h> #include <SPI.h> |
Для взаимодействия с модулем MAX9814 с сервиса GitHub скачайте библиотеку TMRpcm.
В следующих строчках кода зададим префикс имени и тип (расширение) файлов, в которые будут сохраняться фрагменты звука. Таким образом, мы будем использовать файлы вида spyxxx.wav.
1 2 3 4 |
TMRpcm audio; // make instance variable int file_number = 0; char filePrefixname[50] = "spy"; char exten[10] = ".wav"; |
Также зададим необходимые переменные. Микрофон в нашем проекте доступен на контакте A0 с частотой дискретизации (sample rate) 16000 Гц.
1 2 3 |
const int recordLed = 2; const int mic_pin = A0; const int sample_rate = 16000; |
В следующем фрагменте кода мы печатаем необходимую информацию в окно монитора последовательной связи.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#define SD_CSPin 10 // defines the CS pin of the SD card. // delay function for serial log. void wait_min(int mins) { int count = 0; int secs = mins * 60; while (1) { Serial.print('.'); delay(1000); count++; if (count == secs) { count = 0; break; } } Serial.println(); return ; } |
В следующем фрагменте кода мы инициализируем последовательную связь (для целей отладки), устанавливаем режимы работы используемых контактов (на ввод или вывод данных). Также мы проверяем возможность работы с SD картой (правильно ли она установлена) и выдаем сообщение об ошибке если ее невозможно инициализировать.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void setup() { // put your setup code here, to run once: //initializes the serial connection between the Arduino and any connected serial device(e.g. computer, phone, raspberry pi...) Serial.begin(9600); //Sets up the pins pinMode(mic_pin, INPUT); pinMode(recordLed, OUTPUT); Serial.println("loading... SD card"); if (!SD.begin(SD_CSPin)) { Serial.println("An Error has occurred while mounting SD"); } while (!SD.begin(SD_CSPin)) { Serial.print("."); delay(500); } audio.CSPin = SD_CSPin; } |
В основном цикле программы loop мы производим запись голоса. Записанный голос мы сохраняем на SD карту, номер файла на которой увеличивается каждый раз когда закончилось время записи в предыдущий файл.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
void loop() { Serial.println("####################################################################################"); char fileSlNum[20] = ""; itoa(file_number, fileSlNum, 10); char file_name[50] = ""; strcat(file_name, filePrefixname); strcat(file_name, fileSlNum); strcat(file_name, exten); Serial.print("New File Name: "); Serial.println(file_name); digitalWrite(recordLed, HIGH); audio.startRecording(file_name, sample_rate, mic_pin); Serial.println("startRecording "); // record audio for 2mins. means, in this loop process record 2mins of audio. // if you need more time duration recording audio then // pass higher value into the wait_min(int mins) function. wait_min(2); // This is the length of the audio file which is set to 2 minutes digitalWrite(recordLed, LOW); audio.stopRecording(file_name); Serial.println("stopRecording"); file_number++; Serial.println("####################################################################################"); } |
Тестирование работы проекта
После того как аппаратная часть проекта будет готова, можете загружать программу в плату Arduino. После загрузки программы устройство начнет запись звука. Работа устройства была проверена с помощью мобильного телефона. Более подробно все эти процессы можно посмотреть на видео, приведенном в конце статьи.
Исходный код программы (скетча)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
/* File Name: spy-recorder.ino Created on: 7-Jan-2021 Author: Noyel Seth (noyelseth@gmail.com) */ /* Hardware Pinout Connection Arduino Nano SD Pin 5v ------------ VCC GND ----------- GND D10 ----------- CS D11 ----------- MOSI D12 ----------- MISO D13 ----------- SCK ________________________________________ Arduino Nano MAX9814 3.3v ----------- VDD GND ------------ GND A0 ------------- Out ________________________________________ Arduino Nano D2 pin user for Led to notify that record is in process. */ /* use Link: https://www.arduino.cc/reference/en/libraries/tmrpcm/ TMRpcm library for recording audio using MAX9814 Recording a WAV file to an SD card is an advanced feature of the TMRpcm library so you must edit the library configuration file in order to use it. It simply searches the file "pcmConfig.h" using File Explorer and disables a few lines of code (then saves it). 1. On Uno or non-mega boards uncomment the line #define buffSize 128 2. Also uncomment #define ENABLE_RECORDING and #define BLOCK_COUNT 10000UL */ #include <TMRpcm.h> #include <SD.h> #include <SPI.h> TMRpcm audio; int file_number = 0; char filePrefixname[50] = "spy"; char exten[10] = ".wav"; const int recordLed = 2; const int mic_pin = A0; const int sample_rate = 16000; #define SD_CSPin 10 // с помощью этой функции мы затем будем отмерять 2-х минутные интервалы void wait_min(int mins) { int count = 0; int secs = mins * 60; while (1) { Serial.print('.'); delay(1000); count++; if (count == secs) { count = 0; break; } } Serial.println(); return ; } void setup() { // put your setup code here, to run once: //initialises the serial connection (инициализируем последовательную связь) between the arduino and any connected serial device(e.g. computer, phone, raspberry pi...) Serial.begin(9600); //задаем режимы работы используемых контактов pinMode(mic_pin, INPUT); pinMode(recordLed, OUTPUT); Serial.println("loading... SD card"); if (!SD.begin(SD_CSPin)) { Serial.println("An Error has occurred while mounting SD"); } while (!SD.begin(SD_CSPin)) { Serial.print("."); delay(500); } audio.CSPin = SD_CSPin; } void loop() { Serial.println("####################################################################################"); char fileSlNum[20] = ""; itoa(file_number, fileSlNum, 10); char file_name[50] = ""; strcat(file_name, filePrefixname); strcat(file_name, fileSlNum); strcat(file_name, exten); Serial.print("New File Name: "); Serial.println(file_name); digitalWrite(recordLed, HIGH); audio.startRecording(file_name, sample_rate, mic_pin); Serial.println("startRecording "); // записываем аудио в течение 2-х минут // если вам необходимо записывать аудио в течение большего интервала // то подставьте большее значение в параметр функции wait_min(int mins) wait_min(2); //отмеряем 2-х минутный интервал digitalWrite(recordLed, LOW); audio.stopRecording(file_name); Serial.println("stopRecording"); file_number++; Serial.println("####################################################################################"); } |
Здравствуйте, при подключении к компу все работает как часы, при подключении к повербанку создает файлы но не записывает ничего
Добрый вечер. А вы повербанк к плате через USB подключаете или каким то другим образом?
Инструкция для тех, у кого вылетает ошибка 'class TMRpcm' has no member named 'stopRecording':
1. переходите в папку с библиотекой TMRpcm
2. ищете файл pcmConfig.h, открываете для изменения
3. ищете и убираете слеши (раскомментировать надо) у следующих строк:
1. #define buffSize 128
2. #define ENABLE_RECORDING
3. #define BLOCK_COUNT 10000UL
у меня после этого всё заработало. profit!
Хорошо, спасибо вам за конструктивный комментарий к данной статье
Собрал всё по вашей схеме, но добавил на аналоговый пин 1 аналоговую клавиатуру, опрашиваемую через AnalogRead. Всё, что у вас в loop, записал в отдельную функцию, но появилась проблема - после использования этой функции AnalogRead зависает и показывает одно и то же значение, то, которое было в момент выхода из функции. Не подскажите, почему так может быть?
Сложно сказать почему так происходит. Попробуйте по очереди убирать из функции фрагменты кода, так вы найдете фрагмент из-за которого возникает проблема, а потом в этом фрагменте можно аналогичным образом найти проблемную строку.
Так, что насчет audio.startRecording(file_name, sample_rate, mic_pin); ?????
Ошибка не исправлена..
О какой именно ошибке идет речь? Самые нижние комментарии к этой статье говорят о том, что с этой строкой должно быть все хорошо
Устанавливаем библтотеку TMRpcm-master.zip Затем запускаем тестовый пример из этой библиотеки или ваш скетч. запускаем компиляцию и получаем эту ошибку..
При установке библиотеки TMRpcm точно такая же ошибка.
Ошибка полностью:
Arduino: 1.8.16 (Mac OS X), Плата:"Arduino Nano, ATmega328P (Old Bootloader)"
/var/folders/vj/47cqjxrj2ms5wxhlsnq84nqc0000gn/T/arduino_modified_sketch_909951/Recording.ino: In function 'void loop()':
Recording:58:25: error: 'class TMRpcm' has no member named 'startRecording'
case 'r': audio.startRecording("test.wav",16000,A0); break; //Record at 16khz sample rate on pin A0
^~~~~~~~~~~~~~
Recording:59:25: error: 'class TMRpcm' has no member named 'startRecording'
case 'R': audio.startRecording("test.wav",16000,A0,1); break; //Record, but with passthrough to speaker.
^~~~~~~~~~~~~~
Recording:60:25: error: 'class TMRpcm' has no member named 'startRecording'
case 't': audio.startRecording("test.wav",16000,A0,2); break; //Do not record. Output direct to speaker
^~~~~~~~~~~~~~
exit status 1
'class TMRpcm' has no member named 'startRecording'
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
https://github.com/TMRh20/TMRpcm/blob/master/TMRpcm.h - строка № 80, там есть метод startRecording. Поэтому мне сложно, к сожалению, сказать, из-за чего возникает эта ошибка. Можно попробовать удалить строку № 81 из библиотеки, но шансы малы что это поможет. Уберите из программы все, кроме запуска функции startRecording и строк, необходимых для ее запуска. Посмотрите, будет ли выдаваться ошибка
Выдает следующую ошибку:
sketch_apr26a:111:9: error: 'class TMRpcm' has no member named 'startrecording'
sketch_apr26a:118:9: error: 'class TMRpcm' has no member named 'stopRecording'
exit status 1
'class TMRpcm' has no member named 'startrecording'
Библиотеку подключил. Что сделать в таком случае?
Сложно так сразу сказать из-за чего такая ошибка если библиотека корректно установлена. Попробуйте удалить из программы все строки в которых используются методы, на которые у вас выдается ошибка. Или вообще оставить в программе только минимум строк. Заработает в этом случае или нет.
Я посмотрел исходники библиотеки (https://github.com/TMRh20/TMRpcm/blob/master/TMRpcm.h), там есть методы startRecording и stopRecording, строки с 80 по 83
Спасибо. Интересный проект. Постараюсь разобраться. Мне нужен прибор для перевода на СД карту 2-х канального аналогового стереосигнала с высоким качеством. Не думал даже что ардуино это сможет. Но нужно попробовать.
Спасибо что оценили наш труд. Будем признательны если потом отпишитесь о результатах ваших экспериментов
Можно ли сделать так, чтобы:
1) между записями была пауза (например, 2 минуты записывает, 8 минут - нет)?
2) запись производилась только в определенное время суток (например, с 6 до 9 часов утра)?
3) в названии файлов записи была дата и время записи (например, 20230102_170100.wav)
1. Поместить процесс записи в цикл, в котором 2 минуты пишете, а потом на 8 минут ставите паузу.
2. Использовать модуль часов реального времени, например, DS1307, или определять время по протоколу NTP - в этом случае Ардуино необходимо будет подключить к интернету, например, с помощью модуля ESP8266.
3. С помощью строковой переменной можно сконструировать любое допустимое для SD карты имя файла
Как же вы утомили своими недопримерами!
Где функция audio.startRecording(file_name, sample_rate, mic_pin); ?????
Чем вы дышите?
Опечатка в коде? Где конкретно, не подскажите?
Импортировали библиотеку.
TMRpcm audio; // create an object for use in this sketch
Сам сначала разберись.
И что вы хотели этим сказать?
То, что Евгений не разобрался в коде и фигню несёт.
Хорошо, будем надеяться что он уже разобрался