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