Hello all,
I'm using the default SD card library with the software spi function. I can read files from my SD card (I'm able to play a 10kHz 8but mono wav). Reading a byte and driving the speaker takes 45 us. 10 kHz sound requires a new byte fed to the speaker every 100 us, so I hooked up an interrupt to Timer 1 at this frequency. Working code:
volatile byte play_byte = 0;
volatile byte play_byte_used = 0;
void setup()
{
Serial.begin(9600);
// pins 7 (SCK), 6 (MISO), 5 (MOSI) are defined in SD card library
pinMode( 3, OUTPUT); // for PWM sound generation
pinMode( SS_CARD, OUTPUT); // SS for sd card
pinMode(MISO, OUTPUT);
digitalWrite(4,HIGH); // set SS high for software SPI
// initialize SPI
SPCR |= _BV(SPE); // start hardware SPI in Slave mode
SPI.attachInterrupt(); // attach slave mode interrupt handler for SPI
// Set pin 3 for PWM generation, fast PWM mode, toggle on overflow and passing OCRB; OCRB (0-255) determines duty cycle
TCCR2A = B00100011;
TCCR2B = B00000001;
OCR2B = 0; // duty cycle = 0 %
//try to initialize SD card on startup
initialize_SDcard();
/******** Initialize Timer and 50 us interrupt ********/
Timer1.initialize(100); // initialize timer1, and set a 100 us period
// In the PWM modes pin 1 and 9 are grouped, and pin 2 and 10
Timer1.disablePwm(9); // clear PWM on all pins
Timer1.disablePwm(10);
Timer1.attachInterrupt(callback);
// start playing a WAV
openNewWav(4);
Serial.println(millis());
player_status = STATUS_PLAYING;
}
void loop()
{
// nothing happens after setup
if(play_byte_used && player_status==STATUS_PLAYING)
{
play_byte = myFile.read();
play_byte_used = 0;
}
}
void callback()
{
if (player_status == STATUS_PLAYING)
{
OCR2B = play_byte;
play_byte_used = 1;
file_pos++;
if (file_pos==100000 /*sample_size*/) player_status = STATUS_CLOSINGWAV;
//delayMicroseconds(54);
}
}
This sounds well. However, in order to expand my project, I want to move the "reading the byte from the sd-card" part to the interrupt function.
volatile byte play_byte = 0;
volatile byte play_byte_used = 0;
void setup()
{
Serial.begin(9600);
// pins 7 (SCK), 6 (MISO), 5 (MOSI) are defined in SD card library
pinMode( 3, OUTPUT); // for PWM sound generation
pinMode( SS_CARD, OUTPUT); // SS for sd card
pinMode(MISO, OUTPUT);
digitalWrite(4,HIGH); // set SS high for software SPI
// initialize SPI
SPCR |= _BV(SPE); // start hardware SPI in Slave mode
SPI.attachInterrupt(); // attach slave mode interrupt handler for SPI
// Set pin 3 for PWM generation, fast PWM mode, toggle on overflow and passing OCRB; OCRB (0-255) determines duty cycle
TCCR2A = B00100011;
TCCR2B = B00000001;
OCR2B = 0; // duty cycle = 0 %
//try to initialize SD card on startup
initialize_SDcard();
/******** Initialize Timer and 50 us interrupt ********/
Timer1.initialize(100); // initialize timer1, and set a 100 us period
// In the PWM modes pin 1 and 9 are grouped, and pin 2 and 10
Timer1.disablePwm(9); // clear PWM on all pins
Timer1.disablePwm(10);
Timer1.attachInterrupt(callback);
// start playing a WAV
openNewWav(4);
Serial.println(millis());
player_status = STATUS_PLAYING;
}
void loop()
{
// nothing happens after setup
}
void callback()
{
if (player_status == STATUS_PLAYING)
{
play_byte = myFile.read();
OCR2B = play_byte;
play_byte_used = 1;
file_pos++;
if (file_pos==100000 /*sample_size*/) player_status = STATUS_CLOSINGWAV;
//delayMicroseconds(54);
}
}
My speaker now just garbles. Timewise this should fit.
I have no idea how to investigate further. I have been over all sd-card files, but found no apparent clue. Ideas are welcome.
Cheers, Jack