Path Finder¶
Description¶
This vehicle is designed to follow a specific colored path and measure the distance of the flat surface it is traveling. It is built to run on Raspberry Pi board, based on the Coder-Maker prototype : a combination of technology and scientific concepts.
Learning Objectives¶
- Conversion of angular to linear motion
- Relate wheel circumference and radius of a moving device to the distance traveled.
- Design and make an application based on the engineering design process
- Replicate the wiring connection and the Python code used on the Raspberry Pi
- Relate science concepts to real-life applications
Materials Needed¶
- Raspberry Pi with micro SD card with Raspbian
- Breadboard & Jumper Wires
- 2x Gear motors
- 2x Wheels
- L293d (H-bridge)
- Wheel Encoder
- MCP3008 (ADC)
- Analog Grayscale Sensor
- Glue gun
- Rectangular Plexiglas Board
- 6V battery
- 5V Power supply
Setup and Functionality¶
This application consists on controlling the wheels (aka gear motors) based on the grayscale sensor output, which detects black and white. According to the algorithm used, it outputs a result very close to zero when it detects white, and a larger output when it detects black. It is coded such that the machine will follow a white path: when it detects a black one, it will stop, and check left then right for a white path.
Meanwhile, it is measuring the distance traveled using a wheel encoder attached to one of the gear motors.
The H-bridge L293D is used to control the rotational direction of the gear motors.
The MCP3008 is used as an ADC to read the analog signal from the grayscale sensor and convert it to a digital signal for the Raspberry Pi to read.
Circuitry and Electronics:¶
All the electronics used are to be connected as shown in the picture below:

