-
Notifications
You must be signed in to change notification settings - Fork 1
Stepper Motors
Stepper motors are special, brushless DC motors. Inside they have coils which pull the rotor along. They are called stepper motors because every time the next coil turns on, one step is performed which turns the rotor a consistent distance. To control these directly would be quite challenging, so instead we use stepper motor controllers which are like the Sabertooth, but for stepper motors. It is worth noting that we have a few different motor controllers for our stepper motors, but they still all work the same.
So how do we control the stepper motor controllers? The main part is Pulse Frequency Modulation. Big words aside, we need to tell the motor controller when to turn the motor, so we do that by sending it a pulse (just setting the "PUL" pin to HIGH). But now what? It turned one step which we couldn't even see because it's so tiny and then it stopped! So we have to set it back to LOW and then we can set it to HIGH again to get another step. Just keep doing that HIGH LOW HIGH LOW and you've got it turning! Except we can't send those pulses too fast or else the motor controller won't even know what to do, so we need to add some delay. It depends on the way the motor controller is setup, but I tend to have good luck with a 500 μs delay. If you want to go slower, make the delay longer. If you want to go faster, make the delay shorter, but do note that if you start with to high of a frequency, the motor can sleep and make the worst sound you've ever heard. Trust me, I've only heard it about a hundred times
Basically it looks like this:
pulse = DigitalOutputDevice(PUL_PIN)#This assumes you have constants named PUL_PIN, ENA_PIN, and DIR_PIN going to the correct pins on a stepper motor controller
enable = DigitalOutputDevice(ENA_PIN, active_high=False)#active_high=False means that enable is set to run as active-low, so we don't have to worry about inverting the enable every time
direction = DigitalOutputDevice(DIR_PIN)
enable.on()
direction.on()#we don't really know which way it'll turn now... Fun surprises! (It depends on how you wired up the motor windings)
for i in range(3000):#run for 3000 steps
pulse.on()
sleep(500 / 1000000)#divide by 1000000 to convert to μs
pulse.off()
sleep(500 / 1000000)
It is also worth noting: since steppers step very precisely with each pulse, we can also accurately track the position of the rotor of the stepper motor. For instance, we are using steppers to rotate our wheels. These wheels need to go to very specific angles to drive effectively. As such, the robot must always know where the wheels are. This is possible because we know how many steps it takes to rotate the rotor 360 degrees. (In our case, 200 steps per revolution). There is also a gearbox that is 60:1, so it takes 60 rotor revolutions to turn the wheels 360 degrees. As such, it takes 200*60 = 12000 steps per wheel revolution. With this knowledge, we can determine the precise angle that the wheel is away from its starting angle (down to 0.03 degrees!) The only problem then is determining the starting angle. There are many solutions to this. In our case, we use limit switches or hall-effect sensors which basically tell the robot when the robot has reached a particular angle.