DEV Community

Cover image for Control rc car using raspberry pi (Part 5 : Wire up raspberry pi...)
medmor
medmor

Posted on

Control rc car using raspberry pi (Part 5 : Wire up raspberry pi...)

The next image show how we can wire up the raspberry pi to the motor driver to control the two motors of the rc car.

Wiring the car to the raspberry py

I did my best, but I know it's a messy drawing.

Change the server.py to control the car

You can find the project at github here

In the server script, we will use a Car class to wrap all the needed functionalities to control the car.
For example: car.runForward(), car.setSpeed(), car.turnLeft() ...

The final server script look like this:

from bottle import post, route, static_file, run
from car import Motor, Car

car = Car(Motor(23, 24), Motor(18, 15, 14))

@route("/")
def index():
    return static_file("index.html", root="./")

@post("/right")
def right():
    car.turnRight()

@post("/left")
def left():
    car.turnLeft()

@post("/center")
def center():
    car.resetDir()

@post("/forward/<amount>")
def forwardWithSpeed(amount):
    car.setSpeed(int(amount))
    car.runForward()

@post("/backward/<amount>")
def backwardWithSpeed(amount):
    car.setSpeed(int(amount))
    car.runBackward()

@post("/speed/<amount>")
def speed(amount):
    car.setSpeed(int(amount))

@post("/stop")
def stop():
    car.stop()

@post("/siren")
def siren():
    car.siren()


run(host="0.0.0.0", port=8080, debug=True)

Enter fullscreen mode Exit fullscreen mode

The car needs tow Motors instances passed as parameters.
The Motor class receive 2 or 3 numbers. These numbers are raspberry pi pins out used to control the motor. For more information about the pins, you can see here

I think if I try to explain how the GPIOs are set and used to control the motor and change the speed, the article will be too long. But I think also that by just reading the code and little search, you can understand how it works.

The Car and The Motor classes are defined like this:

import RPi.GPIO as GPIO
import pygame

GPIO.setmode(GPIO.BCM)

class Motor:
    def __init__(self, io1: int, io2: int, io3=-1) -> None:
        self.io1 = io1
        self.io2 = io2
        GPIO.setup(io1, GPIO.OUT)
        GPIO.setup(io2, GPIO.OUT)
        if io3 > 0:
            GPIO.setup(io3, GPIO.OUT)
            self.io3 = GPIO.PWM(io3, 1000)
            self.io3.start(60)

    def forward(self):
        GPIO.output(self.io1, GPIO.HIGH)
        GPIO.output(self.io2, GPIO.LOW)

    def backward(self):
        GPIO.output(self.io1, GPIO.LOW)
        GPIO.output(self.io2, GPIO.HIGH)

    def stop(self):
        GPIO.output(self.io1, GPIO.LOW)
        GPIO.output(self.io2, GPIO.LOW)

    def setSpedd(self, speed: int):
        self.io3.ChangeDutyCycle(speed)


class Car:

    def __init__(self, frontMotor: Motor, backMotor: Motor) -> None:
        self.frontMotor = frontMotor
        self.backMotor = backMotor
        pygame.mixer.init()
        pygame.mixer.music.load("siren.mp3")
        pygame.mixer.music.set_volume(1.0)

    def turnRight(self):
        self.frontMotor.forward()

    def turnLeft(self):
        self.frontMotor.backward()

    def resetDir(self):
        self.frontMotor.stop()

    def runForward(self):
        self.backMotor.forward()

    def runBackward(self):
        self.backMotor.backward()

    def stop(self):
        self.backMotor.stop()

    def setSpeed(self, speed: int):
        self.backMotor.setSpedd(speed)

    def siren(self):
        if(pygame.mixer.music.get_busy()==0):
            pygame.mixer.music.play()
        else:
            pygame.mixer.music.stop()

    #to do : call this method on server stop
    def cleanup():
        GPIO.cleanup()
Enter fullscreen mode Exit fullscreen mode

Top comments (0)