Микрофон2
- Войдите на сайт для отправки комментариев
Всем привет!
Прошу прощения, что создаю новую тему по старому вопросу. Не нашел как можно удалить старую тему.
В ходе разбирательств с работой микрофона и ардуино нашел библиотеку для записи аудио файлов на сд карту. Большими усилиями я переделал найденные примеры в сети и получил код для записи на карту звуков определенной длительности (задается в начале скетча). Запись начинается путем нажатия на кнопку. Используются Ардуино Нано, МАХ9814, Модуль для микроСД карт HW-125.
Проблема в том, что если скетч из примера работает идеально, то мой не записывает данные на карту.
К сожалению, я не понимаю где ошибка в коде. Может быть кто-то на форуме ее найдет.
Инициализация микросд карты проходит норм - в мониторе порта SD OK
При нажатии на кнопку идет сообщения о старте записи, а далее об ее окончании
#include <SD.h>
#include <SPI.h>
#include <TMRpcm.h>
#include <EEPROM.h>
#define SD_ChipSelectPin 4 //using digital pin 4 on arduino nano 328, can use other pins , CS
#define microphone_pin A0
TMRpcm audio; // create an object for use in this sketch
int RecordNumber;
char FileName[10];
const int buttonPin = 8; // the number of the pushbutton pin
const int ledPin = 6; // the number of the LED pin
int buttonState; // variable for reading the pushbutton status
int recordState = 0; // if the recording is going on
int recordTime = 3; // sec
void setup() {
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output
pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input
pinMode(12,OUTPUT); //Pin pairs: 9,10 Mega: 5-2,6-7,11-12,46-45, MISO
Serial.begin(9600);
if (!SD.begin(SD_ChipSelectPin)) {
Serial.println("sd faild");
return;
}else{
Serial.println("SD OK");
}
// The audio library needs to know which CS pin to use for recording
audio.CSPin = SD_ChipSelectPin;
RecordNumber = EEPROM.read(0);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
Serial.println("button is pressed");
RecordNumber++;
EEPROM.write(0, RecordNumber);
sprintf(FileName,"Audio_%d.wav", RecordNumber);
audio.startRecording(FileName,16000,microphone_pin);
Serial.println("recording start");
digitalWrite(ledPin, HIGH);
delay(recordTime*1000);
audio.stopRecording(FileName);
Serial.println("recording stopped");
digitalWrite(ledPin, LOW);
}
}
А зачем вы заказываете запись 16сек длиной, а прерываете ее через три?
Скажу честно, я не знаю точно как это работает, но скорее всего это приводит к сбросу записи и ничего не сохраняется либо же файл получается "битый".
Здравствуйте!
Если Вы про 44 строчку, то 16000 это задается частота дискретизации
Проблема в том, что если скетч из примера работает идеально, то мой не записывает данные на карту.
а если сравнить ваш скетч и пример - в чем разница? она вроде должна быть очевидна, там кода-то всего ничего
Разница большая. Вот стандартный пример из библиотеки
#include <SD.h> #include <SPI.h> #include <TMRpcm.h> //#define SD_ChipSelectPin 53 //example uses hardware SS pin 53 on Mega2560 #define SD_ChipSelectPin 10 //using digital pin 4 on arduino nano 328, can use other pins #define microphone_pin A0 TMRpcm audio; // create an object for use in this sketch void setup() { pinMode(12,OUTPUT); //Pin pairs: 9,10 Mega: 5-2,6-7,11-12,46-45 Serial.begin(9600); if (!SD.begin(SD_ChipSelectPin)) { Serial.println("sd faild"); return; }else{ Serial.println("SD OK"); } // The audio library needs to know which CS pin to use for recording audio.CSPin = SD_ChipSelectPin; } void loop() { if(Serial.available()){ //Send commands over serial to play switch(Serial.read()){ case 'r': audio.startRecording("test.wav",16000,microphone_pin); Serial.println("recording start"); break; //Record at 16khz sample rate on pin A0 case 's': audio.stopRecording("test.wav"); Serial.println("recording stopped"); break; //Stop recording } } }Тут пример из видео на ютубе
#include <SD.h> #include <SPI.h> #include <TMRpcm.h> #include <EEPROM.h> #define ENABLE_DEBUG //Включение вывода отладочной информации через Serial. Только для отладки! Закоментировать эту строку перед заливкой в готовое устройство! #define SD_ChipSelectPin 10 // #define ledStart 2 /* PIN LED Start */ #define ledStop 3 /* PIN LED Stop */ #define MicPin A1 // Аналоговый пин, к которму подключен микрофон char NameRecord[10]; // Имя нового - записываемого файла на SD-карту int RecordNumber; // Номер записи - храним в EEPROM. в диапазоне от 0 до 32767 byte Recording = 0; // Переменная определяет идет сейчас запись или нет //----------------------------------------------- int RecInterval = 5; //! Минимальная продолжительность записи в секундах ! //----------------------------------------------- unsigned long TimeInterval = 0; // Переменная для вычисления времени int MaxAnalogPinValue = 1000; // Уровень сигнала на аналоговом входе при котором произойдет старт записи // Значение подбирается индивидуально! (100 - 1023) int SaveADC1 = 0; int SaveADC2 = 0; unsigned int sample; unsigned int signalMax = 0; unsigned int signalMin = 256; unsigned int peakToPeak = 0; #define peakToPeakMinLevel 200 // Уровень срабатывания на звук. Значение подбирается индивидуально! // Максимальное значение - 255 TMRpcm audio; // create an object for use in this sketch void setup() { #if defined (ENABLE_DEBUG) Serial.begin(9600); #endif pinMode(ledStart, OUTPUT); pinMode(ledStop, OUTPUT); //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 defined (ENABLE_DEBUG) Serial.print("Analog level: "); Serial.println(AnR); #endif if (AnR >= MaxAnalogPinValue) { #if defined (ENABLE_DEBUG) Serial.print("Start recording! File: "); Serial.print(RecordNumber+1); Serial.println(".wav"); #endif StartRec(); } } if (Recording == 1){ sample = ADCH; if (sample < 256) { if (sample > signalMax) { signalMax = sample; // save just the max levels } else if (sample < signalMin) { signalMin = sample; // save just the min levels } } #if defined (ENABLE_DEBUG) Serial.print("Max MIC signal: "); Serial.println(signalMax); #endif if (millis() - TimeInterval >= RecInterval) { peakToPeak = signalMax - signalMin; signalMax = 0; signalMin = 256; #if defined (ENABLE_DEBUG) Serial.print("peakToPeak = "); Serial.println(peakToPeak); #endif if (peakToPeak < peakToPeakMinLevel) { analogRead(MicPin); StopRec(); #if defined (ENABLE_DEBUG) Serial.println("Recording stopped"); #endif }else{ TimeInterval = millis()-1; #if defined (ENABLE_DEBUG) Serial.println("Continue recording..."); #endif } } } } void StartRec() { // begin recording process SaveADC1 = ADCSRA; SaveADC2 = ADCSRB; Recording = 1; digitalWrite(ledStop, HIGH); digitalWrite(ledStart, LOW); RecordNumber++; if (RecordNumber > 32766) = 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; ADCSRA = SaveADC1; ADCSRB = SaveADC2; }Я брал некоторые команды из второго скетча.
И хотел сделать так, чтобы ардуина записывала трек определенной длины
обратите внимание, что в обоих примерах кода не используется delay(). а у вас - оно присутсвует именно во время записи.
Поскольку delay() блокирует контроллер, вероятно МК не может записывать звук в это время
ага, а как тогда можно сделать так, чтобы он записывал звук именно определенное время.
пример
спасибо! попробую сегодня-завтра. отпишусь о результатах.
По моему delay() в данном случае не виновен.
Проверить можно изменив заведомо рабочий скетч примера, добавив после команды старта команду delay(30000) (числом 30000 а не переменной для определенности) и команду окончания записи.
Дополнено позже. ошибочно написал 30000 вместо 3000
Всем привет!
Мы с другом сидели с кодом часа два и поняли в чем ошибка.
строчка 10
в ней задаются биты для имени файла. их было недостаточно. то есть здесь нужно вставить большее значение)
делэй не при чем )
Строка 22 из первого сообщения не мешает?
pinMode(12,OUTPUT);
(на симуляторе для UNO мешает, т.к. 12 это MISO и используется для обмена с SD)
НАДА БОООЛЬШЕ БИТОВ!!! для имени файла, всё дело в этом!!!
Пидец. Не угадал.
Строка 22 из первого сообщения не мешает?
pinMode(12,OUTPUT);
(на симуляторе для UNO мешает, т.к. 12 это MISO и используется для обмена с SD)
нет, не мешает) к 12 пину как раз подключается MISO :)