From Control Systems Technology Group
Import required packages
#!/usr/bin/python
from pyzbar.pyzbar import decode # QR reader
from PIL import Image # Image reader
import cv2 # Image reader
import RPi.GPIO as GPIO # GPIO pin control
import time # Posibility to delay
import signal # Cleanup when ending script
import sys # Needed to stop script if no camera
Set up constants
pin_s1 = 29 # Continuous servo 1
pin_s2 = 33 # Continuous servo 2
freq = 50 # Continuous servo frequency [Hz]
s1left = 5.00 # 100% velocity to left
s1center = 6.70 # no movement
s1right = 8.00 # 100% velocity to right
s2left = 5.00 # 100% velocity to left
s2center = 6.60 # no movement
s2right = 8.00 # 100% velocity to right
cyldelay = 2 # Time it takes for cylinder to rotate
dropdelay = 5 # Time it takes to drop package
pauzedelay = 2 # Time between cylinder rotation and platform movement
platformdelay = 2 # Time it takes for platform to move down
imgname = "image2.jpg" # File frame is temporarily saved in
# Imports allowed QRcodes
passcodelist = []
with open("authcodes") as file:
passcodelist = [line.strip() for line in file]
Stops the script safely if CTRL+C is pressed
# Releases pins when script is interrupted
def end_run(signal,frame):
global running
print("Ctrl+C captured, ending script")
running = False
servo1.stop()
servo2.stop()
GPIO.cleanup()
# Runs end_run if ctrl+C is clicked
signal.signal(signal.SIGINT, end_run)
Takes a picture with the camera
# Takes picture from camera, reads and evaluates QRcode
def QRscanner(passcodelist, camslot):
camera = cv2.VideoCapture(camslot) # Initializes camera viewer
grabbed, im = camera.read() # Reads figure
Checks if a picture is taken, and if it is not, it looks for other cameras or stops the script
if not grabbed: # Searches for working camera
if camslot < 5:
camstr = "No camera connected in slot: " + str(camslot)
print(camstr)
camslot = camslot + 1
return False, camslot
else:
print("No camera connected")
servo1.stop()
servo2.stop()
GPIO.cleanup()
sys.exit()
Reads QR-codes in the image and checks if a correct code is presented
cv2.imwrite(imgname,im) # Converts image to jpg
img = Image.open(imgname) # Reads jpg
decodedObjects = decode(img) # Decodes image
for obj in decodedObjects: # Makes sure every code is read
qrdata = obj.data # Reads the alphanumerical code
for passcode in passcodelist:
if passcode in qrdata: # Verifies if code is legit
print("Correct code, cylinders start opening")
return True, camslot
else:
print("Wrong code")
return False, camslot
Sets up the output pins that control the servos
GPIO.setmode(GPIO.BOARD) # Board numbering sceme pins
GPIO.setup(pin_s1, GPIO.OUT) # Sets pins as output
GPIO.setup(pin_s2, GPIO.OUT)
servo1 = GPIO.PWM(pin_s1, freq) # Assigns frequency to pins
servo2 = GPIO.PWM(pin_s2, freq)
servo1.start(s1center) # Starts servos in neutral position
servo2.start(s2center)
Sets up variables, starts the script, and runs the QR-code reader until correct code is presented or CTRL+C is pressed
camslot = 0 # Default camera slot
running = True
print("Program Running, provide QR-code")
while running:
rightcode, camslot = QRscanner(passcodelist, camslot) # Runs QR-reader
Makes Cylinders and platform move if the correct code is presented
if rightcode:
servo1.ChangeDutyCycle(s1left) # Cylinders open
time.sleep(cyldelay) # Duration of cylinder movement
servo1.ChangeDutyCycle(s1center) # Cylinders stop moving
print("Cylinders are open, package can be dropped")
time.sleep(dropdelay) # Duration of package dropping
print("Package dropped, cylinders start closing")
servo1.ChangeDutyCycle(s1right) # Cylinders close
time.sleep(cyldelay) # Duration of cylinder movement
servo1.ChangeDutyCycle(s1center) # Cylinders stop moving
print("Cylinders are closed")
time.sleep(pauzedelay) # Time buffer
print("Platform starts moving down")
servo2.ChangeDutyCycle(s2left) # Platform moves down
time.sleep(platformdelay) # Duration of platform movement
servo2.ChangeDutyCycle(s2center) # Platform stops moving
print("Platform stopped moving down, new code can be scanned")