After proving that I could use a Raspberry Pi to drive a Servo, I decided to change out the motor drive steering of this car for a servo and adjust the software accordingly to drive it. The initial video that explained it all was at https://www.youtube.com/watch?v=N5QmZ92uvUo and he explains teh concepts behind PWM control with it. A simpler explanation is at https://www.youtube.com/watch?v=xHDT4CwjUQE
I have got it working but have not yet taken it out on the road because the R-Pi is sitting beside the car like a heart monitor.
Here is the servo in position for steering car I drilled a hole in the steering arm for the servo arm to go through, rather than trying anything fancy like rods as usually seen in RC airplane controls. The Servo is stuck in place courtesy of my hot glue gun. At the top right of the picture is the original steering motor just pushed out of place.
Raspberry Pi Model B connected to the Car. All of the pins connected to the second row of the GPIO except for a yellow ground pin.
Pin 2 +5v to Servo Black wire
Pin 6 gnd to Servo Reddish wire
pin 12 to IC socket pin 11
Pin 16 to IC socket pin 10
Pin 18 PWM to Servo Yellow wire
Pin 9 gnd to IC socket pin 2 (gnd)
See this previous writeup for the IC pinouts on the control board. https://madsmaddad.blogspot.com/2018/03/second-rc-car.html
This shows the IC socket replacing the receiver IC on the driver board. The black connector card connects all the driver outputs to the relevant motor and also brings in the power for the board from the battery pack at the bottom of the picture.
SOFTWARE
This uses the Flask setup with the Wifi setup as an Access Point so that I can work direct to it from my tablet.
There are three programs required.
Shell script: Incorporate this in rc.local to make it run at startup,
export FLASK_APP=/home/pi/rc-car/app.py
flask run --host=192.168.1.8
Set IP address to correct address for the Access Point setup.
HTML:
<!DOCTYPE html>
<! developed using https://www.w3schools.com/css/css_grid.asp for the grid 30 Jan2019
<html>
<head>
<title>RC-Car with Flask & PWM steering 20-1-2020</title>
<style>
.grid-container {
display: grid;
grid-template-columns: auto auto auto auto;
background-color: #ffffff;
padding: 10px;
grid-column-gap: 20px;
grid-row-gap: 50px;
}
.grid-item {
background-color: rgba(255, 255, 255, 0.8);
border: 3px solid rgba(0, 0, 0, 0.8);
padding: 20px;
font-size: 50px;
text-align: center;
}
</style>
</head>
<body>
<h1 align="center">RC-Car with Flask & PWM 20-1-2020</h1>
<div class="grid-container">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item">
<a href="/motor-forwards/" data-toggle="tooltip" title="Forward" class="btn btn-success">Forward</a>
</div>
<div class="grid-item"></div>
<div class="grid-item">
<a href="/motor-left/" data-toggle="tooltip" title="Left-Left-Left!" class="btn btn-success">Turn Left</a>
</div>
<div class="grid-item">
<a href="/turn-center/" data-toggle="tooltip" title="Left-Left-Left!" class="btn btn-success">Center</a>
</div>
<div class="grid-item">
<a href="/motor-stop/" data-toggle="tooltip" title="Stop Motors" class="btn btn-danger">STOP</a>
</div>
<div class="grid-item">
<a href="/motor-right/" data-toggle="tooltip" title="Turn right!" class="btn btn-success">Turn Right</a>
</div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item">
<a href="/motor-backwards/" data-toggle="tooltip" title="Reverse!" class="btn btn-warning">Backward</a>
</div>
<div class="grid-item"></div>
</div>
</body>
</html>
Note that I have used W3Schools for a lot of help in getting my HTML correct. Some of the bits in each line referencing the contents of a box are possibly redundant. They were there in the code where I pinched the stuff. [ see below for simplified stuff].
PYTHON:
# 2020-1-20 Modifications to drive steering using a servo and PWM. Because I
# don't know if gpiozero and RPi.GPIO can work together I'll remove the GPIOzero and motor
# command. motor = Motor(forward=12, backward=16)
# look at ancient code for motor handling.
# 2018-04-05 Modified from Les Pounder program to handle two motors
# one for steering and one for motion
# steering is Left = 10, right = 11
# changing it trying to add Turn for motor control
# 2018-10-31 changing toggle LED to stop motors
from flask import Flask, render_template
from time import sleep
import RPi.GPIO as GPIO
#Set GPIO Numbering mode
GPIO.setmode(GPIO.BOARD)
# set pins for motor control
GPIO.setup(12,GPIO.OUT)
GPIO.setup(16,GPIO.OUT)
# set pin 18 as Output for Servo Steering
GPIO.setup(18,GPIO.OUT)
servo_st = GPIO.PWM(18,50)
#start PWM running on servo, init value 0 (pulse off)
servo_st.start(0)
# servo runs from duty cycle 2 to duty cycle 12, 7 being central position for servo used in youtube demo.
# define variable duty
duty = 2
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/motor-stop/')
def on():
GPIO.output(12,False)
GPIO.output(16,False)
return render_template('index.html')
@app.route('/motor-forwards/')
def motorforwards():
GPIO.output(12,True)
GPIO.output(16,False)
return render_template('index.html')
@app.route('/motor-backwards/')
def motorbackwards():
GPIO.output(12,False)
GPIO.output(16,True)
return render_template('index.html')
@app.route('/motor-left/')
def motorleft():
duty = 2
servo_st.start(duty)
sleep(1.3)
servo_st.ChangeDutyCycle(0)
return render_template('index.html')
@app.route('/turn-center/')
def centersteering():
duty = 7
servo_st.start(duty)
sleep(0.3)
servo_st.ChangeDutyCycle(0)
return render_template('index.html')
@app.route('/motor-right/')
def motorright():
duty = 15
servo_st.start(duty)
sleep(0.3)
servo_st.ChangeDutyCycle(0)
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
The major changes in this, other than PWM operation, is the change to GPIO Board numbering rather than GPIO Name numbering. Also I stopped using GPIOzero, so have reverted to direct control of pins in the software. I like this better. Comments can be used to explain functions that are not clear.
Questions: I am happy to answer them, but they may be already answered in previous posts.
27/1/2020 corrections and simplifications
The line
<a href="/motor-forwards/" data-toggle="tooltip" title="Forward" class="btn btn-success">Forward</a>
can be simplified by removing things that don't serve any purpose in this case. It becomes:
<a href="/motor-forwards/" >Forward</a>
SERVOS
I was given a box of Servos and after having problems with the one that I had put in the car, I went through them plugging them into the Raspberry Pi.
Four of them totally didn't work and caused the R-Pi to shut down. These were all small ones without labels.
Some of them partially worked.
Here is a breakdown of what happened. The software is set to duty cycle 2 for a Left turn, 7 for a centre position, and 15 for a right turn. I noticed that in some cases the servo shaft turned CCW when I expected CW, and am now confused as to which is left and right.
Device Left Centre Right
small unit with black arm. x ? ?
Small unit with white arm -90 0 +90 (CW)
Digifleet FPS-20 -60 0 +60
Digifleet FPS-30 dead kills Pi.
Aristocraft HS-100 -90 increments increments
'increments' possibly means that I have to extend the range. needs testing
GWS Mini STD +90 0 -90
Tower Pro Airplane 99 iffy, slow to respond
Small Black with arm +110 no response -100
Black, short wires +110 -90
Digifleet FPS33 (2) dead
Black with black arm. dead
Powermax Skyranger 5 white-X arm +75 steps -70
Steps/increments probably means that I have to expand the range from 2-7-15.
Another bothersome feature of these servos is that the arms, or whatever the proper term for them is, are different sizes and shapes so are not transferrable from one unit to another. Most are splined, but some are square.
2020-02-08 See https://en.wikipedia.org/wiki/Servo_control
It is not duty cycle that is important, it is pulse width, generally between 1msec to 2 msec wide.
Now I am using a value of duty 2-7-12 with a pulse rate of 50 Hertz.
Also:
https://learn.adafruit.com/adafruit-raspberry-pi-lesson-9-controlling-a-dc-motor/software
and
https://github.com/sarfata/pi-blaster
No comments:
Post a Comment