A Class for Unipolar Motor Stepper - Part I
bentejuy Fri Jul 17, 2015 Tags InterfaceGPIO MotorStepper Unipolar

One of the first classes built in Raspybot was the MotorStepper, which allows me to control stepper motors. I thought it was fascinating to be able to control motors step by step because those are the ones that allow us to interact actively with the Raspberry PI. Here, I detail how to control a motor with MotorStepperUnipolar class.

There is abundant documentation on the web about what the Unipolar Motors Stepper is, and how it works, and how it is different compared to Bipolar Motor Stepper, but I will not delve into that subject here. For your information, basically they can have a number of wires that varies between 5 and 8, depending on the internal connection of its windings. Normally the motor with 5 wires is similar to the motor with 6 wires, the only difference being that the common wires are attached and you get a wire that is common to all. With excitation of one or more windings, the motor will advance a certain number of degrees; the number of degrees in each step that the motor will move is one of the most important parameters of this type of motor and is a factor that depends on the internal design of the manufacturer. This relationship is called degrees per step.

The MotorStepperUnipolar object was created to control stepper motors of 4 wires plus a common wire, like the 28BY-J-48 engine that will be used in our tests. This motor has a gearbox with a gear reduction ratio of 64/1, so 64 laps of the engine are necessary to get a full turn. With the gearbox we get two things: higher precision per step and greater strength, but in return the engine loses speed.

The most important features of 28BY-J-48 are:

Rated Voltage 5Vc - 12Vc
Windings 4
Resistance per phase 300Ω
Step Angle 5.625º / 64 = 0.8789º
Gear Reduction Rate 1 : 64

In the example code I will use two 28BY-J-48 stepper motors configured in two different work modes. Motor1 will be configured in dual mode (MODE_DUAL) and motor2 in half step mode (MODE_HALF). In dual mode, the engine needs 2048 steps to complete a turn, while in half step, we will need 4096 steps to make a full turn.

Relationship between steps and winding excited:

Logic Steps Mode
Step Simple Dual Half
0 0 0 1 X   X
0 0 1 1   X X
0 0 1 0 X   X
0 1 1 0   X X
0 1 0 0 X   X
1 1 0 0   X X
1 0 0 0 X   X
1 0 0 1   X X

To be honest, not everything worked as I would have liked, although I suspected it would happen this way because I know the limitations of Python with the timing and it is precisely there where it has failed. As you can see in the video, although both engines are set at the same speed and both should take the same time in testing, this is not the case because Python's latencies make the time control quite difficult to control.

Download Code
										
#!/usr/bin/env python
# -+- coding: utf-8 -+-
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#
# Name:         tests/motorstepper1
# Purpose:      Testing MotorStepperUnipolar object with blocking mode
#
# Created:      03/20/2015
# Modified:     12/05/2015
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

import sys
import time

from raspybot.devices.motor import MotorStepperUnipolar
from raspybot.io.interface import InterfaceManager, InterfaceGPIO

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

def startinfo(motor):
    print 'Starting Motor => %s' % motor.get_name())


def stopinfo(motor):
    print 'Stopping Motor => %s' % motor.get_name())

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

manager = InterfaceManager()

iface1 = InterfaceGPIO(manager, pinout=(17, 18, 22, 23))
iface2 = InterfaceGPIO(manager, pinout=(9, 25, 11, 8))

motor1 = MotorStepperUnipolar(iface1, 'Motor stepper 1', start=startinfo, stop=stopinfo)
motor2 = MotorStepperUnipolar(iface2, 'Motor stepper 2', start=startinfo, stop=stopinfo)

try:
    motor1.set_mode(motor1.MODE_HALF)
    motor1.set_degrees(5.625/64)                    #  Default steps for stepper motor 28BYJ-48
    motor1.set_speed(15)

    motor2.set_mode(motor2.MODE_DUAL)
    motor2.set_degrees(5.625/64)                    #  Default steps for stepper motor 28BYJ-48
    motor2.set_speed(15)

    motor1.forward(degrees=360)
    motor2.forward(degrees=360)

    motor1.join()
    motor2.join()

    time.sleep(0.5)

    motor1.backward(2048)                           # Move 2048 steps
    motor2.backward(2048)

    motor1.join()
    motor2.join()

    time.sleep(0.5)

    motor1.angle_to(180)                             # Turn clockwise 180 degrees
    motor2.angle_to(180)

    motor1.join()
    motor2.join()

    time.sleep(0.5)

    motor1.angle_to(-180)                            # Turn counteclockwise 180 degrees
    motor2.angle_to(-180)

    motor1.join()
    motor2.join()

except KeyboardInterrupt:
	print '\nScript stopped...'

except Exception, error:
    print 'Error :', error

finally:
    motor1.stop()
    motor2.stop()

    manager.delete(iface1)
    manager.delete(iface2)
    manager.cleanup()