PRE2017 3 11 Python Code
From Control Systems Technology Group
(Difference between revisions)
(15 intermediate revisions not shown) | |||
Line 1: | Line 1: | ||
+ | __NOTOC__ | ||
+ | ==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=== | ||
+ | <pre> | ||
#!/usr/bin/python | #!/usr/bin/python | ||
- | from pyzbar.pyzbar import decode | + | from pyzbar.pyzbar import decode # QR reader |
+ | from PIL import Image # Image reader | ||
import cv2 # Image reader | import cv2 # Image reader | ||
- | + | import RPi.GPIO as GPIO # GPIO pin control | |
- | import RPi.GPIO as GPIO | + | |
import time # Posibility to delay | import time # Posibility to delay | ||
import signal # Cleanup when ending script | import signal # Cleanup when ending script | ||
+ | import sys # Needed to stop script if no camera | ||
+ | </pre> | ||
- | + | ===Set up constants=== | |
- | + | ||
- | + | <pre> | |
+ | 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 | ||
+ | </pre> | ||
+ | ===Imports access codes=== | ||
+ | <pre> | ||
+ | # Imports allowed QRcodes | ||
+ | passcodelist = [] | ||
+ | with open("authcodes") as file: | ||
+ | passcodelist = [line.strip() for line in file] | ||
+ | </pre> | ||
+ | |||
+ | ===Stops the script safely if CTRL+C is pressed=== | ||
+ | <pre> | ||
# Releases pins when script is interrupted | # Releases pins when script is interrupted | ||
def end_run(signal,frame): | def end_run(signal,frame): | ||
global running | global running | ||
- | print "Ctrl+C captured, ending script" | + | print("Ctrl+C captured, ending script") |
running = False | running = False | ||
servo1.stop() | servo1.stop() | ||
Line 23: | Line 58: | ||
# Runs end_run if ctrl+C is clicked | # Runs end_run if ctrl+C is clicked | ||
signal.signal(signal.SIGINT, end_run) | signal.signal(signal.SIGINT, end_run) | ||
+ | </pre> | ||
+ | ===Takes a picture with the camera=== | ||
+ | |||
+ | <pre> | ||
# Takes picture from camera, reads and evaluates QRcode | # Takes picture from camera, reads and evaluates QRcode | ||
- | def QRscanner( | + | def QRscanner(passcodelist, camslot): |
- | + | camera = cv2.VideoCapture(camslot) # Initializes camera viewer | |
- | + | grabbed, im = camera.read() # Reads figure | |
- | + | </pre> | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ===Checks if a picture is taken, and if it is not, it looks for other cameras or stops the script=== | |
- | + | <pre> | |
- | + | 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() | ||
+ | </pre> | ||
- | + | ===Reads QR-codes in the image and checks if a correct code is presented=== | |
- | + | <pre> | |
- | + | 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 | ||
+ | </pre> | ||
- | + | ===Sets up the output pins that control the servos=== | |
- | + | ||
- | + | ||
- | + | <pre> | |
- | + | 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) | ||
+ | </pre> | ||
- | + | ===Sets up variables, starts the script, and runs the QR-code reader until correct code is presented or CTRL+C is pressed=== | |
- | + | ||
- | + | ||
- | + | <pre> | |
- | + | camslot = 0 # Default camera slot | |
- | + | running = True | |
- | + | print("Program Running, provide QR-code") | |
- | + | ||
- | + | ||
while running: | while running: | ||
- | + | rightcode, camslot = QRscanner(passcodelist, camslot) # Runs QR-reader | |
- | rightcode = QRscanner( | + | </pre> |
+ | |||
+ | ===Opens/closes the cylinder and moves down the platform=== | ||
+ | |||
+ | <pre> | ||
if rightcode: | if rightcode: | ||
- | + | servo1.ChangeDutyCycle(s1right) # Cylinders open | |
- | + | ||
time.sleep(cyldelay) # Duration of cylinder movement | time.sleep(cyldelay) # Duration of cylinder movement | ||
servo1.ChangeDutyCycle(s1center) # Cylinders stop moving | servo1.ChangeDutyCycle(s1center) # Cylinders stop moving | ||
- | print "Cylinders are open, package can be dropped" | + | print("Cylinders are open, package can be dropped") |
time.sleep(dropdelay) # Duration of package dropping | time.sleep(dropdelay) # Duration of package dropping | ||
- | print " | + | print("Package dropped, cylinders start closing") |
- | servo1.ChangeDutyCycle( | + | servo1.ChangeDutyCycle(s1left) # Cylinders close |
time.sleep(cyldelay) # Duration of cylinder movement | time.sleep(cyldelay) # Duration of cylinder movement | ||
servo1.ChangeDutyCycle(s1center) # Cylinders stop moving | servo1.ChangeDutyCycle(s1center) # Cylinders stop moving | ||
- | print "Cylinders are closed | + | print("Cylinders are closed") |
- | servo2.ChangeDutyCycle( | + | time.sleep(pauzedelay) # Time buffer |
+ | print("Platform starts moving down") | ||
+ | servo2.ChangeDutyCycle(s2right) # Platform moves down | ||
time.sleep(platformdelay) # Duration of platform movement | time.sleep(platformdelay) # Duration of platform movement | ||
servo2.ChangeDutyCycle(s2center) # Platform stops moving | servo2.ChangeDutyCycle(s2center) # Platform stops moving | ||
- | print "Platform stopped moving down, new code can be scanned" | + | print("Platform stopped moving down, new code can be scanned") |
+ | </pre> | ||
+ | |||
+ | ==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: | ||
+ | |||
+ | <pre> | ||
+ | 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) | ||
+ | </pre> | ||
+ | |||
+ | ==Platform Resetter== | ||
+ | After the storage box is emptied, the platform has to move back up, which is done with the following python code: | ||
+ | |||
+ | <pre> | ||
+ | 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() | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | ==Cylinder Resetter== | ||
+ | If any failures occur when the cylinder is opened, this script can be activated to close the cylinder: | ||
+ | |||
+ | <pre> | ||
+ | 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() | ||
+ | |||
+ | </pre> |
Current revision as of 12:37, 2 April 2018
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()