Motor control using PWM with the K8055 and K8061 boards

This project turned out to be easier than expected. The circuit diagram is below. An IRF 630 MOS-FET is connected to the PWM1 output of the Velleman board. The waveform at this output turns the transistor on and off as it rises and falls. As the average ON and OFF time changes, so does the speed of the motor. A relay is used to control the direction of the motor. This is connected to the number 8 output of the K8055 USB board. The circuit diagram and a suggested PCB layout can be admired below.


The single stepper project
The pcb layout

The PWM projectThe circuit board and motor are shown on the right, connected to the K8055. The motor is the grey square shape. It originated from a Fischertechnik kit - as did the large red and black cog wheel on the right.

The program

K8055

To produce a pulse modulated waveform on the K8055, one simply writes to the D to A converter. This produced a voltage at the DAC output and the corresponding waveform at the PWM output. Note that writing 255 produces a minimum and 0 a maximum waveform, so don't be surprised when your motor starts turning the minute the board is connected.

SYS K8055_OutputAnalogChannel%,1,255


writes 255 to the DAC channel 1 and this will stop the motor.

SYS K8055_OutputAnalogChannel%,1,0

 will run the motor at maximum speed. Values in between these extremes will turn the motor with varying speed. Mind you, the resistance of the gears, the load and the type of motor used will also greatly affect the final speed. As starting and stopping as well as changing direction can cause a possibly harmful back emf, the program stops and starts the motor by ramping the speed up and down one step at a time. The same happens when you change direction. The current speed is always displayed at the bottom of the menu. Below is a zip archive with  the BBC BASIC for Windows program file and the executable of the same program, in case you don't have BB4W

K8055_singlePWM-2-2.zip Version 2.0 June 2012

and here is a link to a video of the project
Video link


The switch and magnetSince writing the above I have altered the program so that the current speed in rev/min is displayed. The speed is detected by counting the pulses of a reed switch every 5 seconds. The switch is mounted on the little grey column seen in the picture on the right. It is activated by a small magnet stuck to the rim of the red wheel. This is the little white rectangle. This magnet has to be fairly strong I used a small piece from an ex hard drive magnet.

The reed switch is connected to digital input I1 and every 5 seconds counter number no. 1 is read and then reset. The arrangement works quite well and involves no further electronic circuitry.
The bit of code doing all this is shown below..


  


  510  IF SpeedCount$="Start" AND TIME>=500 THEN
  520     SYS K8055_ReadCounter%,1 TO SpeedCount%
  530     PRINTTAB(6,12);SpeedCount%;" rev/5sec = ";SpeedCount%*12;" rev/min      "
  540     TIME=0 : SYS K8055_ResetCounter%,1
  550   ENDIF


K8061

Adapting the program to run on the K8061 board is fairly straight forward. The K8061 has only one PWM output which is accessed via the call:
SYS OutputPWM%,Board%,n

where Board% is the address of the board and n is a number between 0 and 1023. The K8061 has a 10 bit PWM output. Below is an archive with the BBC4W program and an executable for the K8061 board. As the K8061 does not have a counter, the above alteration does not apply.

