Control rc car using raspberry pi (Part 5 : Wire up raspberry pi...)
Tags: beginners, raspberrypi, python, unity3d
Published: 2023-08-13 12:37:52

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8f8ijz4gxuaqam3hh0gc.png)

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](https://github.com/medmor/carProjectServer/tree/main)

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)

```

The car needs tow `Motor`s 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](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html)

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()
```