Close

The Interrupt Service Routine

A project log for Motion Controller

An update to "not GRBL" but using an ISR.

agpcooperagp.cooper 01/14/2018 at 02:490 Comments

The Interrupt Service Routine (ISR)

The core of motion control is the frequency generator ISR. Here is an ISR "Blink" sketch:

/*
  Simple 3 Axis ISR Motion Controller - Part 1: The ISR Frequency Generator 
  =========================================================================
  Written by Alan Cooper (agp.cooper@gmail.com)
  This work is licensed under the 
  Creative Commons Attribution - NonCommercial 2.4 License.
  This means you are free to copy and share the code (but not to sell it).
*/

volatile unsigned int magic=0;
ISR(TIMER2_OVF_vect)
{
  static unsigned int phase=0;
  if (phase<0x8000) {
    phase+=magic;
    if (phase>=0x8000) {
      digitalWrite(LED_BUILTIN,LOW);  // LED on
    }
  } else {
    phase+=magic;
    if (phase<0x8000) {
      digitalWrite(LED_BUILTIN,HIGH); // LED off
    }
  }
}

void setup()
{
  // LED
  pinMode(LED_BUILTIN,OUTPUT);
  
  // Use Timer 2 for ISR
  // Good for ATmega48A/PA/88A/PA/168A/PA/328/P
  cli();
  TIMSK2=0;                                     // Clear timer interrupts
  TCCR2A=(0<<COM2A0)|(0<<COM2B0)|(3<<WGM20);    // Fast PWM
  TCCR2B=(1<<WGM22)|(2<<CS20);                  // 2 MHz clock and (Mode 7)
  OCR2A=243;                                    // Set for 8197 Hz
  OCR2B=121;                                    // Not used
  TIMSK2=(1<<TOIE2)|(0<<OCIE2A)|(0<<OCIE2B);    // Set interrupts
  sei();

  // Update frequency without interrupt
  unsigned int freq=1;                          // Note freq should be between 1 and 4095
   
  cli();
  magic=(freq<<3); 
  sei();
}

void loop()
{

} 

The code is based on my Midi project (https://hackaday.io/project/27429-simple-concurrent-tones-for-the-arduino).

The heart of the frequency generator are two 16 bit unsigned integers "magic" and "phase". Now, magic is added to phase approximately 8192 times a second. If magic equal 8, then phase will overflow and reset every second (i.e. 65536=8x8192). I can not set the ISR for exactly 8192 Hz but 8197 Hz is close enough. The ISR sets the LED on as it passes 0x7FFF and reset the LED as it passes 0xFFFF. The formula for magic is "=freq*8", and the range for freq is 1 to 4095 Hz. 

If you upload the sketch to an UNO or a Nano the LED will flash at 1 Hz, assuming "freq=1".

AlanX

Discussions