Programming¶
This application is coded using Python :
import RPi.GPIO as GPIO
import time
import spidev
# INITIALIZING
#CODE FOR GEAR MOTOR using H-bridge (L293d)
# Act upon the results of the grey sensor data
GPIO.setmode(GPIO.BOARD)
Motor1A = 7
Motor1B = 8
Motor1E = 10
GPIO.setup(Motor1A,GPIO.OUT)
GPIO.setup(Motor1B,GPIO.OUT)
GPIO.setup(Motor1E,GPIO.OUT)
Motor2A = 33
Motor2B = 35
Motor2E = 37
GPIO.setup(Motor2A,GPIO.OUT)
GPIO.setup(Motor2B,GPIO.OUT)
GPIO.setup(Motor2E,GPIO.OUT)
#CODE FOR WHEEL ENCODER // INITIALIZE
encoder=0
sum0=0
sum1=0
sum00=0
sum11=0
HighLow = -0.05
GPIO.setmode(GPIO.BOARD)
GPIO.setup(40,GPIO.IN)
temp = GPIO.input(40)
#CODE FOR GREY SENSOR using MCP
#MCP3008 uses SPI(Serial Peripheral Interface bus)
#SPI uses SPIDev library from Python
delay = 0.5
ldr_channel = 0 #Grey Sensor is connected to channel 0(pin 1) of MCP
spi = spidev.SpiDev()
spi.open(0,0)
#creating a function to read from channel
def readadc (adcnum):
if adcnum>7 or adcnum < 0:
return -1
adc = spi.xfer2([1, 8 + adcnum << 4, 0])
data = (( adc[1]&3) << 8 + adc[2])
return data
def color() :
sum1 = 0
sum2 = 0
ldr_value = readadc(ldr_channel)
if ldr_value != 0:
result = ldr_value/1024
sum1 = sum1 + 10
while result != (ldr_value%1023):
result = result/1024
sum1 = sum1 + 10
if sum1 > 1024:
break
result = ldr_value%1023
while result != 1:
result = result/2
sum2 = sum2 + 1
if sum2>1024:
break
result = ((sum1 + sum2)/1024.0)
print result
return result
# RUNNING
while True :
result = color()
while( result > 0.05):
print result
print 'BLACK'
print "Stopping motor"
GPIO.output(Motor1E,GPIO.LOW)
GPIO.output(Motor2E,GPIO.LOW)
time.sleep(1)
print "Checking white path"
GPIO.output(Motor1E,GPIO.HIGH)
GPIO.output(Motor1A,GPIO.HIGH)
GPIO.output(Motor1B,GPIO.LOW)
GPIO.output(Motor2E,GPIO.HIGH)
GPIO.output(Motor2A,GPIO.HIGH)
GPIO.output(Motor2B,GPIO.LOW)
time.sleep(0.5)
print "Checking TO THE LEFT"
GPIO.output(Motor1E,GPIO.HIGH)
GPIO.output(Motor1A,GPIO.LOW)
GPIO.output(Motor1B,GPIO.HIGH)
GPIO.output(Motor2E,GPIO.HIGH)
GPIO.output(Motor2A,GPIO.HIGH)
GPIO.output(Motor2B,GPIO.LOW)
time.sleep(3)
result = color()
if result < 0.05:
break
else :
print "Checking TO THE Right"
GPIO.output(Motor1E,GPIO.HIGH)
GPIO.output(Motor1A,GPIO.HIGH)
GPIO.output(Motor1B,GPIO.LOW)
GPIO.output(Motor2E,GPIO.HIGH)
GPIO.output(Motor2A,GPIO.LOW)
GPIO.output(Motor2B,GPIO.HIGH)
time.sleep(6)
result = color()
if result < 0.05:
break
else:
print 'WHITE'
print "Turning motor on"
GPIO.output(Motor1E,GPIO.HIGH)
GPIO.output(Motor1A,GPIO.LOW)
GPIO.output(Motor1B,GPIO.HIGH)
GPIO.output(Motor2E,GPIO.HIGH)
GPIO.output(Motor2A,GPIO.LOW)
GPIO.output(Motor2B,GPIO.HIGH)
#Measuring flat distance of path
start = time.time()
for i in range(0,1000000):
encoder = GPIO.input(40)
if(encoder==0):
sum0 = sum0 + 1
if(temp != encoder):
temp = encoder
HighLow = HighLow + 0.05
sum00 = sum0
sum0 = 0
#print "zeros", sum00
print HighLow #distance
else :
sum1 = sum1 + 1
if(temp != encoder):
temp = encoder
HighLow = HighLow + 0.05
sum11 = sum1
sum1 = 0
#print "ones", sum11
print HighLow #distance
if( HighLow!= -0.05):
stop = time.time()
timepassed = stop-start
print timepassed
rpm = HighLow/(timepassed/60)
ms = 3.141*0.21*(HighLow/timepassed)
else :
rpm = 0;
f=open('/home/pi/Desktop/Speed.txt','w')
f.write("speed:" + str(int(rpm)) + " rpm ")
f.write( str(round(ms,2)) + " m/s ")
f.close()
print rpm
if ( ( ( int(HighLow%2) == 1) or ( int(HighLow%2) == 0) ) and int(HighLow) > 0 ):
print 'rounds', HighLow
time.sleep(delay)
Science Concepts and Skills¶
The distance travelled by the vehicle is determined by the data collected by the wheel encoder, which is actually measuring the number of revolutions per minute of the rotating wheels.
The total distance travelled by the vehicle can be determined in 2 ways:
Way 1, Tech-based: The distance travelled can be calculated through the code above based on the diameter of the wheel of the encoder. It can also be calculated using the formula:
v = r × v_a × 0.10472
Where:
v is the linear velocity in m/s
r is the radius of anemometer revolving piece
v_a is the angular velocity (circular), in rpm (rotations per minute)
Way 2, Mechanical-based: Students can measure the circumference of the wheel and put a mark on it. They will count the number of rotations of the wheel for a certain distance and multiply it with the circumference. This will give them the total distance travelled. They can also find the circumference of the wheel by using the formula:
D = 2*π*r
Where D is the circumference of the wheel in cm or m
R is the radius of the wheel in cm or m
(The unit of r determines the unit of D. If r in cm, then D is in cm.)
Flex your brain! How can you improve this device by adding safety options that will prevent it from hitting obstacles?