Driving two uni-polar stepper motors

Unipolar stepper motors have four coils and turn with the signal 1-2-3-4-1-2-3-4 and so on. 4-3-2-1-4-3-2-1 will reverse the direction. The faster you send the sequence, the faster the rotor will turn.

You can also send half step signals. Energise one coil, then two adjacent coils then the next coil and so on. Like this: 1 - 1+2 - 2 - 2+3 - 3 - 3+4 - 4 - 4+1 - 1 - and so on. The motion of the motor is now much smoother, particularly at lower speeds.

I have connected the motors to the Velleman board via a small circuit, which simply makes connecting the motor easier. It also allows disconnecting the motor without getting the wires mixed up, as it can be a pain in the neck establishing the correct sequence again.


The Stepper project
Connection diagram The pcb layout

The pcb layout of the little circuit is shown on the right.

A word of warning. Velleman say that the digital outputs will sink only 100mA - and many stepper motors need more. The ULN 2803 chip they are using is rated as 500mA per channel by the manufacturer, so I drive it with more than 100mA quite often and so far there has been no damage. The chip is easily replaced should you burn it out but you have been warned.


Programming the motor

Here is the menu of the program:

  Motor 1
  Left - Stop - Right  . . . . . .  Z  X  C
 
  Motor 2
  Left - Stop - Right  . . . . . .  <  >  ?
  240 PRINT
  Fast - - - Slow      . . . . . .  1  2  3  4  5
  Quit the progran     . . . . . .  Q

Each motor's direction can be changed individually but the speed always applies to both motors

The heart of the program is PROCturn at line 590. It checks in which direction each motor is to turn and picks the relevant bit-pattern from Arrays M1Full% and M2Full%.  The sequence number is stored in the variables Coil1% and Coil2%. The two for bit patterns are then ORed and sent to the output port.

  590 DEFPROCturn
  600
  610 IF M1$="right" Coil1%+=1:IF Coil1% > 4 Coil1% = 1
  620 IF M1$="left" Coil1%-=1:IF Coil1% < 1 Coil1% = 4
  630 IF M2$="right" Coil2%+=1:IF Coil2% > 4 Coil2% = 1
  640 IF M2$="left" Coil2%-=1:IF Coil2% < 1 Coil2% = 4
  650 Pattern%=M1Full%(Coil1%) OR M2Full%(Coil2%)
  660 SYS K8055_WriteAllDigital%,Pattern%
  670
  680 ENDPROC



 The motors have a step angle of 7.5 degrees and hence it takes 48 pulses to produce one revolution. Because the Velleman board has a slow refresh time, the motor cannot turn very fast. The best I can manage is slightly more than 1 revolution per second. However, to compensate for this you can make the thing turn as slowly as you like - 1 rev per day is entirely possible!


As usual I supply an archive with the BBC BASIC for Windows program and the executable of the same file in case you don't own BB4W

K8055_twostep.zip

There is also a

YouTube video

If you prefer the K8061, the two files below may be of passing interest

