Skip to content

Instantly share code, notes, and snippets.

@Lord-McSweeney
Created March 22, 2024 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lord-McSweeney/2f7c42823ec0757d2b4ca136b4740ead to your computer and use it in GitHub Desktop.
Save Lord-McSweeney/2f7c42823ec0757d2b4ca136b4740ead to your computer and use it in GitHub Desktop.
# CamJam EduKit 3 - Robotics
# Worksheet 8 - Line Following Robot
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
pinMotorAForwards = 10
pinMotorABackwards = 9
pinMotorBForwards = 8
pinMotorBBackwards = 7
# Set variables for the line detector GPIO pin
pinLineFollower = 25
# How many times to turn the pin on and off each second
Frequency = 20
# How long the pin stays on each cycle, as a percent (here, it's 30%)
DutyCycleA = 30
DutyCycleB = 30
# Setting the duty cycle to 0 means the motors will not turn
Stop = 0
GPIO.setup(pinMotorAForwards, GPIO.OUT)
GPIO.setup(pinMotorABackwards, GPIO.OUT)
GPIO.setup(pinMotorBForwards, GPIO.OUT)
GPIO.setup(pinMotorBBackwards, GPIO.OUT)
GPIO.setup(pinLineFollower, GPIO.IN)
pwmMotorAForwards = GPIO.PWM(pinMotorAForwards, Frequency)
pwmMotorABackwards = GPIO.PWM(pinMotorABackwards, Frequency)
pwmMotorBForwards = GPIO.PWM(pinMotorBForwards, Frequency)
pwmMotorBBackwards = GPIO.PWM(pinMotorBBackwards, Frequency)
# Start the software PWM with a duty cycle of 0
pwmMotorAForwards.start(Stop)
pwmMotorABackwards.start(Stop)
pwmMotorBForwards.start(Stop)
pwmMotorBBackwards.start(Stop)
def StopMotors():
pwmMotorAForwards.ChangeDutyCycle(Stop)
pwmMotorABackwards.ChangeDutyCycle(Stop)
pwmMotorBForwards.ChangeDutyCycle(Stop)
pwmMotorBBackwards.ChangeDutyCycle(Stop)
def Forwards():
pwmMotorAForwards.ChangeDutyCycle(DutyCycleA)
pwmMotorABackwards.ChangeDutyCycle(Stop)
pwmMotorBForwards.ChangeDutyCycle(DutyCycleB)
pwmMotorBBackwards.ChangeDutyCycle(Stop)
def Backwards():
pwmMotorAForwards.ChangeDutyCycle(Stop)
pwmMotorABackwards.ChangeDutyCycle(DutyCycleA)
pwmMotorBForwards.ChangeDutyCycle(Stop)
pwmMotorBBackwards.ChangeDutyCycle(DutyCycleB)
def Right():
pwmMotorAForwards.ChangeDutyCycle(Stop)
pwmMotorABackwards.ChangeDutyCycle(DutyCycleA)
pwmMotorBForwards.ChangeDutyCycle(DutyCycleB)
pwmMotorBBackwards.ChangeDutyCycle(Stop)
def Left():
pwmMotorAForwards.ChangeDutyCycle(DutyCycleA)
pwmMotorABackwards.ChangeDutyCycle(Stop)
pwmMotorBForwards.ChangeDutyCycle(Stop)
pwmMotorBBackwards.ChangeDutyCycle(DutyCycleB)
def IsOverBlack():
if GPIO.input(pinLineFollower) == 0:
return True
else:
return False
# Search for the black line
def SeekLine():
print("Seeking the line")
# The direction the robot will turn = True = Left
Direction = True
SeekSize = 0.25 # Turn for 0.25s
SeekCount = 1 # A count of times the robot has looked for the line
MaxSeekCount = 5 # The maximum time to seek th eline in one direction
# Turn the robot left and right until it finds the line
# Or it has been searched for long enough
while SeekCount <= MaxSeekCount:
# Set the seek time
SeekTime = SeekSize * SeekCount
# Start the motors turning in a direction
if Direction:
print("Looking left")
Left()
else:
print("Looking Right")
Right()
# Save the time it is now
StartTime = time.time()
# While the robot is turning for SeekTime seconds,
# check to see whether the line detector is over black
while time.time()-StartTime <= SeekTime:
if IsOverBlack():
StopMotors()
# Exit the SeekLine() function returning
# True = the line was found
return True
# The robot has not found the black line yet, so stop
StopMotors()
# Increase the seek count
SeekCount += 1
# Change direction
Direction = not Direction
# The line wasn't found, so return False
return False
try:
#repeat the next indented block forever
print("Following the line")
while True:
# If the sensor is low (=0), it's above the black line
if IsOverBlack():
Forwards()
# If not (else), print the following
else:
StopMotors()
if SeekLine() == False:
StopMotors()
print("The robot has lost the line")
else:
print("Following the line")
# If you press CTRL+C, cleanup and stop
except KeyboardInterrupt:
GPIO.cleanup()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment