Arduino AVR L298 Motor Shield Interrupt Driven Stepper Motor

by Gilissen Erno in Circuits > Arduino

649 Views, 2 Favorites, 0 Comments

Arduino AVR L298 Motor Shield Interrupt Driven Stepper Motor

complete.png

Stepper motor drivers I found for Arduino (AVR) always seemed to be software based. Either locking the AVR core while the motor spins or requiring some service function call to perform motor stepping. The first prevents the core from doing anything else. The 2nd often results in unstable stepping, certainly at high step rates. So I decided to write a non-blocking (timer interrupt driven) stepper motor driver instead. Interrupt driven has a stepping interval stability comparable to blocking code. However it leaves the main loop available to perform other tasks. The disadvantage is that interrupt driven uses the 16bit hardware timer from the AVR core. By default, this timer is not used by Arduino, but one has to make sure other libraries / software running on it don't use that timer either.

This driver supports Arduino Motor Shield V3 (basically any L298 driver) using bipolar stepper motors or ULN280x drivers using uni-polar stepper motors. The Arduino motor shield using L298 has hard-coded pins, but one is free to modify the source code if another L298 based board is used instead. As the documentation states, one must ensure all Arduino pins driving the stepper motor coils must be on the same AVR I/O port.

The stepper function outputs a stepper motor pattern to the motor driver at a predefined step interval. The rotation speed can even be changed while the code runs in the background. That leaves the main loop free to conduct other tasks. The source code also allows to stop motor spinning after a certain amount of motor steps.

The driver uses timer1 on the Arduino Uno and may use timer 1, 3, 4 or 5 on the Mega 2560. Other Arduino variants are not tested / supported by this code. In theory, minimal modification will be required to support other AVR based Arduino boards.

Supplies

external-content.duckduckgo.com.jpg
uln2803.png

Motor drivers as shown above are supported. Other may require some code tweaks.

The Arduino Driver based on the L298 can drive bipolar (4-wire) stepper motors, the ULN2803 based driver can drive unipolar (5 or 6 wire) motors.

This is a typical stepper motor driver, other motors are not supported.

Code & Documentation

ULN2803.png

Put the files in a directory "stepMotorDriver". The ino file can then be opened using Arduino IDE, it demonstrates how the driver may be used. Don't forget to set the proper Arduino type (Uno or Mega 2560) in the Arduino IDE and select the correct VCP (COM) port.

In case of Arduino motor shield: plug it on top of the Arduino. If different outputs or an ULN280x driver are used, one has to update the header file or even change the source code accordingly. The header file provides for various defines to select the kind of driver used and what Arduino pins control the motor coils / other driver pins.

In all cases, pins driving the coils must be AVR I/O pins belonging to the same I/O port. See the documentation for details: it lists Arduino pins vs. AVR ports.

Since I already created the documentation in Excel (but it's not accepted by Instructables to upload), I converted this file to PDF. The disadvantage is one can no longer fill in cell values and observe calculations get updated on-the-fly.


P.S. I uploaded a new version of myStepperDriver. This is at present untested, but it fixes a potential issue with the timer config: in the previous timerUpdate function, the clock scaler is initialized before the division value is written to the timer. If the actual value was zero, this doesn't comply the AVR datasheet. The _upd version is untested at this time, but it has a simple modification to write the clock prescale register after the timer data registers.