(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.

Atmega168 Timer interrupts

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.

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 )

Google+ photo

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

Connecting to %s