Skip to content

Instantly share code, notes, and snippets.

@maartenpaauw
Created January 28, 2016 20:10
Show Gist options
  • Save maartenpaauw/2c09e282fe7c9e33ff2e to your computer and use it in GitHub Desktop.
Save maartenpaauw/2c09e282fe7c9e33ff2e to your computer and use it in GitHub Desktop.
# Group: YouMedtBro (#25)
# Students: Don, Maarten, Youri, Murtaza, Idriss
# Referenced:
# https://learn.adafruit.com/adafruits-raspberry-pi-lesson-10-stepper-motors/software
import RPi.GPIO as GPIO # Raspberry GPIO
import os # Required for shutdown and reboot functions
import time
from multiprocessing import Process # Required in order to run the animation function async
class Hwctrl:
# Init
def __init__(self):
# Set GPIO mode to BCM (Broadcom pin numbers)
GPIO.setmode(GPIO.BCM)
# Stepper pins
self.coil_A_1_pin = 17
self.coil_A_2_pin = 18
self.coil_B_1_pin = 27
self.coil_B_2_pin = 22
self.switch_pin = 23 # Limit switch
self.sensor_pin = 13 # Light sensor
self.light_pin = 21 # LED Light
# Delay between steps (10ms, 4x 2.5ms 0.0025)
self.delay = 0.0025
# Different settings for R.Pi version A (armv6l)
if "armv6" in os.popen('uname -m').read():
self.coil_B_1_pin = 23 # Different stepper pin
self.switch_pin = 25 # Limit switch
self.sensor_pin = 27 # Light sensor
self.light_pin = 24 # Led light
self.delay = 0.00235 # Sync delay
# GPIO setup
GPIO.setup(self.switch_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(self.sensor_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(self.light_pin, GPIO.OUT)
GPIO.setup(self.coil_A_1_pin, GPIO.OUT)
GPIO.setup(self.coil_A_2_pin, GPIO.OUT)
GPIO.setup(self.coil_B_1_pin, GPIO.OUT)
GPIO.setup(self.coil_B_2_pin, GPIO.OUT)
# Stepper sequence
self.stepSeq = [[0,0,0,1],[0,0,1,0],[0,1,0,0],[1,0,0,0]]
# Group animation pattern
# 0 = Wait (seconds)
# 1 = Move (direction, steps)
# 2 = Flash LED
# 3 = Pause, Wait for light trigger (the R.Pi at position X:0/Y:0 does not wait for this trigger)
# 4 = Trigged halt: same as pause, but happens only once during animation runtime
# 5 = (true/false) Set LED
# Timeline:
self.animation = [ [3],
[1,False,125],
[2],
[1,False,275],
[1,True,400]
]
# Threaded animation
self.animThr = Process(target=self.animatePlay, args=())
self.animationActive = False
# Threaded LEDflash (so the motion doesn't stop when a signal is given)
self.flashThr = Process(target=self.flashLed, args=())
# Load X and Y position from disk
fh = open('/boot/x.txt', 'r')
self.xpos = int(fh.read())
fh.close()
fh = open('/boot/y.txt', 'r')
self.ypos = int(fh.read())
fh.close()
# Move the stepper motor
def move(self,direction,steps,override):
if not self.animationActive or override: # Check if the animation is currently running, if yes: abort (moves made by the animation itself may override this check)
for i in range(steps):
# Check if limit switch has been activated
if not self.checkSwitch() or not direction:
self.step(direction) # One turn
# Upper limit reached: stop motion
else:
self.setStep(0, 0, 0, 0) # Power down
break
self.setStep(0, 0, 0, 0) # Power down
return True
else:
return False
# One turn
def step(self,direction):
# One turn up
if direction:
for i in range(4):
self.setStep(self.stepSeq[i][0], self.stepSeq[i][1], self.stepSeq[i][2], self.stepSeq[i][3])
time.sleep(self.delay)
# One turn down
else:
for i in range(3,-1,-1):
self.setStep(self.stepSeq[i][0], self.stepSeq[i][1], self.stepSeq[i][2], self.stepSeq[i][3])
time.sleep(self.delay)
# Return home
def moveHome(self):
return self.move(True, 10000, False)
# Control stepper motor coils
def setStep(self,w1,w2,w3,w4):
GPIO.output(self.coil_A_1_pin, w1)
GPIO.output(self.coil_A_2_pin, w2)
GPIO.output(self.coil_B_1_pin, w3)
GPIO.output(self.coil_B_2_pin, w4)
# Start animation
def animateStart(self):
if not self.animationActive:
self.moveHome()
self.move(False,100,False) # Drop ball by 100 steps before the animation runs
self.animationActive = True
self.animThr = Process(target=self.animatePlay, args=())
self.animThr.start()
return True
else:
return False
# Stop animation
def animateStop(self):
if self.animationActive:
if self.animThr.is_alive():
self.animThr.terminate()
self.animationActive = False
self.toggleLight(False)
self.moveHome()
return True
else:
return False
# Play animation
def animatePlay(self):
trigged = False
while self.animationActive:
for a in self.animation:
# Wait
if a[0] == 0:
time.sleep(a[1])
# Move
elif a[0] == 1:
self.move(a[1],a[2],True)
# Flash LED
elif a[0] == 2:
self.flashThr = Process(target=self.flashLed, args=())
if not self.flashThr.is_alive():
self.flashThr.start()
# Pause, Wait for light trigger
elif a[0] == 3:
while (self.checkSensor() == False):
time.sleep(.02)
# Trigged pause, Wait a single light trigger, ignore for the rest of the animation
elif a[0] == 4:
if not trigged:
while (self.checkSensor() == False):
time.sleep(.02)
trigged = True
# Pause, Wait for light trigger
elif a[0] == 5:
self.toggleLight(a[1])
# Flash the LED
def flashLed(self):
self.toggleLight(True)
time.sleep(.5)
self.toggleLight(False)
return
# Shutdown R.Pi
def shutdown(self):
if self.animationActive: # Animation is running, cancel action
return False
else:
if os.system("/sbin/shutdown -h now") is not None:
return True # Command successful
else:
return False # Command failed
# Reboot R.Pi
def reboot(self):
if self.animationActive: # Animation is running, cancel action
return False
else:
if os.system("/sbin/shutdown -r now") is not None:
return True # Command successful
else:
return False # Command failed
# Return X-postion
def getXpos(self):
return self.xpos
# Return Y-postion
def getYpos(self):
return self.ypos
# Check the switch status
def checkSwitch(self):
if GPIO.input(self.switch_pin) == 0:
return True
else:
return False
# Check the light sensor status (always true for the first Pi in the row)
def checkSensor(self):
if self.firstPi():
return True
elif GPIO.input(self.sensor_pin) == 0:
return True
else:
return False
# First Raspberry on the block (position 0,0)
def firstPi(self):
if self.xpos == 0 and self.ypos == 0:
return True
else:
return False
# Return if the animation is active or not
def getAnimationActive(self):
return self.animationActive
# Control the LED light
def toggleLight(self,onoff):
GPIO.output(self.light_pin,onoff)
# Cleanup GPIO
def cleanShutdown(self):
print "## Shutting down..."
GPIO.cleanup()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment