Hi, my name is Lucas, from Argentina.
I read yesterday this instructable about auido + arduino (http://www.instructables.com/id/Arduino-Timer-Interrupts/step2/Structuring-Timer-Interrupts/)
And I have a few questions that may be you can explain to me.
I have a little project where I have to record a sample of audio in a SD card, I have the Arduino UNO and ethernet SHIELD.
I've made this input audio http://www.atmel.com/Images/doc1456.pdf (page 7) that I put in my A0 analog input.
I've made a audio format research and I've decide to write the bytes in a WAVE format, that is the simpler audio format that I've found.
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
Following those instructions and yours I could make a sample of audio but it's seems to be issue with the interrupt, like if the interrupt is not working at 38,5khz.
I also saw the interrupt guide that is in linked in your instructable, but I thing that is not clear at all what you are doing there, i can't understand that " ADCSRA " means and why he puts the prescaler to 500khz.
If I make a counting of samples into the main, it takes 27 second to record 380000 samples rate when it should take less than 10 seconds.
I'll send you my pice of code where you can find what I'm doing. (I know that the frecuency I putted in the WAVE header is not 38.5khz but putting 16khz its sounds better).
I hope you can understand what I said, sorry about my english it's pritty bad
This is my code:
//Audio out with 38.5kHz sampling rate and interrupts
#include
struct HEADER
{
byte chunkid[4];
byte chunksize[4];
byte format[4];
byte subchunk1id[4];
byte subchunk1size[4];
byte audioformat[2];
byte numchannels[2];
byte samplerate[4];
byte byterate[4];
byte blockalign[2];
byte bytepersample[2];
byte subchunk2id[4];
byte subchunk2size[4];
};
HEADER headerwave = {0x52, 0x49, 0x46, 0x46, // RIFF
0x00, 0x00, 0x00, 0x00, // 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size) o bien 36 + subchunk2size
0x57, 0x41, 0x56, 0x45, // WAVE
0x66, 0x6d, 0x74, 0x20, // FMT_
0x10, 0x00, 0x00, 0x00, // Chunk size 16 para pcm
0x01, 0x00, // Audio Format PCM
0x01, 0x00, // Cantidad de canales
0x80, 0x3E, 0x00, 0x00, // Frecuencia
0x80, 0x3E, 0x00, 0x00, // SampleRate * NumChannels * BitsPerSample/8
0x01, 0x00, //NumChannels * BitsPerSample/8
0x08, 0x00, // bits por muestra
0x64, 0x61, 0x74, 0x61, // DATA
0x00, 0x00, 0x00, 0x00, // NumSamples * NumChannels * BitsPerSample/8
};
unsigned long int samples = 0;
byte* headerbegin = &headerwave.chunkid[0];
const int chipSelect = 4;
int incomingAudio;
byte flag = 0;
byte iled = 0;
boolean eled = true;
void setup()
{
pinMode(10, OUTPUT);
if (!SD.begin(chipSelect)) {
return;
}
pinMode(7, OUTPUT);
cli();
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS0); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements
sei();//enable interrupts
}
ISR(ADC_vect)
{//when new ADC value ready
incomingAudio = ADCH;//update the variable incomingAudio with new value from A0 (between 0 and 255)
flag = 0;
/* iled++;
if (iled == 1000)
{
iled = 0;
if (eled)
{
digitalWrite(7, LOW);
eled = false;
}
else
{
digitalWrite(7, HIGH);
eled = true;
}
} */
}
void loop()
{
digitalWrite(7, HIGH);
File dataFile = SD.open("test.wav", FILE_WRITE);
if(dataFile)
{
headerwave.subchunk2size[0] = 0x00;
headerwave.subchunk2size[1] = 0x71;
headerwave.subchunk2size[2] = 0x02;
headerwave.chunksize[0] = 0x24;
headerwave.chunksize[1] = 0x71;
headerwave.chunksize[2] = 0x02;
dataFile.write(headerbegin, 44);
while(true)
{
if(flag == 0)
{
flag = 1;
if (samples < 160000)
{
dataFile.write(incomingAudio);
samples ++;
}
else
{
dataFile.close();
digitalWrite(7, LOW);
}
}
}
}
}