class Bell: def __init__(self, port_bell_1, port_bell_2): self.__bell_1 = DigitalOutputDevice(port_bell_1) self.__bell_2 = DigitalOutputDevice(port_bell_2) self.turn_the_other_direction = True self.is_ringing = False def __chime(self, duration): if self.turn_the_other_direction: self.__bell_1.on() self.__bell_2.off() else: self.__bell_1.off() self.__bell_2.on() self.turn_the_other_direction = not self.turn_the_other_direction sleep(duration / 1000.0) def ring_the_bell(self, speed=100, count=-1): current_count = 0 self.is_ringing = True while self.is_ringing: if count > -1: current_count += 1 if current_count > count: break self.__chime(speed) def stop_ringing(self, ): self.is_ringing = False
class DigitalPiDevice: """ Digital modulated devices in combination with Raspberry Pi GPIO Setup: https://gpiozero.readthedocs.io/en/stable/remote_gpio.html """ def __init__(self, PIN, BOARD_IP: str = None): """ :param BOARD_IP: IP adress of board connected to the Device """ if BOARD_IP is not None: self._factory = PiGPIOFactory(host=BOARD_IP) self._device = DigitalOutputDevice(PIN, pin_factory=self._factory) else: self._factory = None self._device = DigitalOutputDevice(PIN) self._running = False def turn_on(self): self._device.on() self._running = True def turn_off(self): self._device.off() self._running = False def toggle(self): self._device.toggle() self._running = self._device.is_active
class Motor: """Klasse for å kontrollere en motor""" def __init__(self, forward, backward, pwm): // Disse er inn signalene til h-blokken self.forward = DigitalOutputDevice(forward) self.backward = DigitalOutputDevice(backward) self.pwm = PWMOutputDevice(pwm, True, 0, 1000) def speed(self, speed): """Justerer hastigheten og rettningen til motoren""" self.direction(speed) self.pwm.value = norm(speed) def direction(self, speed): """Bestemmer rettningen basert på hastigheten""" if speed > 0: self.forward.on() self.backward.off() else: self.forward.off() self.backward.on() def close(self): """Frigjør og rydder opp""" self.forward.close() self.backward.close() self.pwm.close()
def main(): DRYNESS_THRESHOLD = load_config() i2c = busio.I2C(board.SCL, board.SDA) ads = ADS.ADS1115(i2c) led = LED(LIGHT_PIN, active_high=False) fans = DigitalOutputDevice(FANS_PIN, active_high=False) pumps = DigitalOutputDevice(PUMP_PIN, active_high=False) sensor = AnalogIn(ads, ADS.P0) while (True): os.system('clear') now = datetime.datetime.now().time() if (time_in_range(startTime, endTime, now)): led.on() fans.on() # Read from sensor if (sensor.value > DRYNESS_THRESHOLD): pumps.on() print("Pump turned on!") else: pumps.off() print("Pump turned off!") print("LED turned on!") elif not (time_in_range(startTime, endTime, now)): led.off() fans.off() print("LED turned off!") print("Time Now: " + str(now)) print("Start Time: " + str(startTime)) print("End Time: " + str(endTime)) print("Sensor: " + str(sensor.value)) print("Threshold: " + str(DRYNESS_THRESHOLD)) time.sleep(10)
class RPi: PIN_NODE_RST = 27 PIN_START_BTN = 23 PIN_EXIT_EN = 24 def __init__(self, onStart=None, onStop=None): if not RPI_OK: return self.rstPin = DigitalOutputDevice(self.PIN_NODE_RST) #self.btnPin = DigitalInputDevice(self.PIN_START_BTN) self.btnPin = Button(self.PIN_START_BTN) self.exitPin = DigitalOutputDevice(self.PIN_EXIT_EN, active_high=True) #self.outPin.source = self.btnPin.values if onStart: self.btnPin.when_pressed = onStart if onStop: self.btnPin.when_released = onStop return def resetNetwork(self): if not RPI_OK: return self.rstPin.blink(n=1, on_time=0.1, off_time=0.1, background=True) return def openDoors(self, on): if not RPI_OK: return if on: self.exitPin.on() else: self.exitPin.off() return def gameEnabled(self): if not RPI_OK: return False return self.btnPin.is_active
class ICAHSensor: ping_dur = 0.00015 # s, same as measured for gpiozero speed_of_sound = 343 # m/s at 101325 Pa, 293 K def __init__(self, trig, echo): self.trig = DigitalOutputDevice(trig) self.echo = DigitalInputDevice(echo) self.hist = [] def get_distance(self): ''' This could be made non-blocking by using a background thread that continually updates the current distance. We should also reject outliers in the distance measurements using the filter() function or similar. ''' del (self.hist[:]) for i in range(10): self.trig.on() sleep(self.ping_dur) self.trig.off() self.echo.wait_for_active() t0 = time() self.echo.wait_for_inactive() dt = time() - t0 dist = dt * ICAHSensor.speed_of_sound / 2 self.hist.append(dist) return sum(self.hist) / len(self.hist)
def turn_on_the_light(duration, actor): logging.info('New light request by {} for {} seconds'.format( actor, duration)) relay = DigitalOutputDevice(17) relay.on() time.sleep(float(duration)) relay.off() relay.close()
class RWF: def __init__(self): self._value1 = 0 self._value2 = 0 self._pump = DigitalOutputDevice(17) # GPIO 17 self._sensor1 = DigitalInputDevice(27) # GPIO 27 self._sensor2 = DigitalInputDevice(22) # GPIO 22 self._verification_delay = VERIFICATION_DELAY_PUMP_OFF # default pump off self._last_pump_on_time = None self._last_pump_off_time = None def pump_off(self): self._pump.off() self._verification_delay = VERIFICATION_DELAY_PUMP_OFF self._last_pump_off_time = datetime.now() set_firebase(0) def pump_on(self): self._pump.on() self._verification_delay = VERIFICATION_DELAY_PUMP_ON self._last_pump_on_time = datetime.now() set_firebase(1) def print(self): message = "Sensor(1)={0}, Sensor(2)={1}, Delay={2}\n" print( message.format(self._value1, self._value2, self._verification_delay)) def read(self): self._value1 = self._sensor1.value self._value2 = self._sensor2.value def is_pump_on(self): return self._verification_delay == VERIFICATION_DELAY_PUMP_ON def sensor1(self): return self._value1 def sensor2(self): return self._value2 def elapsed_seconds_last_pump_off(self): if self._last_pump_off_time: return (datetime.now() - self._last_pump_off_time).total_seconds() return 0 def elapsed_seconds_last_pump_on(self): if self._last_pump_on_time: return (datetime.now() - self._last_pump_on_time).total_seconds() return 0 def sleep(self): sleep(self._verification_delay) def verification_delay(self): return self._verification_delay
class Ringer: def __init__(self,gpio): self.output=DigitalOutputDevice(gpio) def start_ringing(self): print("start ringing") self.output.blink(on_time=1.5,off_time=.5) def stop_ringing(self): print("stop ringing") self.output.off()
class HardwareControl: """ One instance class to control and setup hardware (LIDAR sensor and motor) Integrates Motor and Lidar control. """ def __init__(self): """ Setups Motor and Lidar """ self.Motor = StepMotor() self.Lidar = LidarSensor() self.Lidar.configure() self.Laser = DigitalOutputDevice(21) #BOARD40 def __del__(self): if self.Laser.value != 0: self.Laser.off() def turnMotor(self, degrees, stepInsteadofDeg=False, steptime=1): """ Steptime is in miliseconds. Turns motor and returns the new angle of the motor. The motor range is limited to 200 degrees both directions. """ if stepInsteadofDeg: stepnum = int(degrees) else: stepnum = int(degrees / self.Motor.STEP_DEGREE) steptime = steptime / 100. motangle = self.Motor.turnbyStep(stepnum) return motangle def calibrateMotor(self): """ Changes the absolute motor angle to the current position of motor """ self.Motor.angle = 0 def getDistance(self): """ returns the distances in a list """ lvalues = self.Lidar.getdata() it = 0 while len(lvalues) == 0 and it < 5: lvalues = self.Lidar.getdata() it = it + 1 return lvalues def toggleLaser(self): if self.Laser.value == 1: self.Laser.off() else: self.Laser.on()
class Roseluck: #gpizero uses broadcom pin numbers VALVE_1_PIN = 23 VALVE_2_PIN = 24 def __init__(self, v1pin = VALVE_1_PIN, v2pin = VALVE_2_PIN): self.valve1 = DigitalOutputDevice(v1pin) self.valve2 = DigitalOutputDevice(v2pin) self.valves = [self.valve1, self.valve2] self.valve1thread = None self.valve2thread = None self.threads = [self.valve1thread, self.valve2thread] #function to turn off valves, either zone 1 or zone 2 by int. #pass 0 or nothing to turn both valves off. def turnoff(self, valve = 0): if ((valve < 0) or (valve > 2)): print ("Invalid valves in turnoff function") return 1 if ((valve == 1) or (valve == 0)): self.valve1.off() if ((valve == 2) or (valve == 0)): self.valve2.off() return 0 #Turns on the passed valve as long as it's valid def turnon(self, valve): if (valve < 1 or valve > 2): print("Invalid valve in turnon function") return 1 self.valves[valve-1].on() #function to trigger a valve for a duration def runstation(self, valve, duration): if valve < 1 or valve > 2: print ("Invalid valve or duration in runstation") print ("Attempted to run station " + str(valve) + " for " + str(duration) + "seconds.") return 1 if self.threads[valve-1] is not None and self.threads[valve - 1].is_alive(): print ("Valve " + str(valve) + " is already active.") return 2 else: self.threads[valve-1] = ValveWorker(self, valve, duration) #self.threads[valve-1].daemon = True self.threads[valve-1].start() return 0 #function to test the system. Engage each zone for five minutes. def systemtest(self): print ('System test:') print ("Triggering zone 1 for 5 minutes...") self.runstation (1, 300) print ("Triggering zone 2 for 5 minutes...") self.runstation (2, 300) print ("System test complete") print ("____________________")
class LightPoint(Point): def __init__(self, id, controlPin, buttonPin, comm_service): Point.__init__(self, id=id, controlPin=controlPin) self.buttonPin = buttonPin self.button = None self.led = None self.comm_service = comm_service logging.info("Light point {0} initialized, Ctn: {1}, Btn: {2}".format( self.id, self.controlPin, self.buttonPin)) def initialize(self): self.button = Button(pin=self.buttonPin, hold_time=0.1) self.button.when_held = self.toggle self.led = DigitalOutputDevice(self.controlPin) def notifyCurrentState(self): message = None logging.info("Notify light {id} state to {state}".format( id=self.id, state=self.led.value)) if self.led.value == 1: message = COMMAND_ON else: message = COMMAND_OFF self.comm_service.sendStatusUpdate(point_id=self.id, message=message) def updateStatus(self, message): if message == COMMAND_OFF: self.disable() else: if message == COMMAND_ON: self.enable() else: logging.error( "Unrecognized command {cmd} for point {id}, skipped.". format(cmd=message, id=self.id)) def reset(self): self.updateStatus(COMMAND_OFF) self.notifyCurrentState() def enable(self): self.led.on() logging.info("Enabled point {0}".format(self.id)) def disable(self): self.led.off() logging.info("Disabled point {0}".format(self.id)) def toggle(self): if self.led.value == 1: self.disable() else: self.enable() self.notifyCurrentState()
def fan_control(): fan = DigitalOutputDevice(GPIO_PIN) while True: temp = check_temp() if temp > ON_TEMP: fan.on() elif temp < OFF_TEMP: fan.off() sleep(5)
class MOSFETSwitch(object): def __init__(self, pin): self.mosfet = DigitalOutputDevice(pin=pin, active_high=True, initial_value=False) def on(self): self.mosfet.on() def off(self): self.mosfet.off()
class Escape: def __init__(self): self.motor_escape = DigitalOutputDevice(pin=pin_fig.escape_relayswitch) def on(self): self.motor_escape.on() print("escape on") def off(self): self.motor_escape.off() self.motor_escape.close() print("escape off")
class Snake: PIN_SNAKE_EN = 2 PIN_EASTER_EN = 3 PIN_SNAKE_DONE = 25 def __init__(self): self.snakeOnPin = DigitalOutputDevice(self.PIN_SNAKE_EN, active_high=False) self.snakeDonePin = DigitalInputDevice(self.PIN_SNAKE_DONE, pull_up=False) self.snakeDonePin.when_activated = self.onDone self.done = False self.enabled = False return def onDone(self): self.done = True self.snakeOnPin.off() def isAlive(self): return True def getDone(self, newValue=None): if (newValue != None): self.done = newValue if self.snakeDonePin.is_active: self.done = True return self.done def getEnabled(self, newValue=None): if (newValue != None): self.enabled = newValue if self.enabled and not self.done: self.snakeOnPin.on() else: self.snakeOnPin.off() return self.enabled def update(self): self.getDone() return def getAllValues(self): values = {} values['done'] = self.done values['alive'] = self.isAlive() return values
def motionController(): global txMotionData, camAngle, headAngle leftPowerPin = 12 # 32IN1 - Forward Drive leftDirPin = 16 # 36IN2 - Reverse Drive rightPowerPin = 24 # 18 IN1 - Forward Drive rightDirPin = 23 # 16IN2 - Reverse Drive leftPower = PWMOutputDevice(leftPowerPin, True, 0, 1000) leftDir = DigitalOutputDevice(leftDirPin, True, False) rightPower = PWMOutputDevice(rightPowerPin, True, 0, 1000) rightDir = DigitalOutputDevice(rightDirPin, True, False) # print('\nmotionController Started') while stopMotionController is not True: power = int(rxMotionData % 1000) # if power!= 0: angle = int(rxMotionData / 1000) power = (power + 1) / 256 if angle in range(80, 101) or angle in range(260, 281): rPower = power lPower = power elif angle in range(101, 181): rPower = power lPower = power * ((180 - angle) / 90) elif angle in range(181, 261): rPower = power lPower = power * ((angle - 180) / 90) elif angle in range(0, 80): rPower = power * ((angle) / 90) lPower = power else: rPower = power * ((359 - angle) / 90) lPower = power if lPower < 0.1: lPower = 0 if rPower < 0.1: rPower = 0 if angle in range(0, 181): leftDir.off() rightDir.off() leftPower.value = lPower rightPower.value = rPower else: leftDir.on() rightDir.on() leftPower.value = lPower rightPower.value = rPower txMotionData = int(lPower + rPower) time.sleep(0.04)
class TB6612FNG: def __init__(self, pin_fig_in1, pin_fig_in2, pin_fig_pwm, frequency=None): self.in1 = DigitalOutputDevice(pin=pin_fig_in1) self.in2 = DigitalOutputDevice(pin=pin_fig_in2) if frequency is None: # Not PWM mode self.pwm = DigitalOutputDevice(pin=pin_fig_pwm) else: # PWM mode self.pwm = PWMOutputDevice(pin=pin_fig_pwm, frequency=frequency) def cw(self): self.in1.on() self.in2.off() self.pwm.on() def ccw(self): self.in1.off() self.in2.on() self.pwm.on() def stop(self): self.in1.off() self.in2.off() self.pwm.off() def stop_and_close(self): self.stop() self.in1.close() self.in2.close() self.pwm.close()
class PluginModule(object): def __init__(self): logger.info('background light control') path = pathlib.Path(__file__).parent with open(path / 'light_control.yaml') as file: self.config_data = yaml.load(file, Loader=yaml.FullLoader) self.relay = DigitalOutputDevice(int(self.config_data['gpio_pin']), active_high=True) self.turn_off_time = time.time() self.check_sleep_time = int(self.config_data['checktime']) self.waittime = int(self.config_data['waittime']) self.set_turn_on_time() self.run() def worker(self): while True: current_time = time.time() logger.info('time %s %s %s', self.turn_off_time, current_time, self.relay) if (self.turn_off_time <= current_time) & self.relay.is_active: logger.info('turn off') self.relay.off() eventlet.sleep(self.check_sleep_time) def run(self): logger.info('run') eventlet.spawn(self.worker) eventlet.sleep(0) #threading.Thread(target=self.worker, daemon=True).start() def set_turn_on_time(self): logger.info('turn on') self.relay.on() self.turn_off_time = time.time() + self.waittime def set_turn_on_time_service(self): self.set_turn_on_time() return ('OK') def activate(self, app): app.add_url_rule('/api/v1/resources/lighston', view_func=self.set_turn_on_time_service)
class Motor: def __init__(self, forward, backward, active_high=True, initial_value=False, pin_factory=None, name=''): self.forward_motor = DigitalOutputDevice(pin=forward, active_high=active_high) self.backward_motor = DigitalOutputDevice(pin=backward, active_high=active_high) self.name = name def forward(self): self.forward_motor.on() self.backward_motor.off() print(self.name, 'forward') def backward(self): self.forward_motor.off() self.backward_motor.on() print(self.name, 'backward') def stop(self): self.forward_motor.off() self.backward_motor.off() print(self.name, 'stop') def close(self): self.forward_motor.close() self.backward_motor.close()
class AsyncMotor(CompositeDevice): def __init__(self, open_pin, close_pin, open_time, close_time, active_high=False, pin_factory=None): self.open_door_relay = DigitalOutputDevice( open_pin, active_high=active_high, initial_value=0, pin_factory=pin_factory) self.close_door_relay = DigitalOutputDevice( close_pin, active_high=active_high, initial_value=0, pin_factory=pin_factory) super().__init__(self.open_door_relay, self.close_door_relay) self.open_move_duration = open_time self.close_move_duration = close_time async def open_door(self): self.close_door_relay.off() await asyncio.sleep(1) self.open_door_relay.on() await asyncio.sleep(self.open_move_duration) self.open_door_relay.off() async def close_door(self): self.open_door_relay.off() await asyncio.sleep(1) self.close_door_relay.on() await asyncio.sleep(self.close_move_duration) self.close_door_relay.off()
class PowerLight(): @staticmethod def getDefaultConfig(): return {"pin": 7, "real": ON_PI} def __init__(self, config): if config["real"]: self.led = DigitalOutputDevice(config["pin"]) def set(self, on=True): if self.led: if on: self.led.on() else: self.led.off()
class Controller: def __init__(self, pin): self.__status = Status.OFF self.__device = DigitalOutputDevice(pin) def setStatus(self, status): if status == Status.OFF: self.__device.off() elif status == Status.ON: self.__device.on() self.__status = status return self.__status def getStatus(self): return self.__status
class ShotsAlarmStrobe: def __init__(self): self.strobe = DigitalOutputDevice(17) self.off() def on(self): self.strobe.on() def off(self): self.strobe.off() def alarm_activate(self, countdownLength, strobeLength): self.on() def alarm_cancel(self): self.off()
class ShiftRegister(object): def __init__(self, data_pin=17, latch_pin=27, clock_pin=22, num_registers=1): self.data = DigitalOutputDevice(pin=data_pin) self.latch = DigitalOutputDevice(pin=latch_pin) self.clock = DigitalOutputDevice(pin=clock_pin) self.num_registers = num_registers self.current_data = None logging.info('Data Pin: {0} Latch Pin: {1} Clock Pin: {2}'.format( self.data.pin, self.latch.pin, self.clock.pin)) def get_current(self): return self.current_data def write(self, byte_array): byte_array = byte_array[0:self.num_registers] if byte_array == self.current_data: return False self.current_data = byte_array self._unlatch() for byte in byte_array: self._shiftout(byte) self._latch() return True def _unlatch(self): self.latch.off() def _latch(self): self.latch.on() def _shiftout(self, byte): for x in range(8): self.data.value = (byte >> x) & 1 self.clock.on() self.clock.off()
class Motor: """ The class takes three pin numbers as the input to control one of the motor connected to TB6612FNG module. """ def __init__(self, in1, in2, pwm): self.in1 = DigitalOutputDevice(in1) self.in1.off() self.in2 = DigitalOutputDevice(in2) self.in2.on() self.pwm = PWMOutputDevice(pwm, frequency=1000) def set_throttle(self, val): """Control the orientation and the speed of the motor. Arguments: val: a number between -1.0 and 1.0. The motor rotates in forward direction if val > 1, otherwise in reverse direction. Setting val to None will set the motor to stop mode. """ # Set the motor to stop mode. if val is None: self.in1.off() self.in2.off() self.pwm.value = 1.0 else: # Determine the orientation of the motor. if val > 0.0: self.in1.off() self.in2.on() else: self.in1.on() self.in2.off() # Clamp the pwm signal (throttle) to [0, 1]. pwm = max(0.0, min(abs(val), 1.0)) # Note that setting PWM to low will brake the motor no matter what # in1 and in2 input is. self.pwm.value = pwm def close(self): self.in1.close() self.in2.close() self.pwm.close()
class Relay(): "Simple wrapper for a power relay" def __init__(self, pin: int): self.device = DigitalOutputDevice(pin) @property def value(self) -> bool: return bool(self.device.value) def set(self) -> None: self.device.on() def unset(self) -> None: self.device.off() def toggle(self) -> None: self.device.toggle()
def _check_pin(self, pin_number: int) -> bool: try: device = DigitalOutputDevice("GPIO" + str(pin_number), active_high=False) print(f'Found GPIO{pin_number} Pin. Turning on!') device.on() confirm = [{ 'type': 'confirm', 'message': 'Is any device working right now?', 'name': 'working', 'default': False, }] answer = prompt(confirm) device.off() return answer['working'] except GPIOZeroError as exc: print(f'Couldn\'t set up gpio pin: {pin_number}') raise exc
def debug_start(message): start_time = time.time() sample_length = 10 timeout = 2 d_out = DigitalInputDevice(pin=LOAD_CELL_DOUT, pull_up=True) sck = DigitalOutputDevice(pin=LOAD_CELL_SCK) adc = MCP3008(channel=0) sck.off() counter = 1 emit_data = [] while time.time() - start_time < sample_length: # Retrieve data from MCP3008 fsr_data = adc.value # Retrieve data from HX711 loop_start = time.time() while not d_out.is_active: if time.time() - loop_start > timeout: break data = 0 for j in range(24): data = data << 1 sck.on() sck.off() if d_out.value == 0: data = data + 1 #loadcell_data = {'hex': hex(data), 'num': convert_twos_complement(data)} #emit('debug data', {'data': {'fsr': fsr_data, 'loadcell': loadcell_data}}) #counter = counter + 1 #if counter % 8 == 0: # emit('debug data', {'data': emit_data}) # emit_data = [] #else: # emit_data.append({'fsr': fsr_data, 'loadcell': convert_twos_complement(data)}) emit_data.append({ 'fsr': fsr_data, 'loadcell': convert_twos_complement(data) }) # 25th pulse sck.on() sck.off() # 128 pulses for i in range(LOAD_CELL_GAIN): sck.on() sck.off() emit('debug data', {'data': emit_data}) time.sleep(1) emit('debug finish')
class Channel: def __init__(self, name, output_pin, input_pin=None): self.name = name self.state = None self.output_pin = output_pin if input_pin is not None: self.input_pin = input_pin self.output_device = DigitalOutputDevice(output_pin) if input_pin: self.input_device = DigitalInputDevice(input_pin) def set(self, state): """Sets the channel output""" self.state = state if state == 'On': self.output_device.on() elif state == 'Off': self.output_device.off() else: raise NotImplementedError log.info('Channel %s set to %s', self.name, state) def valid(self): """ Checks if the channel output is valid Returns: True, if the output and input pin states match. False, if they don't match. None, if no input pin is defined. """ if self.input_pin is None: return None else: return self.output_device.value == self.input_device.value def status(self): return { 'state': self.state, 'valid': self.valid(), }
def main(): """Run a loop.""" # Wire DC IN to 5V # Wire DC OUT to GND # Wire VCC to GPIO 23 output_pin = 23 relay = DigitalOutputDevice(output_pin) try: while True: relay.on() time.sleep(0.5) relay.off() time.sleep(0.5) except KeyboardInterrupt: pass finally: relay.close()
class Blind: DELAY_TIME = 13 + 7 def __init__(self, name: str, pin_up: Pin, pin_down: Pin, kind="Blind"): self.name = name self.pin_up = pin_up self.pin_down = pin_down self.__blind_up = DigitalOutputDevice(pin_up.value, active_high=False) self.__blind_down = DigitalOutputDevice(pin_down.value, active_high=False) self.kind = kind self.__state = State.DOWN self.stop() print('INFO: Blind:', pin_up.name, '-', pin_up.value, pin_down.name, '-', pin_down.value) def __delay_stop(self): time.sleep(self.DELAY_TIME) # double time self.stop() def stop(self): self.__blind_up.off() self.__blind_down.off() def down(self): self.__blind_up.off() self.__blind_down.on() self.__state = State.DOWN threading.Thread(target=self.__delay_stop).start() def up(self): self.__blind_down.off() self.__blind_up.on() self.__state = State.UP threading.Thread(target=self.__delay_stop).start() def toggle(self): if self.__state == State.UP: self.down() else: self.up() def keep_on(self): if self.__state == State.UP: self.up() else: self.down() def is_moving(self) -> bool: return self.__blind_up.is_active or self.__blind_down.is_active
class Motor: def __init__(self, ain1=None, ain2=None, bin1=None, bin2=None, pwma=None, pwmb=None): print("init") self.ain1 = DigitalOutputDevice(ain1, initial_value=False) self.ain2 = DigitalOutputDevice(ain2, initial_value=False) self.bin1 = DigitalOutputDevice(bin1, initial_value=False) self.bin2 = DigitalOutputDevice(bin2, initial_value=False) self.pwma = PWMOutputDevice(pwma, initial_value=.5) self.pwmb = PWMOutputDevice(pwmb, initial_value=.5) def stop(self): print("stop") self.ain1.off() self.ain2.off() self.bin1.off() self.bin2.off() def forward(): print("forward") self.ain1.on() self.ain2.off() self.bin1.on() self.bin2.off() def backward(): print("backward") self.ain1.off() self.ain2.on() self.bin1.off() self.bin2.on() def turn_left(): print("turn_left") self.ain1.off() self.ain2.on() self.bin1.on() self.bin2.off() def turn_right(): print("turn_right") self.ain1.on() self.ain2.off() self.bin1.off() self.bin2.on()
class PCD8544(SPIDevice): """ PCD8544 display implementation. This implementation uses software shiftOut implementation? @author SrMouraSilva Based in 2013 Giacomo Trudu - wicker25[at]gmail[dot]com Based in 2010 Limor Fried, Adafruit Industries https://github.com/adafruit/Adafruit_Nokia_LCD/blob/master/Adafruit_Nokia_LCD/PCD8544.py Based in CORTEX-M3 version by Le Dang Dung, 2011 [email protected] (tested on LPC1769) Based in Raspberry Pi version by Andre Wussow, 2012, [email protected] Based in Raspberry Pi Java version by Cleverson dos Santos Assis, 2013, [email protected] https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md The SPI master driver is disabled by default on Raspbian. To enable it, use raspi-config, or ensure the line dtparam=spi=on isn't commented out in /boot/config.txt, and reboot. :param int din: Serial data input :param int sclk: Serial clock input (clk) :param int dc: Data/Command mode select (d/c) :param int rst: External reset input (res) :param int cs: Chip Enable (CS/SS, sce) :param contrast :param inverse """ def __init__(self, din, sclk, dc, rst, cs, contrast=60, inverse=False): super(PCD8544, self).__init__(clock_pin=sclk, mosi_pin=din, miso_pin=9, select_pin=cs) self.DC = DigitalOutputDevice(dc) self.RST = DigitalOutputDevice(rst) self._reset() self._init(contrast, inverse) self.drawer = DisplayGraphics(self) self.clear() self.dispose() def _reset(self): self.RST.off() time.sleep(0.100) self.RST.on() def _init(self, contrast, inverse): # H = 1 self._send_command(SysCommand.FUNC | Setting.FUNC_H) self._send_command(SysCommand.BIAS | Setting.BIAS_BS2) self._send_command(SysCommand.VOP | contrast & 0x7f) # H = 0 self._send_command(SysCommand.FUNC | Setting.FUNC_V) self._send_command( SysCommand.DISPLAY | Setting.DISPLAY_D | Setting.DISPLAY_E * (1 if inverse else 0) ) def _send_command(self, data): self.DC.off() self._spi.write([data]) def _send_data_byte(self, x, y, byte): self._set_cursor_x(x) self._set_cursor_y(y) self.DC.on() self._spi.write([byte]) def set_contrast(self, value): self._send_command(SysCommand.FUNC | Setting.FUNC_H) self._send_command(SysCommand.VOP | value & 0x7f) self._send_command(SysCommand.FUNC | Setting.FUNC_V) def write_all(self, data): self._set_cursor_x(0) self._set_cursor_y(0) self.DC.on() self._spi.write(data) def _set_cursor_x(self, x): self._send_command(SysCommand.XADDR | x) def _set_cursor_y(self, y): self._send_command(SysCommand.YADDR | y) def clear(self): self._set_cursor_x(0) self._set_cursor_y(0) self.drawer.clear() @property def width(self): return DisplaySize.WIDTH @property def height(self): return DisplaySize.HEIGHT @property def value(self): return 0 def close(self): super(PCD8544, self).close() @property def draw(self): return self.drawer.draw def dispose(self): self.drawer.dispose()
class Robot(object): SPEED_HIGH = int(config.get("robot.speed","speed_high")) SPEED_MEDIUM = int(config.get("robot.speed","speed_medium")) SPEED_LOW = int(config.get("robot.speed","speed_low")) ##Define the arc of the turn process by a tuple wheels speed (left, right) LEFT_ARC_CLOSE = eval(config.get("robot.speed","left_arc_close")) LEFT_ARC_OPEN = eval(config.get("robot.speed","left_arc_open")) RIGHT_ARC_CLOSE = eval(config.get("robot.speed","right_arc_close")) RIGHT_ARC_OPEN = eval(config.get("robot.speed","right_arc_open")) #Pin pair left FORWARD_LEFT_PIN = int(config.get("robot.board.v1","forward_left_pin")) BACKWARD_LEFT_PIN = int(config.get("robot.board.v1","backward_left_pin")) #Pin pair right FORWARD_RIGHT_PIN = int(config.get("robot.board.v1","forward_right_pin")) BACKWARD_RIGHT_PIN = int(config.get("robot.board.v1","backward_right_pin")) #PWM PINS PWM_LEFT_PIN = int(config.get("robot.board.v1","pwm_left_pin")) PWM_RIGHT_PIN = int(config.get("robot.board.v1","pwm_right_pin")) #Frecuency by hertz FRECUENCY = int(config.get("robot.board.v1","frecuency")) # Cycles fits for pwm cycles LEFT_CYCLES_FIT = int(config.get("robot.board.v1","left_cycles_fit")) RIGHT_CYCLES_FIT = int(config.get("robot.board.v1","right_cycles_fit")) #Pin settings for head control HEAD_HORIZONTAL_PIN = int(config.get("robot.board.v1","head_pwm_pin_horizontal_axis")) HEAD_VERTICAL_PIN = int(config.get("robot.board.v1","head_pwm_pin_vertical_axis")) HEAD_HORIZONTAL_RANGE = config.get("robot.board.v1","head_horizontal_range").split(",") HEAD_VERTICAL_RANGE = config.get("robot.board.v1","head_vertical_range").split(",") RIGHT_WHEEL_SENSOR = int(config.get("robot.board.v1","right_wheel_sensor")) LEFT_WHEEL_SENSOR = int(config.get("robot.board.v1", "left_wheel_sensor")) CONTROLLER_BOARD = config.get("robot.controller", "board") #v2 WHEEL_LEFT_ENABLED = int(config.get("robot.board.v2", "wheel_left_enabled")) WHEEL_LEFT_HEADING = int(config.get("robot.board.v2", "wheel_left_heading")) WHEEL_LEFT_STEP = int(config.get("robot.board.v2", "wheel_left_step")) WHEEL_RIGHT_ENABLED = int(config.get("robot.board.v2", "wheel_right_enabled")) WHEEL_RIGHT_HEADING = int(config.get("robot.board.v2", "wheel_right_heading")) WHEEL_RIGHT_STEP = int(config.get("robot.board.v2", "wheel_right_step")) SERVO_V = None SERVO_H = None head_vertical_current_position = None head_horizontal_current_position = None def __init__(self): if env == "prod": log.debug("Using %s configuration" % self.CONTROLLER_BOARD ) self.SERVO_H = AngularServo(self.HEAD_HORIZONTAL_PIN, min_angle=-80, max_angle=80) self.SERVO_V = AngularServo(self.HEAD_VERTICAL_PIN, min_angle=-80, max_angle=80) ##Digital devices self.forward_left_device = None self.forward_right_device = None self.backward_left_device = None self.backward_right_device = None self.wheel_right_step = None self.wheel_left_step = None self.wheel_right_heading = None self.wheel_left_heading = None self.wheel_right_enabled = None self.wheel_left_enabled = None self.pwm_left = None self.pwm_right = None if self.CONTROLLER_BOARD == "v1": self.forward_left_device = DigitalOutputDevice(self.FORWARD_LEFT_PIN, True, False) self.forward_right_device = DigitalOutputDevice(self.FORWARD_RIGHT_PIN, True, False) self.backward_left_device = DigitalOutputDevice(self.BACKWARD_LEFT_PIN, True, False) self.backward_right_device = DigitalOutputDevice(self.BACKWARD_RIGHT_PIN, True, False) self.pwm_left = PWMOutputDevice(self.PWM_LEFT_PIN, True, False, self.FRECUENCY) self.pwm_right = PWMOutputDevice(self.PWM_RIGHT_PIN, True, False, self.FRECUENCY) if self.CONTROLLER_BOARD == "v2": self.wheel_right_step = DigitalOutputDevice(self.WHEEL_RIGHT_STEP, True, False) self.wheel_left_step = DigitalOutputDevice(self.WHEEL_LEFT_STEP, True, False) self.wheel_right_heading = DigitalOutputDevice(self.WHEEL_RIGHT_HEADING, True, False) self.wheel_left_heading = DigitalOutputDevice(self.WHEEL_LEFT_HEADING, True, False) self.wheel_right_enabled = DigitalOutputDevice(self.WHEEL_RIGHT_ENABLED, True, False) self.wheel_left_enabled = DigitalOutputDevice(self.WHEEL_LEFT_ENABLED, True, False) self.current_horizontal_head_pos = 0 self.current_vertical_head_pos = 0 self.center_head() self._counting_steps = 0 self._current_steps = 0 self._stepper_current_step = 0 def _set_left_forward(self): if self.CONTROLLER_BOARD == "v1": self.forward_left_device.on() self.backward_left_device.off() def _set_left_backward(self): if self.CONTROLLER_BOARD == "v1": self.forward_left_device.off() self.backward_left_device.on() def _set_left_stop(self): if self.CONTROLLER_BOARD == "v1": self.forward_left_device.on() self.backward_left_device.on() def _set_right_forward(self): if self.CONTROLLER_BOARD == "v1": self.forward_right_device.on() self.backward_right_device.off() def _set_right_backward(self): if self.CONTROLLER_BOARD == "v1": self.forward_right_device.off() self.backward_right_device.on() def _set_right_stop(self): if self.CONTROLLER_BOARD == "v1": self.forward_right_device.on() self.backward_right_device.on() def set_forward(self): log.debug("setting movement to forward") if env == "prod": self._set_left_forward() self._set_right_forward() def set_backward(self): log.debug("setting movement to backward") if env == "prod": self._set_left_backward() self._set_right_backward() def set_rotate_left(self): log.debug("setting movement to rotate left") if env == "prod": self._set_left_backward() self._set_right_forward() def set_rotate_right(self): log.debug("setting movement to rotate right") if env == "prod": self._set_right_backward() self._set_left_forward() def stop(self): log.debug("stopping") if env == "prod": if self.CONTROLLER_BOARD == "v1": self.pwm_left.off() self.pwm_right.off() def move(self, speed=None, arc=None, steps=100, delay=0.7, heading=1): if self.CONTROLLER_BOARD == "v1": self._move_dc(speed, arc) elif self.CONTROLLER_BOARD == "v2": self._move_steppers_bipolar(steps=steps, delay=delay, heading=heading) def _move_dc(self, speed, arc): log.debug("Moving using DC motors") if (speed and arc): print("Error: speed and arc could not be setted up at the same time") return if env == "prod": self.pwm_left.on() self.pwm_right.on() if (speed): log.debug("moving on " + str(speed)) log.debug("aplying fit: left " + str(self.LEFT_CYCLES_FIT) + " right " + str(self.RIGHT_CYCLES_FIT)) aditional_left_clycles = self.LEFT_CYCLES_FIT if ((speed + self.LEFT_CYCLES_FIT) <= 100.00) else 0.00 aditional_right_clycles = self.RIGHT_CYCLES_FIT if ((speed + self.RIGHT_CYCLES_FIT) <= 100.00) else 0.00 if env == "prod": self.pwm_left.value = (speed + aditional_left_clycles) / 100.00 self.pwm_right.value = (speed + aditional_right_clycles) / 100.00 if (arc): cycle_left, cycle_right = arc log.debug("turning -> left wheel: " + str(cycle_left) + " right wheel: " + str(cycle_right)) if env == "prod": self.pwm_left.value = cycle_left / 100.00 self.pwm_right.value = cycle_right / 100.00 def _move_steppers_bipolar(self, steps, heading, delay): """ Currently it would take 4 steps to complete a whole wheel turn """ log.debug("Moving steppers bipolars . Steps " + str(steps) + " delay " + str(delay)) steps_left = abs(steps) if env == "prod": self.wheel_left_enabled.off() self.wheel_right_enabled.off() while(steps_left!=0): log.debug("Current step: " + str(steps_left)) if env == "prod": if heading: self.wheel_left_heading.on() self.wheel_right_heading.off() else: self.wheel_left_heading.off() self.wheel_right_heading.on() self.wheel_left_step.off() self.wheel_right_step.off() sleep(delay/1000.00) self.wheel_left_step.on() self.wheel_right_step.on() sleep(delay/1000.00) steps_left -= 1 if env == "prod": self.wheel_left_enabled.on() self.wheel_right_enabled.on() def center_head(self): log.debug("centering head") self.head_horizontal_current_position = 0 self.head_vertical_current_position = 0 if env == "prod": self.SERVO_H.mid() self.SERVO_V.mid() sleep(0.2) self.SERVO_H.detach() self.SERVO_V.detach() def _angle_to_ms(self,angle): return 1520 + (int(angle)*400) / 45 def move_head_horizontal(self, angle): log.debug("horizontal limits: " + self.HEAD_HORIZONTAL_RANGE[0] +" "+ self.HEAD_HORIZONTAL_RANGE[1]) log.debug("new horizontal angle: " + str(angle)) if angle > int(self.HEAD_HORIZONTAL_RANGE[0]) and angle < int(self.HEAD_HORIZONTAL_RANGE[1]): log.debug("moving head horizontal to angle: " + str(angle)) self.head_horizontal_current_position = angle if env == "prod": self.SERVO_H.angle = angle sleep(0.2) self.SERVO_H.detach() def move_head_vertical(self, angle): log.debug("vertical limits: " + self.HEAD_VERTICAL_RANGE[0] +" "+ self.HEAD_VERTICAL_RANGE[1]) log.debug("new vertical angle: " + str(angle)) if angle > int(self.HEAD_VERTICAL_RANGE[0]) and angle < int(self.HEAD_VERTICAL_RANGE[1]): log.debug("moving head vertical to angle: " + str(angle)) self.head_vertical_current_position = angle if env == "prod": self.SERVO_V.angle = angle sleep(0.2) self.SERVO_V.detach() #Used for encoders def steps(self, counting): self._current_steps = counting self.move(speed=self.SPEED_HIGH) self.move(speed=self.SPEED_MEDIUM) rpio.add_interrupt_callback(RIGHT_WHEEL_SENSOR, self._steps_callback, threaded_callback=True) rpio.add_interrupt_callback(LEFT_WHEEL_SENSOR, self._steps_callback, threaded_callback=True) rpio.wait_for_interrupts(threaded=True) def _steps_callback(self, gpio_id, value): self._counting_steps += 1 if self._counting_steps > self._current_steps: self._counting_steps = 0 self._current_steps = 0 rpio.stop_waiting_for_interrupts()