Embedded Wednesdays

 

Week 6 - Let’s take this pig for a spin.


This week we will be playing around with stepper motors.


A stepper motor is a piece of precision equipment. Unlike the motors that you have on your furnace fan or toy car, a stepper motor does not just rotate continuously when power is applied, it rotates in portions of a single rotation or “steps”. Like the second hand of your quartz analog watch, a stepper motor jumps between steps when commanded to do so (a quartz analog watch has a stepper motor built in that steps 1/60 of a rotation once per second).


The stepper motor that I have sitting in front of me (Sparkfun 09238, $23.77CDN from Digikey 1568-1105-ND) is a “NEMA-16” size motor, which simply means that it is 1.6 inches square. It is designed to have 200 steps per revolution, so for each step you get 1.8 degrees of rotation. This is a four wire motor and has two sets of coils that are energized in brilliant patterns to excite two sets of electromagnets that drag the rotor around. There are zillions of YouTube videos that show you how stepper motors work far clearer than I can write.


This motor works with 12 volts at 0.33 amps. That is a lot of voltage and current for our little processors. We need a bit of help to control that much power. Back when I was a boy the hot chip to use was the L293D, which you would see in Seagate disk drives, printers, and anything else that used stepper motors. The L293D is four “driver” sections that take a small input signal and control a large output signal. The input signal is a 5 volt logic level, and the output can be from 4.5 to 36 volts at 1.2 amps for each output.


The processor is expected to provide 4 output pins to make the funky DIO patterns needed to make the motor step properly. It takes a small amount of thinking to get the pattern correct, but it isn’t hard at all.


Our little processor works at 3.3 volts, so a bunch of “glue” chips would be needed to shift our signals up to 5 volts to drive an L293D.


For about the same amount of money* the modern replacement for the L293D is any of the stepper motor controller chips that take care of making the funky patterns of DIO on/off signals and a lot more. All you have to do is provide ground, one signal that indicates, say, high for clockwise rotation and low for counterclockwise rotation, and a step signal that goes low-high-low to indicate one step.


These controllers (such as the Allegro A4988) also handle the more detailed patterns to give you more steps per revolution. By playing with the electromagnets in even weirder patterns, you can make the motor take half steps, so your 200 step motor will now take 400 steps for one rotation, 0.9 degrees per step. Quarter stepping gives 0.45 degrees. Eighth step, 0.225 degrees. 1/16 step, 0.1125 degrees or 3200 steps per rotation.


I picked up a SchmaltzHaus Big Easy Driver board (Sparkfun 12859 Digikey 1568-1066-ND $29.79CDN - The Canadian dollar sucks right now), along with a 12V 1/2A wall wart and a matching jack. I hooked up the power jack to the M+ and GND pads with red and black hookup wires. I soldered the red, green, yellow, and blue wires to the A, A, B, and B pads respectively (and in that order). I then soldered in a strip of 10 - 0.1 inch header pins which helped me put jumper wires between GND, Step, and Direction on the driver board to GND, PE11, and PE9 on the processor board. Smoke testing the board indicated that I didn’t screw up. YAYYYYY.


Then I started a new AC6 project in Eclipse with this:


#include "stm32f4xx.h"

#include "stm32f401_discovery.h"





int main(void) {

GPIO_InitTypeDef GPIO_InitStruct;


HAL_Init();


__GPIOE_CLK_ENABLE();

GPIO_InitStruct.Pin = GPIO_PIN_9;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FAST;


HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);


GPIO_InitStruct.Pin = GPIO_PIN_11;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);


HAL_GPIO_WritePin( GPIOE, GPIO_PIN_9, GPIO_PIN_RESET);

HAL_GPIO_WritePin( GPIOE, GPIO_PIN_11, GPIO_PIN_RESET);


for (;;) {

HAL_Delay(1);

HAL_GPIO_TogglePin( GPIOE, GPIO_PIN_11);

}

}


Standard stuff, initialize the HAL. Turn on the clock for the pins that we are going to use. Set up the pins as outputs with some reasonable speeds and pullup resistors. Initialize them so that PE9 (direction) is low, and PE11 (step) is low.


Next we enter our infinite loop, delay for a millisecond then toggle the step pin. This gives us a 500Hz square wave. This will give us 500 steps per second.


The driver board comes configured for 1/16 step action, so it will take 3200 steps for one rotation or 6.4 seconds.


Why did I choose PE9 and PE11 to drive the motor? They can be driven by Timer 1, but that is next week’s project.




  1. *$5.82 for a L293D DIP, and $4.48 for a A4966 QFN, since chip prices are mostly due to their pins and plastics.



Cool stuff

What is a watchdog timer?

Assume that your program goes nuts. Actually that is a very good assumption, crap happens, as you have seen with all of the years of programs crashing on your desktop box. Embedded systems tend to be way more stable, mostly because we don’t try and create one computer that does everything, but crap still happens. There is nobody sitting in front of our systems that can hit <ctrl><alt><delete> and kill the program (or reset the computer), but we can do exactly that automatically.

The processor manufacturers have given us a tool, basically a count down timer that has to be reset periodically because if the program ever goes nuts and forgets to reset the timer and the timer counts down to zero, the processor gets reset, the program reboots and, hopefully, the cause clears itself.

They call this facility a watchdog timer. It watches over the processor, catching infinite loops, coding bugs, executing data, and all of that stuff. When you reset the timer, that is called strobing or kicking the watchdog.

When dealing with dangerous high voltages or other things that can harm people, an external chip can be added as a watchdog, with timing controlled by a resistor/capacitor pair, that shuts off the power when the processor dies and no longer strobes the watchdog chip.

Beware, never put the watchdog strobe code in a periodic timer interrupt handler. These interrupts will continue to fire, on schedule, even though your program is completely wedged, defeating the purpose of the watchdog. A good place for the strobe code would be in your lowest priority loop after everything else has been handled.