ZacharyIgielman
Posts: 101
Joined: Sun Dec 08, 2013 11:27 am
Location: London

HOW TO: Raspberry Pi Line Follower

Mon Jan 20, 2014 6:18 pm

I have built a robot. It follows a black line on a white piece of paper. It sends a live stream of what a pi camera on the robot is seeing to the local network. It sill also stop should an object come within 30cm of it's path. Feel free to make one yourself. Here's how I did it:

Parts:

Raspberry Pi
Polulu zumo robot chassis
2x Micro metal gear-motors
4x AA batteries
5v USB battery pack mobile phone charger
330ohm resistor
470ohm resistor
HR-SC04 sonar module
2x Digital line detectors
Ryanteck's MCB
Varied jumper wires
SD card
Keyboard
USB wifi dongle
Micro USB cable

Estimated bill of materials: £60 (incl. Raspberry Pi) (excl. Screen, internet connection, local wireless network and laptop to program pi and watch video stream)

Wiring and circuit:

http://t.co/pEyHpc0E0x

Code:

Code: Select all

#run these commands before this file to start stream:
#mkdir /tmp/stream 2>/dev/null
#nohup raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 500 -th 0:0:0 -t 9999999 &
#LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i "input_file.so -f /tmp/stream -n pic.jpg" -o "output_http.so -w /usr/local/www" &

#import necessary modules
import RPi.GPIO as GPIO, sys, threading, time

#use physical pin numbering
GPIO.setmode(GPIO.BOARD)

#set up digital line detectors as inputs
GPIO.setup(3, GPIO.IN)
GPIO.setup(22, GPIO.IN)

#set up motor control pins for RTK-000-001
#use pwm on inputs so motors don't go too fast
GPIO.setup(11, GPIO.OUT)
p=GPIO.PWM(11, 20)
GPIO.setup(15, GPIO.OUT)
q=GPIO.PWM(15, 20)
GPIO.setup(12, GPIO.OUT)
a=GPIO.PWM(12,20)
GPIO.setup(16, GPIO.OUT)
b=GPIO.PWM(16,20)
#turn off motors
GPIO.output(11, 0)
GPIO.output(15, 0)
GPIO.output(16, 0)
GPIO.output(12, 0)

# Allow module to settle
time.sleep(0.5)

# Define GPIO to use on Pi for sonar
GPIO_TRIGGER = 7
GPIO_ECHO = 8
# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)     # Echo
# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

# Allow module to settle
time.sleep(0.5)

#make a global variable to communcate between sonar functiona and main loop
globalstop=0

def sonar():
       while True:
                  global globalstop
                  global GPIO_TRIGGER
                  global GPIO_ECHO
                  # Send 10us pulse to trigger
                  GPIO.output(GPIO_TRIGGER, True)
                  time.sleep(0.00001)
                  GPIO.output(GPIO_TRIGGER, False)
                  start = time.time()
                  count=time.time()
                  while GPIO.input(GPIO_ECHO)==0 and time.time()-count<0.1:
                          start = time.time()
                  stop=time.time()
                  while GPIO.input(GPIO_ECHO)==1:
                          stop = time.time()
                  # Calculate pulse length
                  elapsed = stop-start
                  # Distance pulse travelled in that time is time
                  # multiplied by the speed of sound (cm/s)
                  distance = elapsed * 34000
                  # That was the distance there and back so halve the value
                  distance = distance / 2
                  if distance<20:
                          globalstop=1
                          print("Too close")
                  else:
                          globalstop=0
                          print("Far")
                  time.sleep(1)

threading.Timer(1, sonar).start()

try:
       while True:
                  if GPIO.input(3)==1 and GPIO.input(22)==1 or globalstop==1:
                          b.stop()
                          GPIO.output(16,0)
                          a.stop()
                          GPIO.output(12,0)
                          p.stop()
                          q.stop()
                          GPIO.output(11,0)
                          GPIO.output(15,0)
                          print('stop')
                  elif GPIO.input(3)==0 and GPIO.input(22)==0:
                          p.start(60)
                          a.stop()
                          GPIO.output(12, 0)
                          q.start(60)
                          b.stop()
                          GPIO.output(16, 0)
                          print('straight')
                  elif GPIO.input(3)==1:
                          q.start(100)
                          p.stop()
                          GPIO.output(11,0)
                          b.stop()
                          GPIO.output(16,0)
                          a.start(100)
                          print('right')
                  elif GPIO.input(22)==1:
                          q.stop()
                          GPIO.output(15,0)
                          p.start(100)
                          a.stop()
                          GPIO.output(12,0)
                          b.start(100)
                          print('left')
except KeyboardInterrupt:
       GPIO.cleanup()
       sys.exit()
How to do a live stream:

I used the instructions on recantha’s and Miguel Grinberg’s blogs to do a live stream.
It uses mjpg_streamer to stream stills from the camera. You basically set up your camera to write single pictures to /tmp in timelapse mode and then mjpg_streamer pseudo-streams from the single image file.

Firstly, set up mjpg_streamer: http://blog.miguelgrinberg.com/post/how ... spberry-pi

Commands to start the stream:

Code: Select all

mkdir /tmp/stream 2>/dev/null
nohup raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 500 -th 0:0:0 -t 9999999 &
LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i "input_file.so -f /tmp/stream -n pic.jpg" -o "output_http.so -w /usr/local/www" &

The first one creates a folder in your temporary storage to store the photo for the stream.
The second one uses raspistill’s time-lapse command to take photos 500 milliseconds apart for 9999999 milliseconds and writes them to the same file (/tmp/stream/pic.jpg) which means every photo overwrites the last. So the photo at /tmp/stream/pic.jpg will always be a photo taken less than half a second ago. The ‘&’ symbol means it runs in the background so we can run the next commands and do other things while it’s running.
The third one starts the mjpeg-streamer streaming the /tmp/stream/pic.jpg file.
After you run these commands (you must’ve installed it before you run them: http://blog.miguelgrinberg.com/post/how ... spberry-pi), you can connect with your web browser and watch the stream live. If you want to watch from within the same Raspberry Pi you can enter http://localhost:8080 in the browser's address bar. If you want to watch from another computer in your network use http://<IP-address>:8080.

Photos:

http://t.co/b8scMKsgqV
http://t.co/Q66n8u9kiE

Video:

http://youtu.be/ZY3PNiD7Z-A

If you need any more information or assistance, please do not hesitate to contact me. Send me a private message, commend on this forum or email me ([email protected] or [email protected]).
Don't be mean, I'm only fifteen :D

chetuk
Posts: 49
Joined: Mon Feb 20, 2017 7:27 am

Re: HOW TO: Raspberry Pi Line Follower

Mon Jul 16, 2018 2:46 am

Getting error also not working used same code and same pins.
only i have replaced Ryanteck's MCB with L298N motor diver.

DirkS
Posts: 9524
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex, UK

Re: HOW TO: Raspberry Pi Line Follower

Mon Jul 16, 2018 9:19 am

chetuk wrote:
Mon Jul 16, 2018 2:46 am
Getting error also not working used same code and same pins.
only i have replaced Ryanteck's MCB with L298N motor diver.
If you expect a meaningful response you have to give a lot more info.
Starting with the full error message, changes you made to the original (in detail) etc.
And because that tutorial is several years old that should include versions of various software...

chetuk
Posts: 49
Joined: Mon Feb 20, 2017 7:27 am

Re: HOW TO: Raspberry Pi Line Follower

Sat Dec 01, 2018 1:24 pm

Fixed when change the pyhton to python3

sudo python3 file.py

Return to “Automation, sensing and robotics”