Double DC motor control using pulse width modulation
|
![]() | ![]() |
|
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 BB4WK8055_Dual-pwm.zipand here is a link to a video of the projectVideo link |
10 REM K8055_Two-PWM 20 REM Control two motors using PWM and the Velleman K8055 USB board 30 REM Version 1.0 40 REM Jochen Lueg 50 REM http://roevalley.com 60 REM February 2012 70 80 PROCK8055_init 90 SYS K8055_CloseDevice%,0 100 SYS K8055_OpenDevice%, 0 110 120 ON ERROR PROCerror 130 140 PROCscreen(380,300) 150 OFF 160 PROCinit 170 SYS K8055_OutputAnalogChannel%,1,255 180 SYS K8055_OutputAnalogChannel%,2,255 190 200 PRINT 210 PRINT " Motor 1" 220 PRINT " Left - Stop - Right . . . . . A - S - D" 230 PRINT " Slower - Faster . . . . . . . K - L" 240 PRINT 250 PRINT " Motor 2" 260 PRINT " Left - Stop - Right . . . . . Z - X - C" 270 PRINT " Slower - Faster . . . . . . . < - >" 280 PRINT 290 PRINT " Leave the program . . . . . . Q" 300 310 REPEAT 320 Key$=INKEY$(0) 330 340 REPEAT UNTIL INKEY(0)=-1 350 IF (Key$="a" OR Key$="A") AND (M1_Direction$="M1_Right" OR M1_State$="M1_Stopped") PROCM1_left 360 IF (Key$="s" OR Key$="S") AND M1_State$="M1_Running" PROCM1_stop 370 IF (Key$="d" OR Key$="D") AND (M1_Direction$="M1_Left" OR M1_State$="M1_Stopped") PROCM1_right 380 390 IF (Key$="z" OR Key$="Z") AND (M2_Direction$="M2_Right" OR M2_State$="M2_Stopped") PROCM2_left 400 IF (Key$="x" OR Key$="X") AND M2_State$="M2_Running" PROCM2_stop 410 IF (Key$="c" OR Key$="C") AND (M2_Direction$="M2_Left" OR M2_State$="M2_Stopped") PROCM2_right 420 430 IF Key$="k" OR Key$="K" THEN 440 M1_RunningSpeed%+=1 450 IF M1_RunningSpeed%>255 M1_RunningSpeed%=255 460 SYS K8055_OutputAnalogChannel%,1,M1_RunningSpeed% 470 M1_StartSpeed%=M1_RunningSpeed% 480 REPEAT UNTIL INKEY(0)=-1 490 ENDIF 500 IF Key$="l" OR Key$="L" THEN 510 M1_RunningSpeed%-=1 520 IF M1_RunningSpeed%<0 M1_RunningSpeed%=0 530 SYS K8055_OutputAnalogChannel%,1,M1_RunningSpeed% 540 M1_StartSpeed%=M1_RunningSpeed% 550 REPEAT UNTIL INKEY(0)=-1 560 ENDIF 570 580 IF Key$="," OR Key$="<" THEN 590 M2_RunningSpeed%+=1 600 IF M2_RunningSpeed%>255 M2_RunningSpeed%=255 610 SYS K8055_OutputAnalogChannel%,2,M2_RunningSpeed% 620 M2_StartSpeed%=M2_RunningSpeed% 630 REPEAT UNTIL INKEY(0)=-1 640 ENDIF 650 IF Key$="." OR Key$=">" THEN 660 M2_RunningSpeed%-=1 670 IF M2_RunningSpeed%<0 M2_RunningSpeed%=0 680 SYS K8055_OutputAnalogChannel%,2,M2_RunningSpeed% 690 M2_StartSpeed%=M2_RunningSpeed% 700 REPEAT UNTIL INKEY(0)=-1 710 ENDIF 720 PROCfeedback(M1_RunningSpeed%,M2_RunningSpeed%) 730 740 750 UNTIL Key$="q" OR Key$="Q" 760 770 PROCM1_stop:PROCM2_stop 780 SYS K8055_ClearAllDigital% 790 SYS K8055_OutputAnalogChannel%,1,255 800 SYS K8055_OutputAnalogChannel%,2,255 810 SYS K8055_CloseDevice% 820 SYS "FreeLibrary",K8055_Board% 830 *QUIT 840 END 850 860 870 880 DEFPROCfeedback(Speed1%,Speed2%) 890 LOCAL S% 900 COLOUR 6 910 S1%=(255-Speed1%)/2.55 920 S2%=(255-Speed2%)/2.55 930 940 PRINTTAB(2,13)M1_State$;" ";M1_Direction$;" Speed: ";S1%;" " 950 PRINTTAB(2,14)M2_State$;" ";M2_Direction$;" Speed: ";S2%;" " 960 ENDPROC 970 980 990 DEFPROCM1_right 1000 PROCM1_stop 1010 SYS K8055_SetDigitalChannel%,8 1020 PROCM1_start 1030 M1_Direction$="M1_Right" 1040 ENDPROC 1050 1060 1070 DEFPROCM1_left 1080 PROCM1_stop 1090 SYS K8055_ClearDigitalChannel%,8 1100 PROCM1_start 1110 M1_Direction$="M1_Left" 1120 ENDPROC 1130 1140 1150 DEFPROCM1_start 1160 FOR J%= 255 TO M1_StartSpeed% STEP-4 1170 SYS K8055_OutputAnalogChannel%,1,J% 1180 PROCfeedback(J%,M2_RunningSpeed%) 1190 NEXT 1200 M1_RunningSpeed%=M1_StartSpeed% 1210 M1_State$="M1_Running" 1220 ENDPROC 1230 1240 | 1250 DEFPROCM1_stop 1260 FOR J%= M1_RunningSpeed% TO 255 STEP 4 1270 SYS K8055_OutputAnalogChannel%,1,J% 1280 PROCfeedback(J%,M2_RunningSpeed%) 1290 NEXT 1300 M1_State$="M1_Stopped" 1310 M1_RunningSpeed%=255 1320 ENDPROC 1330 1340 DEFPROCM2_start 1350 FOR J%= 255 TO M1_StartSpeed% STEP-4 1360 SYS K8055_OutputAnalogChannel%,2,J% 1370 PROCfeedback(M1_RunningSpeed%,J%) 1380 NEXT 1390 M2_RunningSpeed%=M2_StartSpeed% 1400 M2_State$="M2_Running" 1410 ENDPROC 1420 1430 1440 DEFPROCM2_stop 1450 FOR J%= M2_RunningSpeed% TO 255 STEP 4 1460 SYS K8055_OutputAnalogChannel%,2,J% 1470 PROCfeedback(M2_RunningSpeed%,J%) 1480 NEXT 1490 M2_State$="M2_Stopped" 1500 M2_RunningSpeed%=255 1510 ENDPROC 1520 1530 1540 DEFPROCM1_right 1550 PROCM1_stop 1560 SYS K8055_SetDigitalChannel%,8 1570 PROCM1_start 1580 M1_Direction$="M1_Right" 1590 ENDPROC 1600 1610 1620 DEFPROCM1_left 1630 PROCM1_stop 1640 SYS K8055_ClearDigitalChannel%,8 1650 PROCM1_start 1660 M1_Direction$="M1_Left" 1670 ENDPROC 1680 1690 1700 1710 DEFPROCM2_right 1720 PROCM2_stop 1730 SYS K8055_SetDigitalChannel%,7 1740 PROCM2_start 1750 M2_Direction$="M2_Right" 1760 ENDPROC 1770 1780 1790 DEFPROCM2_left 1800 PROCM2_stop 1810 SYS K8055_ClearDigitalChannel%,7 1820 PROCM2_start 1830 M2_Direction$="M2_Left" 1840 ENDPROC 1850 1860 1870 DEFPROCinit 1880 M1_RunningSpeed%=255 1890 M1_StartSpeed%=100 1900 M2_RunningSpeed%=255 1910 M2_StartSpeed%=100 1920 1930 M1_Direction$="M1_Left" 1940 M1_State$="M1_Stopped" 1950 M2_Direction$="M2_Left" 1960 M2_State$="M2_Stopped" 1970 ENDPROC 1980 1990 2000 DEFPROCscreen(ScreenWidth%,ScreenHeight%) 2010 COLOUR 128 2020 CLS 2030 COLOUR 15 2040 SYS "SetWindowPos",@hwnd%,-1,0,0,ScreenWidth%,ScreenHeight%,0 2050 VDU 26 2060 ENDPROC 2070 2080 2090 DEFPROCerror 2100 PRINT REPORT$;" at line ";ERL : 2110 SYS K8055_ClearAllDigital%,1 2120 SYS K8055_ClearAllAnalog%,1 2130 SYS K8055_CloseDevice%,1 2140 SYS "FreeLibrary",K8055_Board% 2150 END 2160 ENDPROC 2170 2180 2190 DEFPROCK8055_init 2200 REM These are all the system calls in the order found in the manual 2210 SYS"LoadLibrary","K8055D.dll" TO K8055_Board% 2220 SYS"GetProcAddress",K8055_Board%,"OpenDevice" TO K8055_OpenDevice% 2230 SYS"GetProcAddress",K8055_Board%,"CloseDevice" TO K8055_CloseDevice% 2240 SYS"GetProcAddress",K8055_Board%,"ReadAnalogChannel" TO K8055_ReadAnalogChannel% 2250 SYS"GetProcAddress",K8055_Board%,"ReadAllAnalog" TO K8055_ReadAllAnalog% 2260 SYS"GetProcAddress",K8055_Board%,"OutputAnalogChannel" TO K8055_OutputAnalogChannel% 2270 SYS"GetProcAddress",K8055_Board%,"OutputAllAnalog" TO K8055_OutputAllAnalog% 2280 SYS"GetProcAddress",K8055_Board%,"ClearAnalogChannel" TO K8055_ClearAnalogChannel% 2290 SYS"GetProcAddress",K8055_Board%,"ClearAllAnalog" TO K8055_ClearAllAnalog% 2300 SYS"GetProcAddress",K8055_Board%,"SetAnalogChannel" TO K8055_SetAnalogChannel% 2310 SYS"GetProcAddress",K8055_Board%,"SetAllAnalog" TO K8055_SetAllAnalog% 2320 SYS"GetProcAddress",K8055_Board%,"WriteAllDigital" TO K8055_WriteAllDigital% 2330 SYS"GetProcAddress",K8055_Board%,"ClearDigitalChannel" TO K8055_ClearDigitalChannel% 2340 SYS"GetProcAddress",K8055_Board%,"ClearAllDigital" TO K8055_ClearAllDigital% 2350 SYS"GetProcAddress",K8055_Board%,"SetDigitalChannel" TO K8055_SetDigitalChannel% 2360 SYS"GetProcAddress",K8055_Board%,"SetAllDigital" TO K8055_SetAllDigital% 2370 SYS"GetProcAddress",K8055_Board%,"ReadDigitalChannel" TO K8055_ReadDigitalChannel% 2380 SYS"GetProcAddress",K8055_Board%,"ReadAllDigital" TO K8055_ReadAllDigital% 2390 SYS"GetProcAddress",K8055_Board%,"ResetCounter" TO K8055_ResetCounter% 2400 SYS"GetProcAddress",K8055_Board%,"ReadCounter" TO K8055_ReadCounter% 2410 SYS"GetProcAddress",K8055_Board%,"SedtCounterDebouceTime" TO K8055_SetCounterDebounceTime% 2420 ENDPROC |
Return
to the interfacing index
|