K8061_singlePWM_1_0.zip

   10
   20 REM K8055_SinglePWM
   30 REM Control one dc motor using pulse width modulation with the Velleman K8055 USB interface
   40 REM This version uses a reed switch for speed feedback
   50 REM Version 2.0
   60 REM Jochen Lueg
   70 REM http://roevalley.com
   80 REM April 2012
   90
  100 PROCK8055_init
  110 SYS K8055_CloseDevice%,0
  120 SYS K8055_OpenDevice%, 0
  130
  140 ON ERROR PROCerror
  150 PROCinit
  160 PROCwindow(650,300,"Motor control with feedback")
  170 *FONT Lucida Console,14,2
  180 OFF
  190 SYS K8055_OutputAnalogChannel%,1,255
  200 PRINT
  210 PRINT "  Left - Stop - Right   . . . .  Z - X - C"
  220 PRINT "  Faster - slower       . . . .   <  -  >"
  230 PRINT "  Speed count On - Off  . . . . . F  -  G"
  240 PRINT
  250 PRINT
  260 PRINT "  Leave the program    . . . . . . Q"
  270 TIME=0
  280 SYS K8055_ResetCounter%,1
  290 REPEAT
  300   Key$=INKEY$(0)
  310   REPEAT UNTIL INKEY(0)=-1
  320   IF (Key$="z" OR Key$="Z") AND (Direction$="Right" OR State$="Stopped") PROCleft
  330   IF (Key$="c" OR Key$="C") AND (Direction$="Left " OR State$="Stopped") PROCright
  340   IF (Key$="x" OR Key$="X")  AND State$="Running" PROCstop
  350   IF (Key$="f" OR Key$="F") THEN  SpeedCount$="Start"
  360   IF Key$="g" OR Key$="G" THEN  SpeedCount$="Stop" : PRINTTAB(6,12)"                                                     "
  370   IF Key$="," OR Key$="<" THEN
  380     RunningSpeed%+=1
  390     IF RunningSpeed%>255 RunningSpeed%=255
  400     SYS K8055_OutputAnalogChannel%,1,RunningSpeed%
  410     StartSpeed%=RunningSpeed%
  420   ENDIF
  430   IF Key$="." OR Key$=">" THEN
  440     RunningSpeed%-=1
  450     IF RunningSpeed%<0 RunningSpeed%=0
  460     SYS K8055_OutputAnalogChannel%,1,RunningSpeed%
  470     StartSpeed%=RunningSpeed%
  480     REPEAT UNTIL INKEY(0)=-1
  490   ENDIF
  500   PROCfeedback(RunningSpeed%)
  510   IF SpeedCount$="Start" AND TIME>=500 THEN
  520     SYS K8055_ReadCounter%,1 TO SpeedCount%
  530     PRINTTAB(6,12);SpeedCount%;" rev/5sec = ";SpeedCount%*12;" rev/min      "
  540     TIME=0 : SYS K8055_ResetCounter%,1
  550   ENDIF
  560 UNTIL Key$="q" OR Key$="Q"
  570 PROCstop
  580 SYS K8055_ClearAllDigital%
  590 SYS K8055_OutputAnalogChannel%,1,255
  600 SYS K8055_CloseDevice%
  610 SYS "FreeLibrary",K8055_Board%
  620 *QUIT
  630 END
  640
  650
  660 DEFPROCfeedback(Speed%)
  670 LOCAL S%
  680 S%=(255-Speed%)/2.55
  690 PRINTTAB(6,10)State$;"   "Direction$;"   PWM:  ";S%;"%    "
  700 ENDPROC
  710
  720
  730 DEFPROCspeed_feedback
  740 REM Alternative detyection. Not used at the moment.
  750 SYS K8055_ReadDigitalChannel%,5 TO A%
  760 IF Flag%=0 AND A%=1  SpeedCount%+=1:Flag%=1
  770 IF Flag%=1 AND A%=0 Flag%=0
  780 IF TIME>=500 PRINTTAB(6,12);SpeedCount%;" rev/5sec = ";SpeedCount%*12;" rev/min      ":TIME=0:SpeedCount%=0
  790 ENDPROC
  800
  810
  820 DEFPROCright
  830 PROCstop
  840 SYS K8055_SetDigitalChannel%,8
  850 PROCstart
  860 Direction$="Right"
  870 ENDPROC
  880
  890
  900 DEFPROCleft
  910 PROCstop
  920 SYS K8055_ClearDigitalChannel%,8
  930 PROCstart
  940 Direction$="Left "
  950 ENDPROC
  960
  970
  980 DEFPROCstart
  990 FOR J%= 255 TO StartSpeed% STEP-4
 1000   SYS K8055_OutputAnalogChannel%,1,J%
 1010   PROCfeedback(J%)
 1020 NEXT
 1030 RunningSpeed%=StartSpeed%
 1040 State$="Running"
 1050 ENDPROC
 1060
 1070
 1080 DEFPROCstop
 1090 FOR J%= RunningSpeed% TO 255  STEP 4
 1100   SYS K8055_OutputAnalogChannel%,1,J%
 1110   PROCfeedback(J%)
 1120 NEXT
 1130 SYS K8055_ClearDigitalChannel%,8
 1140 State$="Stopped"
 1150 RunningSpeed%=255
 1160 ENDPROC
 1170
 1180
 1190 DEFPROCinit
 1200 RunningSpeed%=255
 1210 StartSpeed%=100
 1220 Direction$="Left "
 1230 State$="Stopped"
 1240 SpeedCount%=0
 1250 Flag%=0
 1260 SpeedCount$="Stop"
 1270 ENDPROC
 1280
 1290
 1300 DEFPROCwindow(WindowWidth%,WindowHeight%,WindowTitle$)
 1310 MODE 30
 1320 SYS "SetWindowPos",@hwnd%,0,0,0,WindowWidth%,WindowHeight%,6
 1330 COLOUR 128
 1340 CLS
 1350 COLOUR 15
 1360 VDU 26
 1370 SYS "SetWindowText",@hwnd%,WindowTitle$
 1380 ENDPROC
 1390
 1400
 1410 DEFPROCerror
 1420 PRINT REPORT$;" at line ";ERL  :
 1430 SYS K8055_ClearAllDigital%,1
 1440 SYS K8055_ClearAllAnalog%,1
 1450 SYS K8055_CloseDevice%,1
 1460 SYS "FreeLibrary",K8055_Board%
 1470 END
 1480 ENDPROC
 1490
 1500
 1510 DEFPROCK8055_init
 1520 REM These are all the system calls in the order found in the manual
 1530 SYS"LoadLibrary","K8055D.dll" TO K8055_Board%
 1540 SYS"GetProcAddress",K8055_Board%,"OpenDevice" TO K8055_OpenDevice%
 1550 SYS"GetProcAddress",K8055_Board%,"CloseDevice" TO K8055_CloseDevice%
 1560 SYS"GetProcAddress",K8055_Board%,"ReadAnalogChannel" TO K8055_ReadAnalogChannel%
 1570 SYS"GetProcAddress",K8055_Board%,"ReadAllAnalog" TO K8055_ReadAllAnalog%
 1580 SYS"GetProcAddress",K8055_Board%,"OutputAnalogChannel" TO K8055_OutputAnalogChannel%
 1590 SYS"GetProcAddress",K8055_Board%,"OutputAllAnalog" TO K8055_OutputAllAnalog%
 1600 SYS"GetProcAddress",K8055_Board%,"ClearAnalogChannel" TO K8055_ClearAnalogChannel%
 1610 SYS"GetProcAddress",K8055_Board%,"ClearAllAnalog" TO K8055_ClearAllAnalog%
 1620 SYS"GetProcAddress",K8055_Board%,"SetAnalogChannel" TO K8055_SetAnalogChannel%
 1630 SYS"GetProcAddress",K8055_Board%,"SetAllAnalog"  TO K8055_SetAllAnalog%
 1640 SYS"GetProcAddress",K8055_Board%,"WriteAllDigital" TO K8055_WriteAllDigital%
 1650 SYS"GetProcAddress",K8055_Board%,"ClearDigitalChannel" TO K8055_ClearDigitalChannel%
 1660 SYS"GetProcAddress",K8055_Board%,"ClearAllDigital" TO K8055_ClearAllDigital%
 1670 SYS"GetProcAddress",K8055_Board%,"SetDigitalChannel" TO K8055_SetDigitalChannel%
 1680 SYS"GetProcAddress",K8055_Board%,"SetAllDigital"  TO K8055_SetAllDigital%
 1690 SYS"GetProcAddress",K8055_Board%,"ReadDigitalChannel" TO K8055_ReadDigitalChannel%
 1700 SYS"GetProcAddress",K8055_Board%,"ReadAllDigital"  TO K8055_ReadAllDigital%
 1710 SYS"GetProcAddress",K8055_Board%,"ResetCounter"  TO K8055_ResetCounter%
 1720 SYS"GetProcAddress",K8055_Board%,"ReadCounter"  TO K8055_ReadCounter%
 1730 SYS"GetProcAddress",K8055_Board%,"SedtCounterDebouceTime"  TO K8055_SetCounterDebounceTime%
 1740 ENDPROC


 



Return to the interfacing index

Back to the Limavady home page

Tudor with sign