K8061_twostep.zip


   10 REM StepCon
   20 REM Control two stepper motors
   30 REM Speed is the same for both motors
   40 REM Jochen Lueg
   50 REM http://roevalley.com
   60 REM Limavady, February 2012
   70 REM Version 3
   80
   90 ON ERROR PRINT REPORT$;" at line ";ERL
  100 PROCK8055_init
  110 PROCinit
  120 COLOUR 128
  130 CLS
  140 COLOUR 15
  150 SYS K8055_CloseDevice%,0
  160 SYS K8055_OpenDevice%,0
  170
  180 PRINT
  190 PRINT " Motor 1"
  200 PRINT " Left - Stop - Right  . . . . . .  Z  X  C"
  210 PRINT
  220 PRINT " Motor 2"
  230 PRINT " Left - Stop - Right  . . . . . .  <  >  ?"
  240 PRINT
  250 PRINT " Fast - - - Slow      . . . . . .  1  2  3  4  5"
  260 PRINT " Quit the progran     . . . . . .  Q"
  270 REM Main loop
  280 REPEAT
  290   Key$=INKEY$(Speed%):REPEAT UNTIL INKEY(0)=-1
  300   IF Key$ = "z" OR Key$ = "Z" M1$="left"
  310   IF Key$ = "c" OR Key$ = "C" M1$="right"
  320   IF Key$ = "x" OR Key$ = "X" THEN
  330     M1$="stop"
  340     Pattern%=Pattern% AND %11110000
  350     SYS K8055_WriteAllDigital%,Pattern%
  360   ENDIF
  370   IF Key$ = "," OR Key$ = "<" M2$="left"
  380   IF Key$ = "/" OR Key$ = "?" M2$="right"
  390   IF Key$ = "." OR Key$ = ">" THEN
  400     M2$="stop"
  410     Pattern%=Pattern% AND %00001111
  420     SYS K8055_WriteAllDigital%,Pattern%
  430   ENDIF
  440   IF Key$="1" Speed%=0
  450   IF Key$="2" Speed%=1
  460   IF Key$="3" Speed%=5
  470   IF Key$="4" Speed%=15
  480   IF Key$="5" Speed%=25
  490   IF M1$<>"stop" OR M2$<>"stop" PROCturn
  500   IF M1$="stop" AND M2$="stop" SYS K8055_ClearAllDigital%
  510 UNTIL Key$ = "q" OR Key$ = "Q"
  520
  530 SYS K8055_ClearAllDigital%
  540 SYS K8055_CloseDevice%
  550 *QUIT
  560 END
  570
  580
  590 DEFPROCturn
  600 REM M1 right
  610 IF M1$="right" Coil1%+=1:IF Coil1% > 4 Coil1% = 1
  620 IF M1$="left" Coil1%-=1:IF Coil1% < 1 Coil1% = 4
  630 IF M2$="right" Coil2%+=1:IF Coil2% > 4 Coil2% = 1
  640 IF M2$="left" Coil2%-=1:IF Coil2% < 1 Coil2% = 4
  650 Pattern%=M1Full%(Coil1%) OR M2Full%(Coil2%)
  660 SYS K8055_WriteAllDigital%,Pattern%
  670 REMTIME=0:REPEAT UNTIL TIME>Speed%
  680 ENDPROC
  690
  700
 

     
  

 710
  720 DEFPROCinit
  730 M1$="stop" :M2$="stop"
  740 Mode$="FullStep"
  750 Speed%=0
  760 Coil1%=1
  770 Coil2%=1
  780 Pattern%=0
  790 DIM M1Full%(4)
  800 M1Full%(1) = %00000001
  810 M1Full%(2) = %00000010
  820 M1Full%(3) = %00000100
  830 M1Full%(4) = %00001000
  840
  850 DIM M2Full%(4)
  860 M2Full%(1) = %00010000
  870 M2Full%(2) = %00100000
  880 M2Full%(3) = %01000000
  890 M2Full%(4) = %10000000
  900
 1100
 1110 REM Make sure the motors are in sequence
 1120 FOR J%=1 TO 4
 1130   Pattern%=(M1Full%(J%) OR M2Full%(J%))
 1140   SYS K8055_WriteAllDigital%,Pattern%
 1150 NEXT
 1160 SYS K8055_WriteAllDigital%,0
 1170 ENDPROC
 1180
 1190
 1200
 1210 DEFPROCK8055_init
 1220 REM  Typing errors in routine name do not generate an error message - they just hang up the program.
 1230 REM These are all the system calls in the order found in the manual
 1240 SYS"LoadLibrary","K8055D.dll" TO K8055_Board%
 1250 SYS"GetProcAddress",K8055_Board%,"OpenDevice" TO K8055_OpenDevice%
 1260 SYS"GetProcAddress",K8055_Board%,"CloseDevice" TO K8055_CloseDevice%
 1270 SYS"GetProcAddress",K8055_Board%,"ReadAnalogChannel" TO K8055_ReadAnalogChannel%
 1280 SYS"GetProcAddress",K8055_Board%,"ReadAllAnalog" TO K8055_ReadAllAnalog%
 1290 SYS"GetProcAddress",K8055_Board%,"OutputAnalogChannel" TO K8055_OutputAnalogChannel%
 1300 SYS"GetProcAddress",K8055_Board%,"OutputAllAnalog" TO K8055_OutputAllAnalog%
 1310 SYS"GetProcAddress",K8055_Board%,"ClearAnalogChannel" TO K8055_ClearAnalogChannel%
 1320 SYS"GetProcAddress",K8055_Board%,"ClearAllAnalog" TO K8055_ClearAllAnalog
 1330 SYS"GetProcAddress",K8055_Board%,"SetAnalogChannel" TO K8055_SetAnalogChannel%
 1340 SYS"GetProcAddress",K8055_Board%,"SetAllAnalog"  TO K8055_SetAllAnalog%
 1350 SYS"GetProcAddress",K8055_Board%,"WriteAllDigital" TO K8055_WriteAllDigital%
 1360 SYS"GetProcAddress",K8055_Board%,"ClearDigitalChannel" TO K8055_ClearDigitalChannel%
 1370 SYS"GetProcAddress",K8055_Board%,"ClearAllDigital" TO K8055_ClearAllDigital%
 1380 SYS"GetProcAddress",K8055_Board%,"SetDigitalChannel" TO K8055_SetDigitalChannel%
 1390 SYS"GetProcAddress",K8055_Board%,"SetAllDigital"  TO K8055_SetAllDigital%
 1400 SYS"GetProcAddress",K8055_Board%,"ReadDigitalChannel" TO K8055_ReadDigitalChannel%
 1410 SYS"GetProcAddress",K8055_Board%,"ReadAllDigital"  TO K8055_ReadAllDigital%
 1420 SYS"GetProcAddress",K8055_Board%,"ResetCounter"  TO K8055_ResetCounter%
 1430 SYS"GetProcAddress",K8055_Board%,"ReadCounter"  TO K8055_ReadCounter%
 1440 SYS"GetProcAddress",K8055_Board%,"SedtCounterDebouceTime"  TO K8055_SetCounterDebounceTime%
 1450 ENDPROC



Return to the interfacing index

Back to the Limavady home page

Tudor with sign