Официальный сайт компании Arduino по адресу arduino.cc
Диктофон Ардуино с активацией по голосу
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Всем привет!
Делаю диктофон на ардуино. Микрофон - MAX4466, подключен к любому аналоговому пину (А1), TL431 к AREF и по SPI подключена MicroSD.
Скетч:
/* This sketch demonstrates recording of standard WAV files that can be played on any device that supports WAVs. The recording uses a single ended input from any of the analog input pins. Uses AVCC (5V) reference currently. Requirements: Class 4 or 6 SD Card Audio Input Device (Microphone, etc) Arduino Uno,Nano, Mega, etc. Steps: 1. Edit pcmConfig.h a: On Uno or non-mega boards, #define buffSize 128. May need to increase. b: Uncomment #define ENABLE_RECORDING and #define BLOCK_COUNT 10000UL 2. Usage is as below. See https://github.com/TMRh20/TMRpcm/wiki/Advanced-Features#wiki-recording-a... for additional informaiton. Notes: Recording will not work in Multi Mode. Performance is very dependant on SD write speed, and memory used. Better performance may be seen using the SdFat library. See included example for usage. Running the Arduino from a battery or filtered power supply will reduce noise. */ #include <SD.h> #include <SPI.h> #include <TMRpcm.h> #include <EEPROM.h> #define SD_ChipSelectPin 10 // #define ledStart 2 /* PIN LED Start */ #define ledStop 3 /* PIN LED Stop */ #define MicPin A1 /* PIN LED Stop */ char NameRecord[10]; // Имя нового - записываемого файла на SD-карту int RecordNumber; // Номер записи - храним в EEPROM. в диапазоне от 0 до 32767 byte Recording = 0; // Переменная определяет идет сейчас запись или нет int RecInterval = 5; // Минимальная продолжительность записи в секундах unsigned long TimeInterval = 0; // Переменная для вычисления времени int MaxAnalogPinValue = 1000; // Уровень сигнала на аналоговом входе при котором произойдет старт записи // TMRpcm audio; // create an object for use in this sketch void setup() { Serial.begin(9600); pinMode(ledStart, OUTPUT); pinMode(ledStop, OUTPUT); //pinMode(14, OUTPUT); //A0 //pinMode(16, OUTPUT); //A2 //digitalWrite(14, LOW); //digitalWrite(16, LOW); audio.speakerPin = 11; //5,6,11 or 46 on Mega, 9 on Uno, Nano, etc pinMode(10,OUTPUT); //Pin pairs: 9,10 Mega: 5-2,6-7,11-12,46-45 if (!SD.begin(SD_ChipSelectPin)) { digitalWrite(ledStop, LOW); digitalWrite(ledStart, LOW); return; }else{ digitalWrite(ledStop, LOW); digitalWrite(ledStart, HIGH); } analogReference(EXTERNAL); // The audio library needs to know which CS pin to use for recording audio.CSPin = SD_ChipSelectPin; RecordNumber = EEPROM.read(0); RecInterval = RecInterval * 1000; } void loop() { if (Recording == 0){ int AnR = analogRead(MicPin); if (AnR >= MaxAnalogPinValue) { Serial.println(1); StartRec(); } } if (Recording == 1 && millis() - TimeInterval >= RecInterval) { if (analogRead(MicPin) < MaxAnalogPinValue) { StopRec(); Serial.println(2); }else{ TimeInterval = millis()-1; Serial.println(3); } } } void StartRec() { // begin recording process Recording = 1; digitalWrite(ledStop, HIGH); digitalWrite(ledStart, LOW); RecordNumber++; if (RecordNumber > 32766)RecordNumber = 0; // небольшое огриничение в номерации файлов EEPROM.write(0, RecordNumber); // Сохранение в EEPROM номера последнего аудиофайла TimeInterval = millis(); // Запоминаем millis для отсчета времени записи sprintf(NameRecord,"%d.wav", RecordNumber); // создаем название файла из номера и расширения ".wav" audio.startRecording(NameRecord, 16000, MicPin, 0);// Старт записи } void StopRec() { // stop recording process, close file audio.stopRecording(NameRecord);// Стоп записи digitalWrite(ledStop, LOW); digitalWrite(ledStart, HIGH); Recording = 0; }
Библиотека: https://github.com/TMRh20/TMRpcm
Пытаюсь сделать активацию записи голосом. То есть если превысить звуковой порог - включится запись. Дольше, через определенный интервал проверять наличие звукового сигнала. Это в LOOP прописано в условии:
if (Recording == 1 && millis() - TimeInterval >= RecInterval) {
И если есть звуковой сигнал - то продолжать запись. Если нет, то тогда стоп записи. Вроде должно все работать, но не работает! Проблема в том что после выполнения команды:
audio.startRecording(NameRecord, 16000, MicPin, 0);// Старт записи
обращение к аналоговому пину происходит неправильно! Вместо нормального значения возвращается постоянное и неизменное значение - 840. Из-за этого не срабатывает функция "продления" записи, так как не получает необходимого значения... И из-за этого не стартует новая запись после остановки предыдущей записи. Это можно как-то исправить? Есть какие-то идеи?
А автор кода чего говорит?
Я лишь взял пример из библиотеки:
И пытаюсь его переделать под управление голосом. Изначально запись стартовала и останавливалась через сериал. Почитал что пишут на Гитхабе.. Библиотека задействует таймеры, настраивает АЦП, и даже отключает его. Вот кусок из библиотеки:
Я решил эту проблему так: сохраняю начальное значения ADCSRA и ADCSRB, и после их восстанавливаю:
Это решило проблему с неработающим analogRead().
Осталось только придумать способ правильно "понимать" что речь все еще звучит. Простое
if
(analogRead(MicPin) < MaxAnalogPinValue) {
Не срабатывает, так как часто "ловит" не самый высокий фронт звуковой волны, из-за чего "думает" что уже тихо, и нет звука...
Я лишь взял пример из библиотеки:
Так я и спрашиваю Вас, что говорит автор примера/библиотеки. Вы его спрашивали?
Я ему описал все, пока что молчит. По поводу работы АЦП уже подымался вопрос: https://github.com/TMRh20/TMRpcm/issues/101
Но автор не стал это включать в библиотеку. Я это исправление использовал в скетче, по этому Старт/стоп стали работать нормально. Сейчас для меня стоит вопрос как правильно считать значение с аналогового входа, так чтобы понять что есть постоянный звук. Ведь звук - колебание. И если просто делать analogRead(MicPin) то легко можно попасть на уровень, не соответствующий заданному, хотя это все равно будет звуковой волной.
Все, проблему решил. Вот полный скетч: