Чт дек 12, 2019 15:51:51
#include <SdFat.h> /* Библиотека для SD-карты */
#include <EEPROM.h>
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
SdFat sd;
SdFile rec;
#define chipSelect 10 /* Поменял на 10-pln */
unsigned long fileSize = 0L;
unsigned long waveChunk = 16;
unsigned int waveType = 1;
unsigned int numChannels = 1;
unsigned long sampleRate = 22050;
unsigned long bytesPerSec = 22050;
unsigned int blockAlign = 1;
unsigned int bitsPerSample = 8;
unsigned long dataSize = 0L;
unsigned long recByteCount = 0L;
unsigned long recByteSaved = 0L;
#define ledStart 2 /* PIN LED Start */
#define ledStop 3 /* PIN LED Stop */
int recPressed = 0;
int stopPressed = 0;
unsigned long oldTime = 0L;
unsigned long newTime = 0L;
byte buf00[512]; // buffer array 1
byte buf01[512]; // buffer array 2
byte byte1, byte2, byte3, byte4;
unsigned int bufByteCount;
byte bufWrite;
/*_____________*/
char NameRecord[10]; /* Имя нового - записываемого файла на SD-карту. */
int RecordNumber; /* Номер записи - храним в EEPROM. в диапазоне от 0 до 32767. */
unsigned long TimeIntervalStopRecording; /* Время - интервал - остановки записи - time interval stop recording */
byte OnOffRecord; /* подготовка - к старту записи */
/*_____________*/
void setup() { // THIS RUNS ONCE
pinMode(10, OUTPUT);
pinMode(ledStart, OUTPUT);
pinMode(ledStop, OUTPUT);
/* Функция analogReference определяет опорное напряжение относительно которого
происходят аналоговые измерения в analogRead().
EXTERNAL: внешний источник опорного напряжения, подключенный к выводу AREF.
1. Чтобы уменьшить шумы во время записи.
2. Возможность аппаратного изменения звукового порога, срабатывания авто записи,
подключив переменный резистор к (выводу-AREF). */
analogReference(EXTERNAL);
/*_____________*/
Setup_timer2();
Setup_ADC();
/* Если SD-карта не обнаружена - включаем ledStop и ledStart*/
if (!sd.begin(chipSelect, SPI_FULL_SPEED)) { // if error, flash LED twice per second, until reset.
while (1) {
delay(50);
digitalWrite(ledStop, LOW);
digitalWrite(ledStart, LOW);
}
}
digitalWrite(ledStop, LOW);
/*
Читаем значение (int - (2-byte) из EEPROM (ячейки - №0 и №1).
И записываем в RecordNumber.
*/
EEPROM.get(0, RecordNumber);
// delay(50);
OnOffRecord = EEPROM.read(5); /* Подготовка - к старту записи */
// delay(50);
}
void loop() {
if (recPressed == 0 && OnOffRecord == 1) {
StartRec(); /* launch StartRec method - Включаем запись */
}
/*_____________*/
/* Останавливаем запись - по таймеру */
/* Продолжительность записи 10 секунд - можно изменять */
if (OnOffRecord == 1 && millis() - TimeIntervalStopRecording >= 10000) {
StopRec(); /* launch StopRec method - Останавливаем запись. */
/* Блокируем повторный старт записи. */
EEPROM.write(5, 0);
OnOffRecord = 0;
}
/*_____________*/
if (recByteCount % 1024 == 512 && recPressed == 1) {
rec.write(buf00, 512); // save buf01 to card
recByteSaved += 512;
}
if (recByteCount % 1024 == 0 && recPressed == 1) {
rec.write(buf01, 512); // save buf02 to card
recByteSaved += 512;
}
/*_____________*/
/* Подготовка к старту записи "Активация по голосу (VAS)."
Запись начнётся, как только сигнал, поступающий с микрофона,
превышает определенный уровень.
*/
/* Если уровень микрофона превысит порог 1023.
порог - можно изменять! программно,
И аппаратно -
с помощью переменного резистора - "делитель напряжения"
подключённого к выводу AREF, изменяем опорное напряжение "analogRead"
*/
if (recPressed == 0 && analogRead(A5) == 1023) {
EEPROM.write(5, 1); /* подготовка - к старту записи */
if (RecordNumber == 32767)RecordNumber = 0;
/*
Записываем значение (int - (2-byte) в EEPROM (ячейки - №0 и №1).
Переменная RecordNumber - увеличенная на 1.
*/
EEPROM.put(0, RecordNumber + 1);
// delay(100);
/* После окончания записи, в памяти контроллера остаются данные.
И за этого следующая запись бывает качеством хуже.
Поэтому (Делаем программную перезагрузку) перед стартом новой записи. */
((void (*)())0x0000)(); /* Делаем программную перезагрузку - Arduino */
}
}
/*_____________*/
void StartRec() { // begin recording process
/* Для конвертации из int в char / из RecordNumber в NameRecord */
//String str; //declaring string.
char str[] = "01.wav";
//str = String(RecordNumber); //converting integer into a string.
//str = str & ".wav" ;
sprintf(NameRecord,"%d.wav", RecordNumber);
//str.toCharArray(NameRecord, 6); //passing the value of the string to the character array.
TimeIntervalStopRecording = millis(); /* Запоминаем millis */
digitalWrite(ledStart, LOW);
digitalWrite(ledStop, HIGH);
recByteCount = 0;
recByteSaved = 0;
recPressed = 1; // recording button has been pressed
stopPressed = 0;
writeWavHeader();
sbi (TIMSK2, OCIE2A); // enable timer interrupt, start grabbing audio
}
void StopRec() { // stop recording process, update WAV header, close file
cbi (TIMSK2, OCIE2A); // disable timer interrupt
writeOutHeader();
digitalWrite(ledStart, HIGH); // turn off recording LED
digitalWrite(ledStop, LOW); // light stop LED
recPressed = 0;
}
void writeOutHeader() { // update WAV header with final filesize/datasize
rec.seekSet(4);
byte1 = recByteSaved & 0xff;
byte2 = (recByteSaved >> 8) & 0xff;
byte3 = (recByteSaved >> 16) & 0xff;
byte4 = (recByteSaved >> 24) & 0xff;
rec.write(byte1); rec.write(byte2); rec.write(byte3); rec.write(byte4);
rec.seekSet(40);
rec.write(byte1); rec.write(byte2); rec.write(byte3); rec.write(byte4);
rec.close();
}
void writeWavHeader() { // write out original WAV header to file
recByteSaved = 0;
// rec.open("rec00000.wav", O_CREAT | O_TRUNC | O_RDWR);
/* Имя нового - записываемого файла на SD-карту. */
rec.open(NameRecord, O_CREAT | O_TRUNC | O_RDWR);
rec.write("RIFF");
byte1 = fileSize & 0xff;
byte2 = (fileSize >> 8) & 0xff;
byte3 = (fileSize >> 16) & 0xff;
byte4 = (fileSize >> 24) & 0xff;
rec.write(byte1); rec.write(byte2); rec.write(byte3); rec.write(byte4);
rec.write("WAVE");
rec.write("fmt ");
byte1 = waveChunk & 0xff;
byte2 = (waveChunk >> 8) & 0xff;
byte3 = (waveChunk >> 16) & 0xff;
byte4 = (waveChunk >> 24) & 0xff;
rec.write(byte1); rec.write(byte2); rec.write(byte3); rec.write(byte4);
byte1 = waveType & 0xff;
byte2 = (waveType >> 8) & 0xff;
rec.write(byte1); rec.write(byte2);
byte1 = numChannels & 0xff;
byte2 = (numChannels >> 8) & 0xff;
rec.write(byte1); rec.write(byte2);
byte1 = sampleRate & 0xff;
byte2 = (sampleRate >> 8) & 0xff;
byte3 = (sampleRate >> 16) & 0xff;
byte4 = (sampleRate >> 24) & 0xff;
rec.write(byte1); rec.write(byte2); rec.write(byte3); rec.write(byte4);
byte1 = bytesPerSec & 0xff;
byte2 = (bytesPerSec >> 8) & 0xff;
byte3 = (bytesPerSec >> 16) & 0xff;
byte4 = (bytesPerSec >> 24) & 0xff;
rec.write(byte1); rec.write(byte2); rec.write(byte3); rec.write(byte4);
byte1 = blockAlign & 0xff;
byte2 = (blockAlign >> 8) & 0xff;
rec.write(byte1); rec.write(byte2);
byte1 = bitsPerSample & 0xff;
byte2 = (bitsPerSample >> 8) & 0xff;
rec.write(byte1); rec.write(byte2);
rec.write("data");
byte1 = dataSize & 0xff;
byte2 = (dataSize >> 8) & 0xff;
byte3 = (dataSize >> 16) & 0xff;
byte4 = (dataSize >> 24) & 0xff;
rec.write(byte1); rec.write(byte2); rec.write(byte3); rec.write(byte4);
}
void Setup_timer2() {
TCCR2B = _BV(CS21); // Timer2 Clock Prescaler to : 8
TCCR2A = _BV(WGM21); // Interupt frequency = 16MHz / (8 x 90 + 1) = 22191Hz
OCR2A = 90; // Compare Match register set to 90
}
void Setup_ADC() {
ADMUX = 0x65; // set ADC to read pin A5, ADLAR to 1 (left adjust)
cbi(ADCSRA, ADPS2); // set prescaler to 8 / ADC clock = 2MHz
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
}
ISR(TIMER2_COMPA_vect) {
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
recByteCount++; // increment sample counter
bufByteCount++;
if (bufByteCount == 512 && bufWrite == 0) {
bufByteCount = 0;
bufWrite = 1;
} else if (bufByteCount == 512 & bufWrite == 1) {
bufByteCount = 0;
bufWrite = 0;
}
if (bufWrite == 0) {
buf00[bufByteCount] = ADCH;
}
if (bufWrite == 1) {
buf01[bufByteCount] = ADCH;
}
}
Чт дек 12, 2019 16:03:23
Чт дек 12, 2019 16:17:48
Чт дек 12, 2019 16:57:42
Чт дек 12, 2019 17:07:49
Чт дек 12, 2019 19:14:11
Чт дек 12, 2019 22:27:24
Пт дек 13, 2019 00:29:15
Пт дек 13, 2019 04:00:38
1) От дросселя в земле в таких случаях больше вреда чем пользы.forfrends писал(а):На всякий случай, вот срисовал схему модуля
Пт дек 13, 2019 09:35:46
Пт дек 13, 2019 10:15:54
Пт дек 13, 2019 11:07:31
Пт дек 13, 2019 13:46:51
Пт дек 13, 2019 17:14:43
Пт дек 13, 2019 18:16:04
Помехи идут по питанию, очевидно же.alexradio1103 писал(а):Помехи идут по аналогу
Выше написал наиболее возможные причины.forfrends писал(а):Может можно как-то сгладить помехи?
Пт дек 13, 2019 18:24:26
Пт дек 13, 2019 18:36:21
Пт дек 13, 2019 18:45:28
Вт дек 17, 2019 23:12:11
Вт дек 17, 2019 23:16:20
MAX4466 уже того...forfrends писал(а):но вставит неправильно. На выход пошло GND, +3.8 (от аккумулятора) попало на GND, а пин VCC к ардуино.