TimerOne Library counter question

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

  Timer1.initialize(100000);         // initialize timer1, and set a 1/2 second period

Time for a refresher visit to the TimerOne documentation.

  Timer1.attachInterrupt(myInterrupt);  // attaches callback() as a timer overflow interrupt

A very descriptive name. It's obvious what that function does. Not.

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;
  }
}

Pssst. All variables referenced in an ISR should be declared volatile.

              modVal1 = (tNoteVel);

What are the parentheses for?

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.

So, add 32768 to the values that are currently generated. That will shift them to the 0 to 65535 range. (You will never see 32768 now, or 65536 in Mode 14).

Why are you concerned about the values that TimerOne uses internally, anyway? The ISR fires at the appropriate time. You should only be concerned about stuff in your sketch. Set your own counters.

Thanks for the response--I'm not sure why I was worrying about using timer 1's internal timer values, but your comments below make sense, I'll try it with my own counters.

Steve