Silicon Derby Base Vehicle

This is the basic code for version 1 of dojo derby vehicle.

Version 2 will change the fee tech module with an h bridge, and the code will be modified. Also speed controls need to be added.

Requriements:

  • Pi 4
  • Pi Camera
  • 4 motors and wheels
  • Fee Tech servo motor controller module

Index.php is used as the web control panel, and in an iFrame the web video from the pi cam is streamed.

wifiCar.py is the control script for the vehicle. It starts automatically when the pi boots up.

videoStream.py is the script that stream the pi camera video.

index.php


<h1 style="font-align:center;">WiFi Car App</h1>
<?php

$command=$_GET['command'];
file_put_contents("command.txt", $command);
print "Command: ".$command."<br>";
?>

<div style="width:510; height:390; margin-left:auto; margin-right:auto;">
http://192.168.1.14:8000
</div>

<div style="width:170; height:100; margin-left:auto; margin-right:auto;">
<table>
<tr><td><a href="index.php?command=forwardLeft">F Left</a></td><td><a href="index.php?command=forward">Forward</a></td><td><a href="index.php?command=forwardRight">F Right</a></td></tr>
<tr><td><a href="index.php?command=left">Left</a></td><td style="text-align:center;"><a href="index.php?command=stop">Stop</a></td><td><a href="index.php?command=right">Right</a></td></tr>
<tr><td></td><td><a href="index.php?command=backward">Backward</a>
</td><td></td></tr>
</table>
</div>

wifiCar.py

import RPi.GPIO as GPIO
import time

lSensor = 17
mSensor = 27
rSensor = 22

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(6, GPIO.OUT)
GPIO.setup(lSensor,GPIO.IN)
GPIO.setup(mSensor,GPIO.IN)
GPIO.setup(rSensor,GPIO.IN)


pR = GPIO.PWM(12,100)
pL = GPIO.PWM(6,100)

while True:
    
    if (GPIO.input(lSensor) != 1):
        print ("LEFT")
        pR.start(5)
        pL.start(20)
        time.sleep(.5)

    if (GPIO.input(mSensor) !=1):
        print ("Middle")
        pR.start(5)
        pL.start(5)
        time.sleep(.5)

    if (GPIO.input(rSensor) != 1):
        print ("RIGHT")
        pR.start(20)
        pL.start(5)
        time.sleep(.5)

        
    
    file = open("/var/www/html/command.txt","r")
    print("from file: ")
    command = file.read()
    print(command)
    file.close()
            
    #Forward
    if command == "forward":
        pR.start(20)
        pL.start(20)
        
    #Left Forward
    elif command == "forwardLeft":
        pR.start(20)
        pL.start(15)
        
    #Right Forward
    elif command == "forwardRight":
        pR.start(15)
        pL.start(20)    
    
    elif command == "backward":
    #Backward
        pR.start(5)
        pL.start(5)
    
    elif command == "left":
        pR.start(20)
        pL.start(5)
    
    elif command == "right":
        pR.start(5)
        pL.start(20)
   
    elif command == "stop": 
        pR.start(0)
        pL.start(0)
    
    else:
        print ("Error")
#        pR.start(20)
#        pL.start(20)
#        time.sleep(1)
#        pR.start(1)
#        pL.start(1)
#        time.sleep(1)
#        pR.start(0)
#        pL.start(0)
#        time.sleep(1)


    

videoStream.py

import io
import picamera
import logging
import socketserver
from threading import Condition
from http import server

PAGE="""\
<html>
<body>
<img src="stream.mjpg" width="640" height="480" />
</body>
</html>
"""

class StreamingOutput(object):
    def __init__(self):
        self.frame = None
        self.buffer = io.BytesIO()
        self.condition = Condition()

    def write(self, buf):
        if buf.startswith(b'\xff\xd8'):
            # New frame, copy the existing buffer's content and notify all
            # clients it's available
            self.buffer.truncate()
            with self.condition:
                self.frame = self.buffer.getvalue()
                self.condition.notify_all()
            self.buffer.seek(0)
        return self.buffer.write(buf)

class StreamingHandler(server.BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            self.send_response(301)
            self.send_header('Location', '/index.html')
            self.end_headers()
        elif self.path == '/index.html':
            content = PAGE.encode('utf-8')
            self.send_response(200)
            self.send_header('Content-Type', 'text/html')
            self.send_header('Content-Length', len(content))
            self.end_headers()
            self.wfile.write(content)
        elif self.path == '/stream.mjpg':
            self.send_response(200)
            self.send_header('Age', 0)
            self.send_header('Cache-Control', 'no-cache, private')
            self.send_header('Pragma', 'no-cache')
            self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME')
            self.end_headers()
            try:
                while True:
                    with output.condition:
                        output.condition.wait()
                        frame = output.frame
                    self.wfile.write(b'--FRAME\r\n')
                    self.send_header('Content-Type', 'image/jpeg')
                    self.send_header('Content-Length', len(frame))
                    self.end_headers()
                    self.wfile.write(frame)
                    self.wfile.write(b'\r\n')
            except Exception as e:
                logging.warning(
                    'Removed streaming client %s: %s',
                    self.client_address, str(e))
        else:
            self.send_error(404)
            self.end_headers()

class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer):
    allow_reuse_address = True
    daemon_threads = True

with picamera.PiCamera(resolution='640x480', framerate=24) as camera:
    output = StreamingOutput()
    camera.start_recording(output, format='mjpeg')
    try:
        address = ('', 8000)
        server = StreamingServer(address, StreamingHandler)
        server.serve_forever()
    finally:
        camera.stop_recording()

Be the first to comment

Leave a Reply