Arduino Timer Interrupt

I am actually working on a small project using an Arduino micro-controller ATMEGA 328. Timing issues are very critical so I had to find a way to use timer interrupts.

I found the following code and adapted it to the ATMEGA 328.
http://gonium.net/md/2006/12/27/i-will-think-before-i-code/

Following is my implementation for the ATMEGA 328 … The code is driving a stepper motor through the Allegro 5804 stepper motor driver.

#include <avr/interrupt.h>
#include <avr/io.h>

#define INIT_TIMER_COUNT 6
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT

#define CW     HIGH
#define CCW    LOW

// One and two phases
// 60000ms / 48steps = 1250ms/step
#define TRACK  1250

// Half steps
// 60000ms / 96steps = 625
//#define TRACK 625

int led13 = HIGH;
long counter = 0;
int stepStack = 0;

// Aruino runs at 16 Mhz, so we have 1000 Overflows per second...
// 1/ ((16000000 / 64) / 256) = 1 / 1000
ISR(TIMER2_OVF_vect) {
  RESET_TIMER2;
  counter++;
  if(!(counter%TRACK))
  {
    // enqueue step message
    stepStack++;
  }
};

void setup()
{
  pinMode(2, OUTPUT);  // Step
  pinMode(3, OUTPUT);  // Direction
  pinMode(13, OUTPUT); // LED

  pinMode(4, INPUT);   // Power on/off
  pinMode(5, INPUT);   // Rewind

  //Timer2 Settings: Timer Prescaler /64,
  TCCR2A |= (1<<CS22);
  TCCR2A &= ~((1<<CS21) | (1<<CS20));
  // Use normal mode
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
  // Use internal clock - external clock not used in Arduino
  ASSR |= (0<<AS2);
  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= (1<<TOIE2) | (0<<OCIE2A);
  RESET_TIMER2;
  sei();
}

void loop()
{
  // READ INPUTS
  int fast = digitalRead(4);
  int rewind = digitalRead(5);

  if(rewind == HIGH || fast == HIGH)
  {
    // Toggle the LED
    led13 ^= 1;
    digitalWrite(13, led13);

    // Clear the step messages buffer
    stepStack = 0;

    // Set rewind direction
    if(rewind == HIGH)
      digitalWrite(3, CCW);
    else
      digitalWrite(3, CW);

    digitalWrite(2, HIGH);
    delay(10);  

    digitalWrite(2, LOW);
    delay(10);
  }
  else if(stepStack)
  {
    // Toggle the LED
    led13 ^= 1;
    digitalWrite(13, led13); 

    // Set tracking direction
    digitalWrite(3, CW);

    digitalWrite(2, HIGH);
    delay(1);  

    digitalWrite(2, LOW);
    delay(1);

    stepStack--;
  }
}

7 Comments

  1. Dan Shope
    October 21, 2009

    I’m trying to use this driver with a PF35T-48L4 (a unipolar stepper). Everything is wired up according to the research I’ve read (ignore center taps) and I’ve tried different wiring combinations, but can’t get the stepper to move. I had this stepper running on a unipolar driver before — I also tried connecting the center taps to +VDC but no luck.

    I checked all the stepper leads and the stepper driver for proper grounding, and verified that the outputs were firing.

    Reply
  2. pchretien
    October 21, 2009

    Hi Dan,

    I wired my stepper following the instructions of the datasheet at the following address http://www.allegromicro.com/en/Products/Part_Numbers/Archive/5804.pdf but I guess that’s what you did.

    I dont know your skills in electronic so I’ll assume you are as I am, a newbe. Make sure your uses zener diodes to protect the driver and that they are connected the right way. I lost a few 5804 because of that.

    You should also make sure the power comming in the driver to drive the motors on pins 2 and 7 is regulated. I also lost a few chips because of that. :)

    As you did, I had to connect the center taps to the +VDC to make it work. Do you get any rotation or feedback from the motor?

    Would be great to have a picture so I can help a bit more.

    P.

    Reply
  3. Dan Shope
    October 23, 2009

    @pchretien
    There was no rotation at all no matter in what sequence I tried wiring the four leads.

    When I was building my own unipolar circuit (four transistors) and had things wired in the wrong order, I would at least get some jitter from the stepper.

    I’ll try hooking the center taps up again. The only thing I can figure out is that I’m not providing enough power to the stepper — ~5.4VDC out. The weird thing is I’ve succesfully driven it with under 5V before… but using the unipolar driver.

    Reply
  4. chethan
    January 16, 2010

    pls send circuit of running stepper motor to chethancit@gmail.com

    Reply
    1. pchretien
      January 26, 2010

      Hi,

      You can find sample circuits in the datasheet of the Allegro 5804 at the following address.
      http://www.allegromicro.com/en/Products/Part_Numbers/Archive/5804.pdf

      Philippe Chrétien

      Reply
  5. […] Arduino Timer interrupt pour le nouveau modèle duemilanove (Atmel ATmega328) […]

    Reply
  6. […] The electronic is built using an Arduino, an Alegro 5804 driver and a cheap stepper motor. I did this some time ago and, as of today, I would use different parts such as the Adafruit motor shield and the Nema 17 motor. You’ll find more informations about this on my blog at: https://basbrun.com/2009/07/10/arduino-timer-interrupt/ […]

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top