Per Stenebo
2019-11-07 21:33:02
2020-06-25 22:15:37
Bipolar stepper motor with driver board
SM15DD Bipolar stepper motor, ripped from a PC DVD-ROM laser spindle. Link to full image (1.7 MB).
Adafruit TB6612 1.2A DC/Stepper Motor Driver Breakout Board.
Raspberry Pi, version 3 B+ in this case but any version should do.
Link to full image (4.4 MB).
External resources
A russian (?) site where I found valuable info about the motor: avr-cpp.blogspot.com | translated | According to this site, we have a 5 volt motor with 10 ohm per winding and 18 degrees per step. The datasheet above is also from that site.
Adafruit product page: TB6612
Step sequence
Controlling stepper motors is all about energizing the windings in timed order. I found a map, possibly orginating from stepperworld.com, of the possible sequences, wich I have implemented in the python code below.
Breadboard circuit
The circuit as Fritzing file.
The fritzing circuit features a similar driver from Sparkfun: Dual TB6612FNG , the connection seems almost identical, only VM and VCC are moved to the other side.
It seems possible to control the speed with the PWM inputs (other than the time between the steps), but I have not tested PWM yet, just pulled them to logical high (= max speed?).
Python 3 code
#!/usr/bin/python3 # coding: utf-8 ''' Hardware: Adafruit TB6612 1.2A DC/Stepper Motor Driver Breakout Board SM15DD CD-ROM laser spindle motor Bipolar stepper motor 5 V 10 ohm per winding 18 degrees per step sudo apt install python3-dev python3-rpi.gpio Run with: python3 stepper.py python3 /opt/diverse/stepper.py ''' import sys, signal, time import RPi.GPIO as GPIO #----------------------------------------------------------------------- # GPIO setup #----------------------------------------------------------------------- GPIO.setmode(GPIO.BCM) GPIO.setwarnings(True) # Signals from GPIO # Adjust if different coil_A_1_pin = 4 # yellow A+ coil_A_2_pin = 17 # green A- coil_B_1_pin = 23 # blue B+ coil_B_2_pin = 24 # white B- # Step sequence map # Wave drive, one-phase SeqA = [0,1,2,3] SeqA[0] = [0,1,0,0] # 1 +- -- SeqA[1] = [0,0,0,1] # 2 -- +- SeqA[2] = [1,0,0,0] # 3 -+ -- SeqA[3] = [0,0,1,0] # 4 -- -+ # High torque, two-phase SeqB = [0,1,2,3] SeqB[0] = [0,1,0,1] # 1.5 SeqB[1] = [1,0,0,1] # 2.5 SeqB[2] = [1,0,1,0] # 3.5 SeqB[3] = [0,1,1,0] # 4.5 # Half step SeqC = [0,1,2,3,4,5,6,7] SeqC[0] = [0,1,0,0] # 1 SeqC[1] = [0,1,0,1] # 1.5 SeqC[2] = [0,0,0,1] # 2 SeqC[3] = [1,0,0,1] # 2.5 SeqC[4] = [1,0,0,0] # 3 SeqC[5] = [1,0,1,0] # 3.5 SeqC[6] = [0,0,1,0] # 4 SeqC[7] = [0,1,1,0] # 4.5 mode_default = 'A' delay_default = 10 steps_fwd_default = 10 steps_rev_default = 10 GPIO.setup(coil_A_1_pin, GPIO.OUT) GPIO.setup(coil_A_2_pin, GPIO.OUT) GPIO.setup(coil_B_1_pin, GPIO.OUT) GPIO.setup(coil_B_2_pin, GPIO.OUT) #----------------------------------------------------------------------- # Functions (inline) #----------------------------------------------------------------------- # Manage ctrl+c def signal_handler(signal, frame): GPIO.cleanup() print ('Script terminated by Ctrl+C') # Terminate script sys.exit(0) signal.signal(signal.SIGINT, signal_handler) def setStep(w1, w2, w3, w4): GPIO.output(coil_A_1_pin, w1) GPIO.output(coil_A_2_pin, w2) GPIO.output(coil_B_1_pin, w3) GPIO.output(coil_B_2_pin, w4) def forward(delay, steps): for i in range(steps): for j in range(StepCount): setStep(Seq[j][0], Seq[j][1], Seq[j][2], Seq[j][3]) time.sleep(delay) #input("Fwd seq #%d : %s %s %s %s" % (j, Seq[j][0], Seq[j][1], Seq[j][2], Seq[j][3])) def backwards(delay, steps): for i in range(steps): for j in reversed(range(StepCount)): setStep(Seq[j][0], Seq[j][1], Seq[j][2], Seq[j][3]) time.sleep(delay) #input("Rev seq #%d : %s %s %s %s" % (j, Seq[j][0], Seq[j][1], Seq[j][2], Seq[j][3])) #----------------------------------------------------------------------- # Main #----------------------------------------------------------------------- if __name__ == '__main__': setStep(0, 0, 0, 0) print ('A: Wave drive, one-phase') print ('B: High torque, two-phase') print ('C: Half step') mode = input('Select squence mode [%s]? ' % mode_default) if not mode: mode = mode_default if mode.upper() == 'A': Seq = SeqA elif mode.upper() == 'B': Seq = SeqB elif mode.upper() == 'C': Seq = SeqC else: print ('Failed to parse input') GPIO.cleanup() sys.exit(0) StepCount = len(Seq) delay = input("Time Delay (ms) [%d]? " % delay_default) if not delay: delay = delay_default else: delay = int(delay) steps_fwd = input("How many steps forward? [%d] " % steps_fwd_default) if not steps_fwd: steps_fwd = steps_fwd_default else: steps_fwd = int(steps_fwd) steps_rev = input("How many steps backward? [%d] " % steps_rev_default) if not steps_rev: steps_rev = steps_rev_default else: steps_rev = int(steps_rev) while True: forward(delay / 1000.0, steps_fwd) setStep(0, 0, 0, 0) time.sleep(1.0) backwards(delay / 1000.0, steps_rev) setStep(0, 0, 0, 0) time.sleep(1.0)