do i need an interupt and/or timer?

Hi,

I've been writing various midi sequencers on the arduino. To those unfamiliar with a midi sequencer, it
sends a value to the serial tx after every set period of time. For instance 120 times per minute (120 bpm).

Currently I do something like:

loop()
{

// check if needed time has passed, if so send the next step of the sequence

// check for button presses etc.
}

the main problem i see is that the checking of passed time is all done inside the main loop. as i add code to check various buttons, pots, etc. i am afraid it could affect the accuracy of the timing.

i have enough familiarity with the concept of interrupts that i'm wondering if i'd be better off to install an interrupt that goes off every x milliseconds and runs the code that sends the next value in the sequence.

Is this the best way to do this? Is it possible with the arduino?

my current code is :

extern volatile unsigned long timer0_overflow_count;

unsigned long hpticks (void)
{
    return (timer0_overflow_count << 8) + TCNT0;
}


void loop() {
  
  int t1, t2;
  
  
  t1 = hpticks() * 4;
  t2 = hpticks() * 4;
  
  
  while (1) {
    if ((t2 - t1) >= pulse_interval) {
        process_pulse();
        t1 = hpticks() * 4;
    }
    t2 = hpticks() * 4;
  }

}

The code is stuff I found in other peoples examples of how to get more accrute time than milis(). I think I'm most of the way there.

All advice appreciated.

Hey tr909,

I don't think your algorithm needs adjusting. Adding more checks for buttons, pots, etc. won't change the accuracy of your timing. The only danger is if the amount of time need to perform all those checks starts exceeding the length of the midi timeslice in which case you might send your midi packet late. However, you could deal with this by reorganizing your code a bit:

void loop()
{
// check if time has passed and if so send the next step
// check a button
// check time again
// check a pot
// check time again... etc.
}

Another argument against the interrupt strategy is that I'm guessing -- correct me if I'm wrong, somebody -- that serial transmissions won't work inside interrupt handler, because they themselves rely on interrupts.

My 2c!

Mikal

I'm pretty sure the hardware UART does not rely on interrupts and it would be fine to use it in an interrupt handler.

Even if you were using software serial, you could simply set a flag in your interrupt handler and then from your main code, frequently check if the flag is set and if so, send the packet and clear the flag. Thought that would basically be what it's already done (mills is pretty much a flag being set by an interrupt handler).

I'm pretty sure the hardware UART does not rely on interrupts and it would be fine to use it in an interrupt handler.

Even if you were using software serial, you could simply set a flag in your interrupt handler and then from your main code, frequently check if the flag is set and if so, send the packet and clear the flag. Thought that would basically be what it's already done (mills is pretty much a flag being set by an interrupt handler).

I think Oracle missed out on his morning coffee before posting the above :wink:
Mikal is correct, the Arduino hardware serial UART does use interrupts, so one should avoid calling hardware serial functions inside an interrupt handler if you don't want to risk dropping characters. (the handler is in wiring_serial.c)

Millis() returns a calculation based on a counter incremented in the timer interrupt, so unlike with a flag, you actually need to compare the value returned from millis() with a previous value to determine how much time has passed.

It's not clear how accurate the timing needs to be between messages but my suggestion is to poll the standard millis function to see if the correct amount of time has passed for sending the next message.

I think Oracle missed out on his morning coffee before posting the above :wink:

Thanks for putting it so politely. Sorry about that.