def main(): ''' Makes a LED to blink according to the distance meassured by an ultrasonic sensor. Finish when user press a toggle key. ''' blinker = Blinker(27, MAX_DELAY) #P8.17 ultrasonic = Ultrasonic(66, 69) #P8.7, P8.9 key = Gpio(65, Gpio.IN) #P8.18 try: print("Ready. Press toggle key to start.") #Wait for key down event while key.getValue() == Gpio.LOW: sleep(0.2) #Wait for key up event while key.getValue() == Gpio.HIGH: sleep(0.2) print("Started. Press toggle key again to finish.") blinker.start() while key.getValue() == Gpio.LOW: dist = ultrasonic.read() delay = calculateDelay(dist) blinker.setDelay(delay) sleep(0.2) print("Bye!") finally: key.cleanup() blinker.stop() blinker.cleanup() ultrasonic.cleanup()
key = Gpio(65, Gpio.IN) #P8.18 try: light = Gpio.LOW led.setValue(light) lastKeyState = Gpio.LOW print("Ready.\nPress toggle key to change led state or Ctrl+C to exit.") while True: keyState = key.getValue() if lastKeyState != keyState and keyState == Gpio.HIGH: light = not light led.setValue(light) print("Led state changed to {0}.".format("ON" if light else "OFF")) lastKeyState = keyState sleep(0.2) except KeyboardInterrupt: print("\nBye!") finally: led.setValue(Gpio.LOW) led.cleanup() key.cleanup()
class Blinker(object): ''' Makes a LED to blink ''' def __init__(self, port, delay=0.1): ''' Constructor @param port: GPIO port number where the LED is connected to @param delay: Time the LED is on and off. Default 0.1s ''' self._port = Gpio(port, Gpio.OUT) self._delay = delay self._isRunning = False self._doBlinkThread = None def start(self): ''' Starts the LED to be blinking ''' if self._doBlinkThread == None or not self._doBlinkThread.isAlive(): self._isRunning = True self._doBlinkThread = Thread(target=self._doBlink) self._doBlinkThread.start() def stop(self): ''' Stops the LED blinking ''' self._isRunning = False if self._doBlinkThread != None and self._doBlinkThread.isAlive(): self._doBlinkThread.join() def setDelay(self, delay): ''' Set the time the LED is on and off @param delay: seconds ''' self._delay = delay def _doBlink(self): ''' Thread action to be the LED blinking ''' status = True while self._isRunning: self._port.setValue(status) status = not status time.sleep(self._delay) self._port.setValue(False) def cleanup(self): ''' Frees ressources ''' self._port.cleanup()
class Worker(Threader): core = None music = None display = None gpio = None ir_sender = None ir_receiver = None timer_on = None timer_off = None alert = None timer_alert = None time = None date = None menu = None response_code = None def start(self, config, core): self.config = config self.core = core super(Worker, self).start() def run(self): try: self._init_menu() self.music = Music(self.core, self.config['default_tracks'], self.config['default_preset']) self.display = DisplayWithPowerSaving( self.config['display_min_brightness'], self.config['display_max_brightness'], self.config['display_off_time_from'], self.config['display_off_time_to']) self.gpio = Gpio( self.config['buttons_enabled'], self.play_stop_music, self._on_menu_click, self._on_menu_click_left, self._on_menu_click_right, self.config['light_sensor_enabled'], self._on_light_sensor, self.config['relay_enabled']) self.ir_sender = IrSender(self.config['ir_remote'], self.gpio.switch_relay) self.ir_receiver = IrReceiver( self.config['ir_receiver_enabled'], self.play_stop_music, self._on_menu_click, self._on_menu_click_left, self._on_menu_click_right, self.music.decrease_volume, self.music.increase_volume, self.run_alert, self._on_change_preset) self.timer_on = TimerOn(self.play_music) self.timer_off = TimerOff(self.stop_music) self.alert = Alert(self.music, self.ir_sender, self.config['alert_files']) self.timer_alert = TimerAlert(self.run_alert) self.time = Time() self.date = Date([self.timer_on, self.timer_off, self.timer_alert]) self.menu = Menu(self.display, self.MENU, [ self.time, self.date, self.timer_on, self.timer_off, self.timer_alert ]) while True: self.menu.run() if (self.stopped()): break else: sleep(1) except Exception as inst: logging.error(inst) finally: self.ir_sender.stop() self.ir_receiver.stop() self.display.shutdown() self.gpio.cleanup() def _init_menu(self): self.MENU = { "get_sub_menu": lambda: [{ "get_sub_menu": lambda: [ self.MENU_TIMER, self.MENU_PLAY_1, self.MENU_RUN_SH, self. MENU_VOLUME, self.MENU_STYLE, self.MENU_DEMO, self. MENU_SYSTEM ] }] } self.MENU_TIMER = { "get_buffer": lambda: [ 0, Symbols.T1, Symbols.T2, Symbols.I, Symbols.M1, Symbols.M2, Symbols.E, Symbols.R ], "get_sub_menu": lambda: [self.MENU_ALERT, self.MENU_TIMER_OFF, self.MENU_TIMER_ON] } self.MENU_ALERT = { "get_buffer": lambda: [ 0, Symbols.A, Symbols.L, Symbols.E, Symbols.R, Symbols.T1, Symbols.T2, 0 ], "get_sub_menu": lambda: [self.MENU_ALERT_ADD, self.MENU_ALERT_CLEAR, self.MENU_ALERT_RUN] } self.MENU_ALERT_ADD = { "get_buffer": lambda: [0, 0, 0, Symbols.A, Symbols.D, Symbols.D, 0, 0], "get_sub_menu": lambda: [{ "get_buffer": self.timer_alert.get_draw_menu_buffer, "click": lambda: (self.timer_alert.add_timer(), self.display.draw(self.timer_alert.get_draw_menu_buffer())), "click_left": self.timer_alert.decrease, "click_right": self.timer_alert.increase }] } self.MENU_ALERT_CLEAR = { "get_buffer": lambda: [0, 0, Symbols.C, Symbols.L, Symbols.E, Symbols.A, Symbols.R, 0], "click": lambda: self.timer_alert.reset(), "click_animation": True } self.MENU_ALERT_RUN = { "get_buffer": lambda: [0, 0, 0, Symbols.R, Symbols.U, Symbols.N, 0, 0], "click": lambda: self.run_alert(), "click_animation": True } self.MENU_TIMER_OFF = { "group": "timer_off", "get_buffer": lambda: [0, 0, 0, Symbols.O, Symbols.F, Symbols.F, 0, 0], "get_sub_menu": lambda: [{ "get_buffer": self.timer_off.get_draw_buffer, "click_left": self.timer_off.decrease, "click_right": self.timer_off.increase }] } self.MENU_TIMER_ON = { "group": "timer_on", "get_buffer": lambda: [0, 0, 0, Symbols.O, Symbols.N, 0, 0, 0], "get_sub_menu": lambda: [{ "get_buffer": self.timer_on.get_draw_buffer, "click_left": self.timer_on.decrease, "click_right": self.timer_on.increase }] } self.MENU_PLAY_1 = { "get_buffer": lambda: [ 0, Symbols.P, Symbols.L, Symbols.A, Symbols.Y, 0, Symbols. NUMBER[1], 0 ], "click": lambda: self.play_music(self.music.get_default_tracks()) } self.MENU_VOLUME = { "group": "volume", "get_buffer": lambda: [ 0, Symbols.U, Symbols.O, Symbols.L, Symbols.U, Symbols.M1, Symbols.M2, Symbols.E ], "get_sub_menu": lambda: [{ "get_buffer": self.music.get_draw_volume, "click_left": self.music.decrease_volume, "click_right": self.music.increase_volume }] } self.MENU_STYLE = { "group": "style", "get_buffer": lambda: [ 0, Symbols.S, Symbols.T1, Symbols.T2, Symbols.Y, Symbols.L, Symbols.E, 0 ], "get_sub_menu": lambda: list( map( lambda x: { "get_buffer": lambda: x["buffer"], "on_draw": lambda: self.music.set_preset(x["name"]) }, self.music.get_presets())) } self.MENU_RUN_SH = { "get_buffer": lambda: [0, Symbols.R, Symbols.U, Symbols.N, 0, Symbols.S, Symbols.H, 0], "click": lambda: self.music.run_sh(), "click_animation": True } self.MENU_DEMO = { "get_buffer": lambda: [0, 0, Symbols.D, Symbols.E, Symbols.M1, Symbols.M2, Symbols.O, 0], "click": lambda: (self.menu.draw_sub_menu_animation( self.music.get_draw_equalizer_animation()), self.menu.reset_sub_menu()) } self.MENU_SYSTEM = { "get_buffer": lambda: [ Symbols.S, Symbols.Y, Symbols.S, Symbols.T1, Symbols.T2, Symbols.E, Symbols.M1, Symbols.M2 ], "get_sub_menu": lambda: [self.MENU_REBOOT, self.MENU_HALT] } self.MENU_REBOOT = { "get_buffer": lambda: [ 0, Symbols.R, Symbols.E, Symbols.B, Symbols.O, Symbols.O, Symbols.T1, Symbols.T2 ], "click": lambda: self.music.reboot(), "click_animation": True } self.MENU_HALT = { "get_buffer": lambda: [0, 0, Symbols.H, Symbols.A, Symbols.L, Symbols.T1, Symbols.T2, 0], "click": lambda: self.music.halt(), "click_animation": True } def _on_menu_click(self): self.menu.click() def _on_menu_click_left(self): if (self.menu.is_sub_menu_visible()): self.menu.click_left() else: self._decrease_timer() def _on_menu_click_right(self): if (self.menu.is_sub_menu_visible()): self.menu.click_right() else: self._increase_timer() def _on_light_sensor(self, now, is_dark): if (self.music.is_playing() and (now.hour >= self.config['light_sensor_time_from'] or now.hour < self.config['light_sensor_time_to'])): if (is_dark): if (self.music.get_volume() > self.config['light_sensor_volume']): self.music.set_volume(self.config['light_sensor_volume']) self.music.set_preset(self.config['light_sensor_preset']) self.timer_off.reset() self.timer_off.increase() self.timer_off.increase() self.timer_off.increase() self.timer_off.increase() self.menu.draw_sub_menu_animation( self.gpio.get_draw_sleep_animation()) else: self.timer_off.reset() def _on_change_preset(self, value): self.music.set_preset(value) if (value < 0): self.menu.click_left(self.MENU_STYLE) else: self.menu.click_right(self.MENU_STYLE) def _increase_timer(self): if (self.music.is_playing()): self.timer_off.increase() self.menu.draw_sub_menu(self.MENU_TIMER_OFF) else: self.timer_on.increase() self.menu.draw_sub_menu(self.MENU_TIMER_ON) def _decrease_timer(self): if (self.music.is_playing()): self.timer_off.decrease() self.menu.draw_sub_menu(self.MENU_TIMER_OFF) else: self.timer_on.decrease() self.menu.draw_sub_menu(self.MENU_TIMER_ON) def run_alert(self): self.menu.draw_sub_menu_animation( self.alert.get_draw_alert_animation()) self.alert.run() def get_presets(self): return self.music.get_presets() def set_preset(self, value): self.music.set_preset(value) def get_volume(self): return self.music.get_volume() def set_volume(self, volume): self.music.set_volume(volume) def get_state(self): return self.music.get_state() def play_stop_music(self): if (self.music.is_playing()): self.stop_music() else: self.play_music() def play_music(self, tracks=None): self.music.set_volume(self.config['default_volume']) self.music.set_preset(self.config['default_preset']) self.music.play(tracks) self.on_started() def pause_music(self): self.music.pause() self.on_paused() def stop_music(self): self.music.stop() self.on_stopped() def on_started(self): self.menu.draw_sub_menu_animation( self.music.get_draw_start_animation()) def on_stopped(self): self.menu.draw_sub_menu_animation(self.music.get_draw_stop_animation()) self.timer_off.reset() self.ir_sender.power(False) def on_playing(self): self.menu.draw_sub_menu_animation(self.music.get_draw_play_animation()) self.timer_on.reset() if (self.music.is_playing()): self.ir_sender.power(True) def on_paused(self): self.menu.draw_sub_menu_animation( self.music.get_draw_pause_animation()) def on_seeked(self): self.menu.draw_sub_menu_animation(self.music.get_draw_seek_animation()) def on_mute(self, mute): if mute: self.on_volume_changed(0) else: self.on_volume_changed() def on_volume_changed(self, volume=None): if (self.menu is not None and self.music is not None and self.music.is_volume_changed(volume)): self.menu.draw_sub_menu(self.MENU_VOLUME) def on_playback_state_changed(self, old_state, new_state): if (old_state != new_state): if (self.music.is_playing(new_state)): self.on_playing() elif (self.music.is_paused(new_state)): self.on_paused()
class Ultrasonic(object): PULSE2CM = 17241.3793 # cm/s MAX_RANGE = 3500 # cm OUT_OF_RANGE = 0xffffffff def __init__(self, triggerPort, echoPort, nSamples=5): ''' Constructor @param triggerPort: Port number of the trigger signal @param echoPort: Port number of the echo port @param nSamples: Number of samples to measure the distance ''' self._nSamples = nSamples #Configure ports self._trigger = Gpio(triggerPort, Gpio.OUT) self._trigger.setValue(Gpio.LOW) self._echo = Gpio(echoPort, Gpio.IN) time.sleep(2) def read(self): ''' Measures distance @return: Distance as centimeters ''' MAX_POLL = 1000 i = 0 dist = 0 while i < self._nSamples and dist != Ultrasonic.OUT_OF_RANGE: self._trigger.setValue(Gpio.HIGH) time.sleep(0.001) self._trigger.setValue(Gpio.LOW) #TODO: use system's poll mechanism or event to wait for GPIO-level change nPoll = 0 while nPoll < MAX_POLL and self._echo.getValue() == Gpio.LOW: nPoll += 1 if nPoll == MAX_POLL: raise ReadGpioException( "Max poll reached: waiting for echo HIGH") pulseStart = time.time() nPoll = 0 while nPoll < MAX_POLL and self._echo.getValue() == Gpio.HIGH: nPoll += 1 if nPoll == MAX_POLL: raise ReadGpioException( "Max poll reached: waiting for echo LOW") pulseEnd = time.time() pulseDuration = pulseEnd - pulseStart distSample = round(pulseDuration * Ultrasonic.PULSE2CM, 0) #cm if distSample < Ultrasonic.MAX_RANGE: dist = (dist + distSample) / 2.0 if i != 0 else distSample else: dist = Ultrasonic.OUT_OF_RANGE i += 1 return dist def cleanup(self): ''' Frees ressources ''' self._trigger.cleanup() self._echo.cleanup()