Dual DC motor control using pwm with the Raspberry Pi


The projectThis project uses two IRF 630 MOS-FET transistors for pulse width modulation and two relays to change the direction of the two motors. . The circuit diagram is below. The two IRF 630 MOS-FETs are connected to the GPIO 15 and 18 pins of the Pi. GPIO 24 and 23 are used to switch the relays. As the RISC OS version of the Raspberry Pi does not have a PWM output (as yet), the signals at GPIO 15 and GPIO 18  need to be pulsed by the control program.

A suggested pcb layout is below right. It need hardly be stated that the relays and the motor have the same voltage rating, in this case between 6 and 8V. The four diodes control the back emf of the relays and the motor. They should be type 1N4148 or similar signal diodes.


Double pulse width diagram
The pcb layout

The double PWM projectThe entire project is on the right. The two motors are hidden by the two big red wheels,k the Pi is to the left of the motors and my 5 in 16 out interface is on the left. The dual pwm circuit board is at the front of the picture..


The program

The program works surprisingly well and allows the speed of both motors to be regulated very smoothly. The heart of the algorithm is below.

  550 DEFPROCpulse(P1%,P2%)
  560 LOCAL N%,M%,J%
  570 IF Go1%=0 P1%=99
  580 IF Go2%=0 P2%=99
  590 FOR J%=1 TO 100
  600   IF J%<P1% N%=1 ELSE N%=0
  610   IF J%<P2% M%=1 ELSE M%=0
  620   SYS&58F81,23,N%
  630   SYS&58F81,24,M%
  640 NEXT
  650 ENDPROC

PROCpulse is called continuously from within the main loop of the program. It assigns high and low values to mthe waveform and sends these 100 times to the GPIO outputs. Then it returns to the main loop where those values can be changed. I was amazed at just how ell this worked. P1% and P2% contain determine the length of time the pulse for the motor is high. This can be a number between 0 and 99.

Below is a zip archive with  the BBC BASIC program file and the drawfile of the pcb layout.

2xpi_pwm.zip

Below is a link to a multi-tasking program which does the same job as the program above but with a touch more elegance.

!PWMx2

Below is a link to a video demonstration of the project.

Video link


    10 REM 2x_Pi-pwm
   20 REM Control two motors using pwm
   30 REM Needs my 5in 16 out interface
   40 REM (c) Jochen Lueg
   50 REM http://roevalley.com
   60 REM Limavady, January 2013
   70 REM Version 1.0
   80
   90 ON ERROR PROCerror
  100 PROCsetupGPIO
  110
  120 OFF
  130
  140 PRINT''''
  150 PRINT " First motor"
  160 PRINT
  170 PRINT' " Z - X - C  - - -   Left - Stop - Right"
  180 PRINT
  190 PRINT  "   A - S    - - -   Faster - Slower"
  200 PRINT''
  210 PRINT " Second motor"
  220 PRINT
  230 PRINT' " < - > - ?  - - -   Left - Stop - Right"
  240 PRINT
  250 PRINT  "   K - L    - - -   Faster - Slower"
  260 PRINT''
  270 PRINT'" Start either motor by pressing the relevant Left or Right keys"
  280 PRINT
  290 PRINT " Press 'Q' to finish"
  300
  310 SYS"GPIO_WriteData",PWM1%,1
  320 SYS"GPIO_WriteData",PWM2%,1
  330
  340 REPEAT
  350   IF INKEY(-98)  SYS"GPIO_WriteData",Dir1%,0:Go1%=1
  360   IF INKEY(-67)  Go1%=0
  370   IF INKEY(-83)  SYS"GPIO_WriteData",Dir1%,1:Go1%=1
  380   IF INKEY(-103) SYS"GPIO_WriteData",Dir2%,0:Go2%=1
  390   IF INKEY(-104) Go2%=0
  400   IF INKEY(-105) SYS"GPIO_WriteData",Dir2%,1:Go2%=1
  410   IF INKEY(-66)  Sp1%-=1:IF Sp1%<0 Sp1%=0
  420   IF INKEY(-82)  Sp1%+=1:IF Sp1%>9999 Sp1%=9999
  430   IF INKEY(-71)  Sp2%-=1:IF Sp2%<0 Sp2%=0
  440   IF INKEY(-87)  Sp2%+=1:IF Sp2%>9999 Sp2%=9999
  470   PROCpulse(Sp1%/100,Sp2%/100)
  480 UNTIL INKEY(-17)
  490 SYS"GPIO_WriteData",PWM1%,1
  500 SYS"GPIO_WriteData",PWM2%,1
  510 QUIT
  520 END
  530
  540
  550 DEFPROCpulse(P1%,P2%)
  560 LOCAL N%,M%,J%
  570 IF Go1%=0 P1%=99
  580 IF Go2%=0 P2%=99
  590 FOR J%=1 TO 100
  600   IF J%<P1% N%=1 ELSE N%=0
  610   IF J%<P2% M%=1 ELSE M%=0
  620   SYS&58F81,23,N%
  630   SYS&58F81,24,M%
  640 NEXT
  650 ENDPROC
  660
  670
  680 DEFPROCsetupGPIO
  690 OSCLI"RMensure GPIO 0.00 RMLoad GPIO"
  700 OSCLI"RMensure GPIO 0.40 ERROR  Please install the GPIO module"
  710
  720 SYS"GPIO_EnableI2C",0
  730 SYS"GPIO_ExpAsGPIO",2
  740 DIM Port%(3)
  750 Port%()=24,23,18,15
  760 REM Set up the otput lines
  770 FOR J%=0 TO 3
  780   SYS"GPIO_WriteMode",Port%(J%),1
  790 NEXT
  800
  810 PWM2%=24 : PWM1%=23
  820 Dir2%=18 : Dir1%=15: REM Direction of themotors
  830 Sp2%=5000  : Sp1%=5000 : REM Speed of the two motors
  840 Go2%=0   : Go1%=0  : REM ON/OFF state of the motors
  850 ENDPROC
  860
  870
  880 DEFPROCerror
  890 CLS
  900 SYS"GPIO_WriteData",PWM2%,1
  910 SYS"GPIO_WriteData",PWM1%,1
  920 PRINT REPORT$;" at line ";ERL
  930 END
  940 ENDROC





Return to the interfacing index

Back to the Limavady home page

Tudor with sign