Hola qué tal compañeros.
les escribo porque tengo ahorita el proyecto de generación de audio por medio del PWM que se encuentra en el Playground, sin embargo, me interesa que en lugar de leerlo directamente de la EEPROM lo reciba desde una comunicacion serial por medio del XBEE.
El problema es que cuando recibo los caracteres por medio de una comunicación serial, se descompone el audio.
Les pido si alguien de ustedes ha hecho algo me pudiera ayudar a ver qué es lo que está mal con mi código.
Saludos
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 16000
int ledPin = 13;
int speakerPin = 11;
volatile uint16_t sample;
byte incomingByte;
// This is called at 8000 Hz to load the next sample.
ISR(TIMER1_COMPA_vect) {
OCR2A = Serial.read();
}
void startPlayback()
{
pinMode(speakerPin, OUTPUT);
Serial.println("---Iniciando playback---");
// Set up Timer 2 to do pulse width modulation on the speaker
// pin.
// Use internal clock (datasheet p.160)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
// Set fast PWM mode (p.157)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);
// Do non-inverting PWM on pin OC2A (p.155)
// On the Arduino this is pin 11.
TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
// No prescaler (p.158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set initial pulse width to the first sample.
OCR2A = Serial.read();
// Set up Timer 1 to send a sample every interrupt.
cli();
// Set CTC mode (Clear Timer on Compare Match) (p.133)
// Have to set OCR1A *after*, otherwise it gets reset to 0!
TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
// No prescaler (p.134)
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set the compare register (OCR1A).
// OCR1A is a 16-bit register, so we have to do this with
// interrupts disabled to be safe.
OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
// Enable interrupt when TCNT1 == OCR1A (p.136)
TIMSK1 |= _BV(OCIE1A);
sample = 0;
sei();
}
void stopPlayback()
{
// Disable playback per-sample interrupt.
TIMSK1 &= ~_BV(OCIE1A);
// Disable the per-sample timer completely.
TCCR1B &= ~_BV(CS10);
// Disable the PWM timer.
TCCR2B &= ~_BV(CS10);
digitalWrite(speakerPin, LOW);
}
void setup()
{
pinMode(ledPin, OUTPUT);
//startPlayback();
//Iniciar el serial a 115200 bps
Serial.begin(115200);
pinMode(speakerPin, OUTPUT);
}
void loop()
{
//Checar si estan llegando datos
if(Serial.available()>0){
startPlayback();
delay(3000);
}
}