PRE2017 3 11 Python Code
Jump to navigation
Jump to search
QR scanner with cylinder and platform response
The main script scans QR codes in front of the camera, opens the cylinder and moves the platform down if a correct code is presented.
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 access codes
# 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
Opens/closes the cylinder and moves down the platform
if rightcode: servo1.ChangeDutyCycle(s1right) # 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(s1left) # 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(s2right) # 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")
Calibrator
In order to make sure that the servos rotated exactly long enough, a python script was written which starts and stops the servos on the press of a button:
import RPi.GPIO as GPIO # GPIO pin control import signal # Cleanup when ending script # 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) 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 GPIO.setmode(GPIO.BOARD) GPIO.setup(pin_s1,GPIO.OUT) GPIO.setup(pin_s2,GPIO.OUT) servo1 = GPIO.PWM(pin_s1,freq) servo2 = GPIO.PWM(pin_s2,freq) servo1.start(s1center) # Starts servos in neutral position servo2.start(s2center) running = True print("1(l,c,r), 2(l,c,r): ") while running: n = raw_input() if n == "1l": servo1.ChangeDutyCycle(s1left) elif n == "1c": servo1.ChangeDutyCycle(s1center) elif n == "1r": servo1.ChangeDutyCycle(s1right) elif n == "2l": servo2.ChangeDutyCycle(s2left) elif n == "2c": servo2.ChangeDutyCycle(s2center) elif n == "2r": servo2.ChangeDutyCycle(s2right)
Platform Resetter
After the storage box is emptied, the platform has to move back up, which is done with the following python code:
import RPi.GPIO as GPIO # GPIO pin control import time import signal # Cleanup when ending script # Releases pins when script is interrupted def end_run(signal,frame): print("Ctrl+C captured, ending script") servo2.stop() GPIO.cleanup() # Runs end_run if ctrl+C is clicked signal.signal(signal.SIGINT, end_run) pin_s2 = 33 # Continuous servo 2 freq = 50 # Continuous servo frequency [Hz] s2left = 5.00 # 100% velocity to left platformdelay = 4.25 # Time it takes for platform to move down GPIO.setmode(GPIO.BOARD) GPIO.setup(pin_s2, GPIO.OUT) servo2 = GPIO.PWM(pin_s2, freq) servo2.start(s2left) time.sleep(platformdelay) servo2.stop() GPIO.cleanup()
Cylinder Resetter
If any failures occur when the cylinder is opened, this script can be activated to close the cylinder:
import RPi.GPIO as GPIO # GPIO pin control import time # Posibility to delay import signal # Cleanup when ending script pin_s1 = 29 # Continuous servo 1 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 cyldelay = 1.35 # Time it takes for cylinder to rotate # 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) GPIO.setmode(GPIO.BOARD) # Board numbering sceme pins GPIO.setup(pin_s1, GPIO.OUT) # Sets pins as output servo1 = GPIO.PWM(pin_s1, freq) # Assigns frequency to pins servo1.start(s1left) # Starts servos in neutral position time.sleep(cyldelay) servo1.stop() GPIO.cleanup()