(7)Arduino IDE+Due/Uno->Audio: Porting? Or new idea?

Upon completing my ventures attempting to use Simulink and the Arduino together with the hardware support package, I am now tryign to port this to the Arduino IDE in C code in order to create something with actual application in the real world.  To begin with I aimed to create a transmitter and receiver to send audio data with LEDs.

However, this proved to be a much larger hurdle than I first expected it to.  In order to “emulate” sampling in code, one would need to use timer interrupts.  This meant physically manipulating the registers inside the MPU.  The Uno has a lot of documentation on how to do this with sites such as the following.

http://www.protostack.com/blog/2010/09/timer-interrupts-on-an-atmega168/

The Due on the other hand was not as well documented.  Thus I decided to try and implement something with the Uno as a test run before I learned to properly write AVR code.  After reading up on the Arduino forums I discovered the following scheme to properly do timer interrupts on the Uno.

//http://www.protostack.com/blog/2010/09/timer-interrupts-on-an-atmega168/
//boolean trigger
// boolean toggle0 = 0;void setup() {
// put your setup code here, to run once:
//observation pin 8
pinMode(8, OUTPUT);//stop interrupts for safety
cli();

//setup interrupt vectors for 15khz
TCCR0A=0;//set timer registers to all 0
TCCR0B=0;//
TCNT0=0;//set timer count to 0

//set the frequency for ~15khz increments
//compare match register = [ 16,000,000Hz/ (prescaler * desired interrupt frequency) ] – 1
//OCR0A=7;
OCR0A=250;//when the counter will reset

//set prescaler
//CS02 CS01 CS00
// 0 1 1 (64 prescaler)
TCCR0B|=(1<<CS02);
TCCR0B|=(1<<CS00);

//MODE2 for wgm 02, 01, 00 will enable ctc (clear timer on compare)
//WGM02 WGM 01 WGM 00
//0 1 0
TCCR0A|=(1<<WGM01);

//enable timer/counter interrupt mask register
TIMSK0|=(1<<OCIE0A);//need to understadn what this is

//reenable interrupts
sei();
}

ISR(TIMER0_COMPA_vect){//timer0 interrupt 1Hz toggles pin 13 (LED)
//generates pulse wave of frequency 2khz/2=1kHz (takes two cycles for full wave- toggle high then toggle low)
if (toggle0){
digitalWrite(8,HIGH);
toggle0 = 0;
}
else{
digitalWrite(8,LOW);
toggle0 = 1;
}
}

void loop() {
// put your main code here, to run repeatedly:
//if toggle0==1 then take a sample from A0
//serial send and recieve by yourself

}

The code has been commented for ease of understanding.  However I was not able to transmit a square wave of anything higher than around 2kHz on the Uno and thus had to keep looking for working code for the Due.  After doing so, I stumbled on the following webpage which details how timer interrupts can be done on the Due.

http://2manyprojects.net/timer-interrupts

Even after further testing using the same sort of square wave testing methodology I was only able to create a square wave/trigger that was around 5 kHz.  After that I concluded that in order to fully maximize the processing power of the Due, I would have to completely forget about timer interrupts.  This is because I need to take advantage of every single instruction that the MPU can process and even doing so I may not be able to transmit and receive data at the desired rate.

With this new scheme, it meant that I would be walking away from the idea of “sampling” data and transmitting data at a certain rate and just work with the max data transfer rate.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s