PRE2017 3 11 Python Code

From Control Systems Technology Group
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()