commit 4ba3a056815e7bd402d25558f1eb21a146402a64 Author: James Gao Date: Wed Oct 15 04:37:45 2014 -0700 Implement the stepper-controlled regulator function diff --git a/server.py b/server.py new file mode 100644 index 0000000..e69de29 diff --git a/stepper.py b/stepper.py new file mode 100644 index 0000000..99fa1b1 --- /dev/null +++ b/stepper.py @@ -0,0 +1,141 @@ +import time +import atexit +import threading +import Queue + +from RPi import GPIO + +class Stepper(threading.Thread): + #half-steppipng pattern, also possible to skip every other for full-stepping + pattern = [ + [1,0,0,0], + [1,0,1,0], + [0,0,1,0], + [0,1,1,0], + [0,1,0,0], + [0,1,0,1], + [0,0,0,1], + [1,0,0,1]] + + def __init__(self, pin1=5, pin2=6, pin3=13, pin4=19, timeout=2): + self.queue = Queue.Queue() + self.finished = threading.Event() + + self.pins = [pin1, pin2, pin3, pin4] + GPIO.setup(pin1, GPIO.OUT) + GPIO.setup(pin2, GPIO.OUT) + GPIO.setup(pin3, GPIO.OUT) + GPIO.setup(pin4, GPIO.OUT) + + self.phase = 0 + self.timeout = timeout + + def stop(self): + self.queue.put((None, None)) + + def step(self, num, speed=10, block=False): + """Step the stepper motor + + Parameters + ---------- + num : int + Number of steps + speed : int + Number of steps per second + block : bool + Block while stepping? + """ + self.finished.clear() + self.queue.put((num, speed)) + if block: + self.finished.wait() + + def run(self): + step, speed = self.queue.get() + while step is not None: + for pin, out in zip(self.pins, self.pattern[self.phase]): + GPIO.output(pin, out) + + self._step(step, speed) + self.finished.set() + + try: + step, speed = self.queue.get(True, self.timeout) + except Queue.Empty: + #handle the timeout, turn off all pins + for pin in self.pins: + GPIO.output(pin, False) + step, speed = self.queue.get() + + for pin in self.pins: + GPIO.output(pin, False) + + def _step(self, step, speed): + steps = range(step) + if step < 0: + steps = range(step, 0)[::-1] + + for i in steps: + now = time.time() + output = self.pattern[(self.phase+i)%len(self.pattern)] + for pin, out in zip(self.pins, output): + GPIO.output(pin, out) + + diff = 1. / (2*speed) - (time.time() - now) + if (diff) > 0: + time.sleep(diff) + + self.phase += step + + +class Regulator(object): + def __init__(self, maxsteps=3072, minsteps=1024, speed=10, ignite_pin=26): + """Set up a stepper-controlled regulator. Implement some safety measures + to make sure everything gets shut off at the end + + Parameters + ---------- + maxsteps : int + The max value for the regulator, in steps + minsteps : int + The minimum position to avoid extinguishing the flame + speed : int + Speed to turn the stepper, in steps per second + ignite_pin : int or None + If not None, turn on this pin during the ignite sequence + """ + self.stepper = Stepper() + self.stepper.start() + self.current = 0 + self.max = maxsteps + self.min = minsteps + self.speed = speed + self.lowthres = lowthres + + self.ignite_pin = ignite_pin + if ignite_pin is not None: + GPIO.setup(ignite_pin, OUT) + + atexit.register(self.off) + + def ignite(self, start=2048, delay=5): + self.stepper.step(start, self.speed, block=True) + if self.ignite_pin is not None: + GPIO.output(self.ignite_pin, True) + time.sleep(delay) + if self.ignite_pin is not None: + GPIO.output(self.ignite_pin, False) + self.stepper.step(start - self.min, self.speed) + self.current = start-stop + + def off(self, block=True): + self.stepper.step(-self.current, self.speed, block=block) + self.current = 0 + + def set(self, value, block=True): + if not 0 < value < 1: + raise ValueError("Must give fraction between 0 and 1") + target = value * (self.max - self.min) + self.min + nsteps = target - self.current + self.current = target + self.stepper.step(nsteps, self.speed, block=block)