Hi,
I'm working on some code that is serving as a template for a robotics project. Basically, I'd like to be able to control the on times of various motors. I'm simulating this with LEDs for the time being, and I was hoping to use the TimerOne library for this project. Basically, when I get the MIDI note number, I'd like the light to stay on for an amount of time that changes based on the velocity value received. The MIDI part of this code works fine. I am wondering if this is a feasible way to use the timer 1 software interrupt (see code below).
#include "TimerOne.h"
#include <MIDI.h>
int modVal1 = 0;
int modVal2 = 0;
void setup()
{
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
Timer1.initialize(100000); // initialize timer1, and set a 1/2 second period
Timer1.attachInterrupt(myInterrupt); // attaches callback() as a timer overflow interrupt
Timer1.setPeriod(10000); //Timer ticks set to 10ms
MIDI.begin();
}
void myInterrupt()
{
static int x = 0;
static int y = 0;
x++;
y++;
if (x>= modVal1 ){
digitalWrite(7, LOW);
x=0;
}
if (y>= modVal2 ){
digitalWrite(8, LOW);
y=0;
}
}
void loop()
{
if (MIDI.read()) { // Is there a MIDI message incoming ?
if (MIDI.getChannel() == 1) { //filter so we only get messages coming on MIDI channel 1
switch(MIDI.getType()) { // Get the type of the message we caught
//NoteOn messages
case NoteOn:
{
int tNoteNum = MIDI.getData1(); //Get Note Number
int tNoteVel = MIDI.getData2(); //Get Velocity
if( tNoteNum == 60 ) {
if( tNoteVel > 0) {
digitalWrite(7, HIGH); //turn it on
modVal1 = (tNoteVel);
}
else {
digitalWrite(7, LOW);
}
}
if( tNoteNum == 61 ) {
if( tNoteVel > 0) {
digitalWrite(8, HIGH); //turn it on
modVal2 = (tNoteVel);
}
else {
digitalWrite(8, LOW);
}
}
}
break;
default:
break;
}
}
}
}
This code seems like it might work to accomplish my goal, but the default setting for the timerOne library is Waveform Generation mode 8, which produces counter values from 0-32768 then -32768-0. Things in my code seem to work fine for the 0-32768 values, and (predictably) not so well for the -32768-0 values. (I should mention that this is my first experience using interrupts, so if this programming strategy seems misguided, please let me know.)
I was thinking that if I could change to a mode that counts up from 0-65536, such as Mode 14, it might solve my problems.
I was wondering if there is an easy way to change either the library or my code to choose a mode that counts from 0-65536, such as mode 14? I tried setting control registers A and B appropriately in the initialize function for mode 14 (WGM13, WGM12, WGM11 = 1, WGM10 = 0), but I just couldn't get it to work. I realize these bits are spread across TCCR1A and TCCR1B.
I added the following code to TimerOne.initialize():
TCCR1A |= (1<<WGM11);
TCCR1B = (1<<WGM12)|(1<<WGM13);
I am pretty new to AVR programming, so I fear I may understand this conceptually but have failed in my implementation. It would be great to get feedback on my "strategy" of using the counters this way, as well as ways to properly set the WGM in AVR.
Thanks for your help!
Steve