def _initialise_brightness_control(self): self.lights_held = False self.sine = Sine() self.rgb_mode_timer = threading.Timer(Config.RGB_MODE_TIMER, self.leave_rgb_mode) self.lights_tx_timer = threading.Timer(Config.LIGHTS_DELAY_TO_SEND, self.lights_send_brightness) self.lights_are_on = True self.brightness = 0xFF self.rgb_long = 0x00FFFFFF self.brightness_control = RotaryEncoder(HAL.LIGHTS_A, HAL.LIGHTS_B, maximum=255, minimum=0, initial=255, step_size=5) self.brightness_control.on_clockwise = self.brightness_up self.brightness_control.on_counter_clockwise = self.brightness_down self._mqtt_client.on_rgb = self.on_rgb_message self.btn_lights = Button(HAL.LIGHTS_C, pull_up=True) self.btn_lights.hold_time = Config.BTN_HOLD_TIME self.btn_lights.when_held = self.enter_rgb_mode self.btn_lights.when_released = self.toggle_lights self.rgb_angle = 0
class MotorController: def __init__(self, mcp_channel, pins, pid_constants, forward): self.current_sensor = CurrentSensor(mcp_channel) self._motor = Motor(pins['pwm'], pins['dir'], forward) self._encoder = RotaryEncoder(pins['a'], pins['b']) self._pid = PID(pid_constants) self._vel_filter = IrregularDoubleExponentialFilter( *motor_vel_smoothing_factors) self._vel = 0 def adjust_motor_speed(self, target_vel, time_elapsed): # use a pi controller to control the speed and limit the output to # [-1, 1] (-1 and 1 correspond to 100% pwm output) error = (target_vel - self._vel) / max_wheel_vel speed = min(max(self._pid.calc(error, time_elapsed), -1), 1) self._motor.set_speed(speed) def read_encoder(self, time_elapsed): # gets the amount the wheel has turned in the last interval and # calculates the wheel's speed with a filter added in dist_traveled = self._encoder.get_pos_dif() * distance_ratio self._vel = self._vel_filter.filter(dist_traveled / time_elapsed, time_elapsed) return dist_traveled def reset(self): self._motor.set_speed(0) self._pid.reset() self._encoder.reset() def stop(self): self._motor.stop() self._encoder.stop()
def __init__(self, mcp_channel, pins, pid_constants, forward): self.current_sensor = CurrentSensor(mcp_channel) self._motor = Motor(pins['pwm'], pins['dir'], forward) self._encoder = RotaryEncoder(pins['a'], pins['b']) self._pid = PID(pid_constants) self._vel_filter = IrregularDoubleExponentialFilter( *motor_vel_smoothing_factors) self._vel = 0
def _initialise_ac(self): self.ac_power = Button(HAL.AC_C, pull_up=True) self.ac_control = RotaryEncoder(HAL.AC_A, HAL.AC_B, maximum=30, minimum=16, initial=24, step_size=1, can_zero=False) self.ac_control.on_value_change = self.set_ac self.ac_power.when_released = self.toggle_ac self.ac_timer = threading.Timer(Config.AIRCON_DELAY_TO_SEND, self.send_ac_temp) self._mqtt_client.on_ac_temp = self.update_temp
def add_rotary_encoder(self, name, callback, pinA, pinB, io_gnd=True): '''Add encoders to listen to Arguments: - name: arbitrary name of the rotary encoder (unique) - callback: function to be called on encoder change "callback(int position, int direction)" - pinA: first io pins - pinB: second io pin - io_gnd: set to False if the encoder common pin is connected to 5v, else True if connected to GND ''' if pinA == pinB: raise ValueError("pinA and pinB can't be the same...") id = tuple(sorted((pinA, pinB))) for pair in self.rot_enc.keys(): if pair == id: self.rot_enc[pair].rot_enc.close() self.rot_enc.pop(pair) elif pinA in pair or pinB in pair: raise ValueError( "You can't share on io-pin between two rotary encoders") if name in [r.name for r in self.rot_enc.values()]: raise ValueError( "Specified name '{}' for rotary encoder is not unique..". format(name)) self.rot_enc[id] = self.Encoder( RotaryEncoder(self.gpio, callback, (pinA, pinB), io_gnd), name)
def __init__(self, menu): print("Init Programmer") # The buttons self.b1 = Button(22) self.b2 = Button(23) self.b3 = Button(24) self.b4 = Button(25) self.breturn = Button(27) # Callback handlers for buttons self.b1.when_pressed = self.callback self.b2.when_pressed = self.callback self.b3.when_pressed = self.callback self.b4.when_pressed = self.callback self.breturn.when_pressed = self.callback # The LCD display self.lcd = None # The rotary encoder self.knob = RotaryEncoder(17, 18, 4) # Which button was selected self.selected = None self.menu = menu
def __init__(self): self.fsr = ADC(Pin(34)) self.fsr.atten(ADC.ATTN_11DB) self.encoder = RotaryEncoder() self.oled = ssd1306.SSD1306_I2C( 128, 64, I2C(-1, scl=Pin(22), sda=Pin(21))) self.graphics = gfx.GFX(128, 64, self.oled.pixel) self.encoder.rotary_encoder.set(value=random.randint(-50, 50)) self.vibration = Vibration()
def _initialise_volume_control(self): self.receiver = eiscp.eISCP('192.168.1.31') self.source = 1 self.tv_mode = False self.volume_power_held = False self.button_amp_power = Button(HAL.VOL_C, pull_up=True) self.button_amp_power.hold_time = Config.BTN_HOLD_TIME self.button_amp_power.when_held = self.btn_volume_held self.button_amp_power.when_released = self.btn_volume_release self.volume_control = RotaryEncoder(HAL.VOL_A, HAL.VOL_B, maximum=60, minimum=0, initial=30, step_size=1) self.volume_control.on_clockwise = self.volume_up self.volume_control.on_counter_clockwise = self.volume_down self.btnvol_was_held = False
def __init__(self, DHT22_pin, lightsensor_pin, re_data, re_clock, re_switch, API_key, db_file, base_path): """ Setup of all the components """ self.screen = Screen() # Show info on screen to inform Pi is booting self.screen.display_text("BOOTING") self.db = Database(db_file, base_path) # self.excel = Excel(excel_file_name) self.climate = ClimateData(DHT22_pin, API_key) self.lightsensor = LightSensor(lightsensor_pin) # Setup interrupt for when light changes GPIO.add_event_detect(lightsensor_pin, GPIO.RISING, callback=self.light_changed, bouncetime=200) self.rotary = RotaryEncoder(re_data, re_clock, re_switch) # setup interrupts for rotary encoder is turned GPIO.add_event_detect(re_data, GPIO.RISING, callback=self.rotary_encoder_changed) GPIO.add_event_detect(re_clock, GPIO.RISING, callback=self.rotary_encoder_changed) GPIO.add_event_detect(re_switch, GPIO.FALLING, callback=self.rotary_encoder_clicked, bouncetime=200) # setup different pages self.pages = [] self.pages.append(PAGES.CurrentWeatherPage(self, base_path)) self.pages.append(PAGES.MinMaxTemperaturePage(self)) self.pages.append(PAGES.SettingsPage(self, base_path)) # index of the current page self.current_page = 0
def __init__(self): # hardcoded PINOUT self.sensor_left = SonicSensor(trig_pin=16, echo_pin=12, numbering_mode=GPIO.BCM) self.sensor_right = SonicSensor(trig_pin=18, echo_pin=24, numbering_mode=GPIO.BCM) self.lcd = CharLCD(numbering_mode=GPIO.BCM, cols=16, rows=2, pin_rs=21, pin_e=20, pins_data=[5,7,8,25,26,19,13,6]) self.rotary = RotaryEncoder(dt_pin=3, clk_pin=4, lower_limit=0, upper_limit=40) self.button = Button(pin=2) # parameters for filtering and smoothing # self.interval = ?? # self.window = 30 # for filters and running smoother self.threshold = 3 # for filters self.weight = .3 # for exponential smoother self.iterations = 3 # for exponential smoother self.lag = 10 # for peak detection. Probably not needed as using a simple peak detector # memory for both sensors self.raw_data_left = deque([-1]*self.window, maxlen=self.window) self.raw_data_right = deque([-1]*self.window, maxlen=self.window) self.data_left = deque([-1]*self.window, maxlen=self.window) self.data_right = deque([-1]*self.window, maxlen=self.window) # parameters and variables for tide self.initial_water_level = -1 # mean measured from past hour self.initial_median_dist = 0 # man measured distance from past readings self.current_median_dist = 0 # self.tide_window = 1001 self.points_for_median_dist = deque(maxlen=self.tide_window) # used for adding points to running average # parameters and variables for speed self.sensor_spacing = 10 # cm self.delay = .3 # time to do one iteration self.left_peak = False self.counter = -1 # used as unit of time # misc self.calibration_delay = 0 # s time used after setting water level to move sensor into place self.line2 = u'Wave: None'
def __init__(self, lcd_screen, plugin): self.lcd = lcd_screen self.rotary_encoder = RotaryEncoder(ROTARY_PIN_A, ROTARY_PIN_B, ROTARY_BUTTON, self.rotary_encoder_event) self.plugin = plugin # our example menu definition items = [ MenuItem("Favorites", [ Command( "Andrew's Mix", self.plugin.load_playlist_and_play, "spotify:user:1230911936:playlist:04OMIJJH2YSLkeVl5jhXjl") ]), DynamicMenuItem("Browse", self.plugin.menu_load_playlists, None) ] # pass all this to the base class return super(RadioMenu, self).__init__(items, self.update)
def __init__(self, platform, **kwargs): sys_clk_freq = platform.clkFreq # SoCMini (No CPU, we are controlling the SoC over UART) SoCMini.__init__(self, platform, sys_clk_freq, csr_data_width=32, ident="My first LiteX System On Chip", ident_version=True) # Clock Reset Generation self.submodules.crg = CRG(platform.request("clk29")) # No CPU, use Serial to control Wishbone bus self.submodules.serial_bridge = UARTWishboneBridge( platform.request("uart"), sys_clk_freq) self.add_wb_master(self.serial_bridge.wishbone) # FPGA identification self.submodules.dna = dna.DNA() self.add_csr("dna") # Led self.submodules.led = GPIOOut( Cat([ platform.request("green_led"), platform.request("orange_led") ])) self.add_csr("led") # Display 7 Segments self.submodules.display7Seg = SevenSegmentDisplay( sys_clk_freq, platform.request("seven_seg")) self.add_csr("display7Seg") # Encoder self.submodules.encoder = RotaryEncoder(sys_clk_freq, platform.request("encoder")) self.add_csr("encoder")
def main(): try: rotary = RotaryEncoder(dt_pin=3, clk_pin=4) rotary.start() button = Button(pin=2) lcd = CharLCD(numbering_mode=GPIO.BCM, cols=16, rows=2, pin_rs=21, pin_e=20, pins_data=[5, 7, 8, 25, 26, 19, 13, 6]) while True: if button.pressed(): break lcd.clear() lcd.write_string(u'{}'.format(rotary.get_count())) time.sleep(0.1) except KeyboardInterrupt: # Ctrl-C to terminate the program pass print("stopped at {}".format(rotary.get_count())) rotary.stop() GPIO.cleanup()
def __init__(self, platform, **kwargs): # TODO Fix the spi flash write speed in bitbang mode #sys_clk_freq = 100.295 * 1000000 sys_clk_freq = 29.498 * 1000000 SoCCore.mem_map = { "rom": 0x00000000, "sram": 0x01000000, "main_ram": 0x40000000, "spiflash": 0x60000000, "csr": 0x82000000, } # SoC with CPU SoCCore.__init__(self, platform, cpu_type="vexriscv", clk_freq=sys_clk_freq, ident="LiteX CPU Test SoC", ident_version=True, integrated_rom_size=0x4000, integrated_main_ram_size=0x2000, uart_name="uart") # Clock Reset Generation self.submodules.crg = CRG(platform.request("clk29"), ~platform.request("buttons")[3]) #self.submodules.crg = _CRG(platform, sys_clk_freq) #self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) # FPGA identification self.submodules.dna = dna.DNA() self.add_csr("dna") # SPI Flash self.submodules.spiflash = SpiFlash(platform.request("spiflash"), dummy=8, div=4, endianness="little") self.register_mem("spiflash", self.mem_map["spiflash"], self.spiflash.bus, size=2 * mB) self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", 256) self.add_constant("SPIFLASH_SECTOR_SIZE", 4096) self.add_constant("FLASH_BOOT_ADDRESS", self.mem_map['spiflash'] + 0x100000) # Led self.submodules.led = GPIOOut( Cat([ platform.request("green_led"), platform.request("orange_led") ])) self.add_csr("led") # Display 7 Segments self.submodules.display7Seg = SevenSegmentDisplay( sys_clk_freq, platform.request("seven_seg")) self.add_csr("display7Seg") # Encoder self.submodules.encoder = RotaryEncoder(sys_clk_freq, platform.request("encoder")) self.add_csr("encoder") # ST7565 Display # TODO usar o modulo spi.py do LiteX para controlar o display pela CPU displayPins = platform.request("spi_display") self.submodules.display = St7565Display(sys_clk_freq, displayPins) self.add_csr("display")
class OceanMonitor: def __init__(self): # hardcoded PINOUT self.sensor_left = SonicSensor(trig_pin=16, echo_pin=12, numbering_mode=GPIO.BCM) self.sensor_right = SonicSensor(trig_pin=18, echo_pin=24, numbering_mode=GPIO.BCM) self.lcd = CharLCD(numbering_mode=GPIO.BCM, cols=16, rows=2, pin_rs=21, pin_e=20, pins_data=[5,7,8,25,26,19,13,6]) self.rotary = RotaryEncoder(dt_pin=3, clk_pin=4, lower_limit=0, upper_limit=40) self.button = Button(pin=2) # parameters for filtering and smoothing # self.interval = ?? # self.window = 30 # for filters and running smoother self.threshold = 3 # for filters self.weight = .3 # for exponential smoother self.iterations = 3 # for exponential smoother self.lag = 10 # for peak detection. Probably not needed as using a simple peak detector # memory for both sensors self.raw_data_left = deque([-1]*self.window, maxlen=self.window) self.raw_data_right = deque([-1]*self.window, maxlen=self.window) self.data_left = deque([-1]*self.window, maxlen=self.window) self.data_right = deque([-1]*self.window, maxlen=self.window) # parameters and variables for tide self.initial_water_level = -1 # mean measured from past hour self.initial_median_dist = 0 # man measured distance from past readings self.current_median_dist = 0 # self.tide_window = 1001 self.points_for_median_dist = deque(maxlen=self.tide_window) # used for adding points to running average # parameters and variables for speed self.sensor_spacing = 10 # cm self.delay = .3 # time to do one iteration self.left_peak = False self.counter = -1 # used as unit of time # misc self.calibration_delay = 0 # s time used after setting water level to move sensor into place self.line2 = u'Wave: None' ''' A control loop in which user uses the rotary encoder to set the initial water level ''' def set_initial_distance(self): self.rotary.start() self.lcd.clear() while self.rotary.get_count() == 0: self.lcd.clear() self.lcd.write_string(u'Use dial to set water level ') time.sleep(2) self.lcd.clear() self.lcd.write_string(u'press button when set') time.sleep(1.5) while True : if self.button.pressed(): break self.lcd.clear() self.lcd.write_string(u'{} cm'.format(self.rotary.get_count()*10)) time.sleep(0.1) self.rotary.stop() self.initial_water_level = self.rotary.get_count()*10 self.lcd.clear() self.lcd.write_string('Set level to {} cm'.format(self.initial_water_level)) ''' a function that uses dsp on the collected data to filter outliers and smooth points ''' ''' Uses the number of iterations, spacing and delay of iteration to get the speed between two detected peaks ''' def __calc_speed(self): return self.sensor_spacing / (self.counter*self.delay) # cm/s ''' maintains a current water level using a windowed average ''' def __update_median_dist(self, point1, point2): self.points_for_median_dist.append(point1) self.points_for_median_dist.append(point2) self.current_median_dist = np.median(self.points_for_median_dist) ''' calulates the tide form the initial water level and the current mean ''' def __get_tide(self): #print(self.initial_water_level , self.initial_median_dist , self.current_median_dist) return self.initial_water_level + self.initial_median_dist - self.current_median_dist ''' An iteration of the main control loop. Samples both sensors and reports if a wave has been detected the speed of an earlier detected wave or the tide as no waves have been detected ASSUMPUTIONS MADE: a wave travels from left to right a waves peak and trough will not both pass the left sensor before the first passes the right sensor ''' ''' TODO: spin loops for synchronus behavior: max delay before left read max delay for read max delay before right read max delay for read max delay after right read ''' def __iteration(self): # if there are no current waves detected then report tide # get data from left sensor self.raw_data_left.append( self.sensor_left.get_distance() ) # perform outlier check self.data_left.append( rolling_median_filter_last_point(np.array(self.raw_data_left), threshold=self.threshold, replace_with=self.data_left[-1]) ) # smooth on checked data clean_data_left = exponential_filter(self.data_left, weight=self.weight, iterations=self.iterations) # check if the previous was a peak was_previous_a_peak_left = recent_peak(clean_data_left, lag=self.lag) #print was_previous_a_peak_left, #print self.raw_data_left[-1], #print self.data_left[-1], clean_data_left[-1], #print np.median(clean_data_left), self.current_median_dist #print (np.std(clean_data_left), clean_data_left[-2], np.median(clean_data_left)) #for d in clean_data_left: # print '{0:.2f},'.format(d), #print line1 = u'Tide: {0:5.1f} cm '.format(self.__get_tide()) if (was_previous_a_peak_left == -1): # it was a trough in the measurement then it is a wave peak if abs(clean_data_left[-self.lag-1]-self.current_median_dist) > 5: #for d in clean_data_left: # print '{0:.2f},'.format(d), #print self.prev_peak_dist = clean_data_left[-2] # inform the world self.line2 = u'Wave: {0:5.1f} cm'.format(self.current_median_dist-clean_data_left[-self.lag-1]) self.counter = 1 self.left_peak = True else: pass #wave was too small, probably not a real wave self.lcd.clear() self.lcd.write_string(line1+self.line2) # get data from right sensor self.raw_data_right.append( self.sensor_right.get_distance() ) # perform outlier check self.data_right.append( rolling_median_filter_last_point(np.array(self.raw_data_right), threshold=self.threshold, replace_with=self.data_right[-1]) ) # smooth on checked data clean_data_right = exponential_filter(self.data_right, weight=self.weight, iterations=self.iterations) # check if the previous was a peak was_previous_a_peak_right = recent_peak(clean_data_right, lag=self.lag) if (was_previous_a_peak_right == -1 and self.left_peak): speed = self.__calc_speed() self.line2 = u'Wave: {0:5.1f} cm/s'.format(self.counter) self.left_peak = False self.__update_median_dist(clean_data_left[-1], clean_data_right[-1]) self.counter += 1 ''' setups and runs the the sensor ''' def run(self): try: # initial distance setting print('setting initial distance') self.set_initial_distance() # delay calibration print('delaying calibration') for i in range(self.calibration_delay): self.lcd.clear() self.lcd.write_string('calibrating in {}'.format(self.calibration_delay-i)) time.sleep(1) # fill the queues withdata print('calibrating') self.lcd.clear() self.lcd.write_string('CALIBRATING: ignore LCD out') time.sleep(1) for i in range(100): self.__iteration() self.initial_median_dist = self.current_median_dist self.lcd.clear() self.lcd.write_string('CALIBRATING: Done!') self.line2 = u'Wave: None' time.sleep(1) # run main event loop print('running') while True: self.__iteration() #time.sleep(1) except KeyboardInterrupt: pass GPIO.cleanup()
ROTARY_PIN_BUTTON = 13 LED_PINS = [ 5, 6, 13, 19, 26 ] # 29, 31, 33, 35, 37 LED_ARRAY = [ [ 1, 2 ], [ 2, 1 ], [ 2, 3 ], [ 3, 2 ], [ 1, 3 ], [ 3, 1 ], [ 0, 2 ], [ 2, 0 ], [ 0, 3 ], [ 3, 0 ], [ 0, 1 ], [ 1, 0 ], [ 0, 4 ], [ 4, 0 ], [ 1, 4 ], [ 4, 1 ], [ 2, 4 ], [ 4, 2 ], [ 3, 4 ], [ 4, 3 ] ] if __name__ == "__main__": print "start" initial_percentage = 0 counter = Counter(initial_percentage) light_array = LightArray(LED_PINS, LED_ARRAY) def on_turn(delta): counter.count(delta) print counter.percentage def on_click(value): print("Button Press") def on_exit(a, b): print("Exiting...") encoder.destroy() sys.exit(0) encoder = RotaryEncoder(ROTARY_PIN_A, ROTARY_PIN_B, callback=on_turn, buttonPin=ROTARY_PIN_BUTTON, buttonCallback=on_click) signal.signal(signal.SIGINT, on_exit) while True: light_array.set_value(counter.percentage)
growth_sw_pin = 27 decay_clk_pin = 22 decay_dt_pin = 23 decay_sw_pin = 24 # Connect to MQTT broker client = mqtt.Client() print("Connecting to MQTT broker..") client.connect(mqtt_broker_addr, mqtt_port, 60) print("..connected") # Start listening to both Rotary Encoders in parallel growth_rotary_encoder = RotaryEncoder(client, "growth_rate", growth_clk_pin, growth_dt_pin, growth_sw_pin) growth_rotary_listener = Process(target=growth_rotary_encoder.listen) growth_rotary_listener.start() decay_rotary_encoder = RotaryEncoder(client, "decay_rate", decay_clk_pin, decay_dt_pin, decay_sw_pin) decay_rotary_listener = Process(target=decay_rotary_encoder.listen) decay_rotary_listener.start() # Set up pi camera with picamera.PiCamera() as camera: camera.resolution = (res_width, res_height) camera.start_preview() time.sleep(2)
def set_speed(self, speed): if speed >= 0: self._set_dir(self._forward) else: self._set_dir(self._forward ^ 1) self._set_pwm(abs(speed)*motor_pwm_range) if __name__ == "__main__": import time from rotary_encoder import RotaryEncoder from parameters import left_pins, right_pins left_motor = Motor(left_pins['pwm'], left_pins['dir'], 0) right_motor = Motor(right_pins['pwm'], right_pins['dir'], 1) left_enc = RotaryEncoder(left_pins['a'], left_pins['b']) right_enc = RotaryEncoder(right_pins['a'], right_pins['b']) base_speed = 20 for speed in range(0, base_speed + 1, 1): left_motor.set_speed(speed/100.0) right_motor.set_speed(speed/100.0) time.sleep(0.1) limit_speed = 40 time.sleep(1) try: while True: for speed in range(base_speed, limit_speed + 1, 1): left_motor.set_speed(speed/100.0) right_motor.set_speed(speed/100.0) time.sleep(0.1)
class WeatherStation: """ Facade class for all functionality of the weather station """ def __init__(self, DHT22_pin, lightsensor_pin, re_data, re_clock, re_switch, API_key, db_file, base_path): """ Setup of all the components """ self.screen = Screen() # Show info on screen to inform Pi is booting self.screen.display_text("BOOTING") self.db = Database(db_file, base_path) # self.excel = Excel(excel_file_name) self.climate = ClimateData(DHT22_pin, API_key) self.lightsensor = LightSensor(lightsensor_pin) # Setup interrupt for when light changes GPIO.add_event_detect(lightsensor_pin, GPIO.RISING, callback=self.light_changed, bouncetime=200) self.rotary = RotaryEncoder(re_data, re_clock, re_switch) # setup interrupts for rotary encoder is turned GPIO.add_event_detect(re_data, GPIO.RISING, callback=self.rotary_encoder_changed) GPIO.add_event_detect(re_clock, GPIO.RISING, callback=self.rotary_encoder_changed) GPIO.add_event_detect(re_switch, GPIO.FALLING, callback=self.rotary_encoder_clicked, bouncetime=200) # setup different pages self.pages = [] self.pages.append(PAGES.CurrentWeatherPage(self, base_path)) self.pages.append(PAGES.MinMaxTemperaturePage(self)) self.pages.append(PAGES.SettingsPage(self, base_path)) # index of the current page self.current_page = 0 def update(self): """ Update all weather station data """ # update outside weather self.weather_hour, self.outside_temp, self.icon = self.climate.get_outside_weather( ) # update inside data self.inside_humid, self.inside_temp = self.climate.get_inside_data() # update today's forecast data self.coldest, self.hottest = self.climate.get_min_max() # update day & time of WeatherStation data with current day & time now = datetime.datetime.now() self.day = now.date() self.hour = now.time() print("Weather station updated at: {} {}".format(self.hour, self.day)) def light_changed(self, pin): """ interrupt handler for when a light change has been detected""" time.sleep(0.1) # if it's light in the room, wake up screen if self.lightsensor.is_light(): if self.screen.is_sleeping(): self.screen.wake_up() print("Woke up screen") # update screen with latest info self.update_screen() # If the screen is not sleeping, put it in sleep mode else: if not self.screen.is_sleeping(): self.screen.go_to_sleep() print("Put screen to sleep") def update_screen(self): """ update information on the screen with current weather station data. WeatherStation should be updated first with update() """ self.pages[self.current_page].update() def rotary_encoder_changed(self, channel): result = self.rotary.read(channel) # current page object page = self.pages[self.current_page] # show next page if result == 1: # if the current page is not browsing its sub pages, go to next main page if page.current_page == None: # if the index is at the last page, loop back to first page if self.current_page == len(self.pages) - 1: self.current_page = 0 else: self.current_page += 1 print("Main page up") # if the current page is browsing its sub pages, go to next subpage else: # if the index is at the last page, loop back to first page if page.current_page == len(page.pages) - 1: page.current_page = 0 else: page.current_page += 1 print("Sub page up") # show previous page elif result == -1: # if the current page is not browsing its sub pages, go to previous main page if page.current_page == None: # if the index is at the first page, loop back to last page if self.current_page == 0: self.current_page = len(self.pages) - 1 else: self.current_page -= 1 print("Main page down") # if the current page is browsing its sub pages, go to previous subpage else: # if the index is at the last page, loop back to last page if page.current_page == 0: page.current_page = len(page.pages) - 1 else: page.current_page -= 1 print("Sub page down") self.update_screen() def rotary_encoder_clicked(self, channel): """ directs the click to a handler method of the current page and updates screen """ self.pages[self.current_page].click() self.pages[self.current_page].update() def log_to_db(self): """ Log the current weather station data to the database WeatherStation should be updated first with update() """ # log data to Excel # self.excel.write_to_excel(self.day, self.hour, self.weather_hour, self.outside_temp, self.inside_temp, self.inside_humid) # log data to SQLite database reading = (self.day, str(self.hour), str(self.weather_hour), self.outside_temp, self.inside_temp, self.inside_humid) self.db.add_reading(reading) def is_light(self): return self.lightsensor.is_light()
def handle_delta(delta): counter.count(delta) light_array.set_value(counter.percentage) print counter.percentage def on_click(value): print("Button click") if use_ensign: update_flag(percentage=counter.percentage, **vars(args)) def on_exit(a, b): print("Exiting...") encoder.destroy() sys.exit(0) encoder = RotaryEncoder(GPIO_A, GPIO_B, callback=on_turn, buttonPin=13, buttonCallback=on_click) signal.signal(signal.SIGINT, on_exit) while True: # This is the best way I could come up with to ensure that this script # runs indefinitely without wasting CPU by polling. The main thread will # block quietly while waiting for the event to get flagged. When the knob # is turned we're able to respond immediately, but when it's not being # turned we're not looping at all. # # The 1200-second (20 minute) timeout is a hack; for some reason, if I # don't specify a timeout, I'm unable to get the SIGINT handler above to # work properly. But if there is a timeout set, even if it's a very long # timeout, then Ctrl-C works as intended. No idea why. EVENT.wait(1200) consume_queue()
""" # Import classes from button import Button from linear_actuator import LinearActuator from load_cell_amplifier import LoadCellAmplifier from load_cell import LoadCell from motor import Motor from rotary_encoder import RotaryEncoder import multiprocessing # Initialize objects motor = Motor(20, 21) linear_actuator = LinearActuator(motor) rotary_encoder = RotaryEncoder(9, 11, 10) load_cell_amplifier = LoadCellAmplifier(5, 6) load_cell = LoadCell(load_cell_amplifier) # Initialize buttons up_button = Button(27, linear_actuator.move_up) down_button = Button(17, linear_actuator.move_down) stop_button = Button(2, linear_actuator.stop) inc_speed_button = Button(7, linear_actuator.increase_speed) dec_speed_button = Button(3, linear_actuator.decrease_speed) # Initialize limit switches bottom_limit_switch = Button(19, linear_actuator.stop) top_limit_switch = Button(26, linear_actuator.stop) # Run load cell and rotary encoder in separate processes
class Coordinator: ########## Constructor ########## def __init__(self): self.ac_on = False self._init_logger() self._init_neopixel() self._init_ir() self._init_mqtt() self._init_lock() self._init_rfid() self._initialise_volume_control() self._initialise_ac() self._initialise_brightness_control() self._init_buttons() self._mqtt_client.send_message("boot", "started") self.strip.set_mode(Effects.RGB) ########## Logger ########## def _init_logger(self): self.formatter = logging.Formatter( fmt='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') self.handler = RotatingFileHandler( filename='/home/pi/app/coffee_table.log', mode='a', maxBytes=20 * 1024 * 1024, backupCount=2, encoding=None, delay=0) self.handler.setFormatter(self.formatter) self.logger = logging.getLogger("coffee_table") self.logger.setLevel(logging.DEBUG) self.logger.addHandler(self.handler) self.logger.debug("Starting coordinator Service") ########## Lock ########## def _init_lock(self): self.lock = OutputDevice(HAL.LOCK) self.lock.off() def open_lock(self, time_s): self.strip.pause() self.lock.on() threading.Timer(time_s, self.close_lock).start() def close_lock(self): self.lock.off() self.strip.unpause() ########## RFID Reader ########## def _init_rfid(self): self._reader = RFID(self.logger) self._reader.on_tag = lambda sender, tag: self._mqtt_client.send_message( "tags", tag) self._reader.start() ########## IR ########## def _init_ir(self): self.comms = Comms() self.device_state_tv = False self.device_state_amp = False self.remote = Remote(1, Config.REMOTE_AMP, self.logger, self.comms) def turn_on_devices(self): if not self.device_state_tv: self.remote.press_button(Key.TV_POWER, 1) self.device_state_tv = not self.device_state_tv if not self.device_state_amp: self.remote.press_button(Key.AMP_POWER, 1) self.device_state_amp = not self.device_state_amp ########## Room Lights ########## def _initialise_brightness_control(self): self.lights_held = False self.sine = Sine() self.rgb_mode_timer = threading.Timer(Config.RGB_MODE_TIMER, self.leave_rgb_mode) self.lights_tx_timer = threading.Timer(Config.LIGHTS_DELAY_TO_SEND, self.lights_send_brightness) self.lights_are_on = True self.brightness = 0xFF self.rgb_long = 0x00FFFFFF self.brightness_control = RotaryEncoder(HAL.LIGHTS_A, HAL.LIGHTS_B, maximum=255, minimum=0, initial=255, step_size=5) self.brightness_control.on_clockwise = self.brightness_up self.brightness_control.on_counter_clockwise = self.brightness_down self._mqtt_client.on_rgb = self.on_rgb_message self.btn_lights = Button(HAL.LIGHTS_C, pull_up=True) self.btn_lights.hold_time = Config.BTN_HOLD_TIME self.btn_lights.when_held = self.enter_rgb_mode self.btn_lights.when_released = self.toggle_lights self.rgb_angle = 0 def brightness_up(self): self.strip.set_temperature(self.brightness_control.percent()) self.lights_tx_timer.cancel() self.lights_tx_timer = threading.Timer(Config.LIGHTS_DELAY_TO_SEND, self.lights_send_brightness) self.lights_tx_timer.start() def brightness_down(self): self.strip.set_temperature(self.brightness_control.percent()) self.lights_tx_timer.cancel() self.lights_tx_timer = threading.Timer(Config.LIGHTS_DELAY_TO_SEND, self.lights_send_brightness) self.lights_tx_timer.start() def rgb_angle_changed(self): self.rgb_angle = self.brightness_control.value self.colour_picker = self.sine.get_triangle(self.rgb_angle * Config.DEGREES_PER_CLICK) self.strip.pixels.fill(self.colour_picker) self.strip.pixels.show() self.lights_tx_timer.cancel() self.lights_tx_timer = threading.Timer(Config.LIGHTS_DELAY_TO_SEND, self.lights_send_rgb) self.lights_tx_timer.start() self.rgb_mode_timer.cancel() self.rgb_mode_timer = threading.Timer(Config.RGB_MODE_TIMER, self.leave_rgb_mode) self.rgb_mode_timer.start() def lights_send_brightness(self): print("Updating Brightness") self._mqtt_client.send_message("lights/brightness", format(self.brightness_control.value)) def lights_send_rgb(self): string = ",".join(str(x) for x in self.colour_picker) print("Updating RGB") self._mqtt_client.send_message("lights/rgb", string) def enter_rgb_mode(self): self.lights_held = True self.strip.set_mode(Effects.RGB) self.strip.blink(0, 0, 255) self.rgb_mode_timer.cancel() print("RGB Mode") self.strip.set_brightness(1) self.brightness_control.loop = True self.brightness_control.maximum = round( 360 / Config.DEGREES_PER_CLICK) - 1 self.brightness_control.step = 1 self.brightness_control.value = self.rgb_angle self.brightness_control.on_clockwise = None self.brightness_control.on_counter_clockwise = None self.brightness_control.on_value_change = self.rgb_angle_changed self.rgb_mode_timer.cancel() self.rgb_mode_timer = threading.Timer(Config.RGB_MODE_TIMER, self.leave_rgb_mode) self.rgb_mode_timer.start() def leave_rgb_mode(self): self.rgb_mode_timer.cancel() print("Normal Mode") self.brightness_control.loop = False self.brightness_control.maximum = 255 self.brightness_control.step = 5 self.brightness_control.value = 255 self.brightness_control.on_clockwise = self.brightness_up self.brightness_control.on_counter_clockwise = self.brightness_down self.brightness_control.on_value_change = None self.rgb_mode_timer.cancel() self.strip.restore() def toggle_lights(self): if (self.lights_held): self.lights_held = False return self._mqtt_client.send_message("lights/brightness", "toggle") def on_rgb_message(self, r, g, b): self.strip.set_colour(r, g, b, transient=False, dim_after=5) ########## Neopixel ########## def _init_neopixel(self): self.strip = Indicator(HAL.WS2812B_DATA, 55) self.strip.set_mode(Effects.CYLON) self.effect = 1 def cycle_effect(self): if self.effect == 0: self.strip.set_mode(Effects.RGB) if self.effect == 1: self.strip.set_mode(Effects.FIRE) if self.effect == 2: self.strip.set_mode(Effects.METEOR) if self.effect == 3: self.strip.set_mode(Effects.CYLON) if self.effect == 4: self.strip.set_mode(Effects.RGB) self.strip.set_colour(40, 0, 0, False) if self.effect == 5: self.strip.set_mode(Effects.RGB) self.strip.set_colour(0, 40, 0, False) if self.effect == 6: self.strip.set_mode(Effects.RGB) self.strip.set_colour(0, 0, 40, False) self.effect = -1 self.effect += 1 ########## Volume ########## def _initialise_volume_control(self): self.receiver = eiscp.eISCP('192.168.1.31') self.source = 1 self.tv_mode = False self.volume_power_held = False self.button_amp_power = Button(HAL.VOL_C, pull_up=True) self.button_amp_power.hold_time = Config.BTN_HOLD_TIME self.button_amp_power.when_held = self.btn_volume_held self.button_amp_power.when_released = self.btn_volume_release self.volume_control = RotaryEncoder(HAL.VOL_A, HAL.VOL_B, maximum=60, minimum=0, initial=30, step_size=1) self.volume_control.on_clockwise = self.volume_up self.volume_control.on_counter_clockwise = self.volume_down self.btnvol_was_held = False def btn_volume_held(self): self.btnvol_was_held = True self.strip.blink(0, 0, 255) def btn_volume_release(self): if not self.btnvol_was_held: self._mqtt_client.send_message("amp", "short") else: self._mqtt_client.send_message("amp", "long") self.btnvol_was_held = False def switch_mode(self): self.tv_mode = not self.tv_mode def volume_up(self): self.strip.set_temperature(self.volume_control.percent()) self.receiver.send('MVLUP') def volume_down(self): self.strip.set_temperature(self.volume_control.percent()) self.receiver.send('MVLDOWN') ########## Aircon ########## def _initialise_ac(self): self.ac_power = Button(HAL.AC_C, pull_up=True) self.ac_control = RotaryEncoder(HAL.AC_A, HAL.AC_B, maximum=30, minimum=16, initial=24, step_size=1, can_zero=False) self.ac_control.on_value_change = self.set_ac self.ac_power.when_released = self.toggle_ac self.ac_timer = threading.Timer(Config.AIRCON_DELAY_TO_SEND, self.send_ac_temp) self._mqtt_client.on_ac_temp = self.update_temp def update_temp(self, temp): self.ac_control.value = int(temp) self.strip.set_temperature(self.ac_control.percent()) def set_ac(self): self.strip.set_temperature(self.ac_control.percent()) self.ac_timer.cancel() self.ac_timer = threading.Timer(Config.AIRCON_DELAY_TO_SEND, self.send_ac_temp) self.ac_timer.start() def send_ac_temp(self): self._mqtt_client.send_message("ac/set_temp", format(self.ac_control.value)) def toggle_ac(self): self._mqtt_client.send_message("btnAC", "click") ########## Buttons ########## def _init_buttons(self): self.btn1 = Button(HAL.BTN1, pull_up=True) self.btn1.when_held = self.btn1_held self.btn1.when_released = self.btn1_release self.btn1_was_held = False self.btn2 = Button(HAL.BTN2, pull_up=True) self.btn2.when_held = self.btn2_held self.btn2.when_released = self.btn2_release self.btn2_was_held = False self.btn3 = Button(HAL.BTN3, pull_up=True) self.btn3.when_held = self.btn3_held self.btn3.when_released = self.btn3_release self.btn3_was_held = False self.btn4 = Button(HAL.BTN4, pull_up=True) self.btn4.when_held = self.btn4_held self.btn4.when_released = self.btn4_release self.btn4_was_held = False self.btn5 = Button(HAL.BTN5, pull_up=True) self.btn5.when_held = self.btn5_held self.btn5.when_released = self.btn5_release self.btn5_was_held = False self.btn6 = Button(HAL.BTN6, pull_up=True) self.btn6.when_held = self.btn6_held self.btn6.when_released = self.btn6_release self.btn6_was_held = False # LED Fun def btn1_held(self): self.btn1_was_held = True self._mqtt_client.send_message("btn1", "hold") self.strip.blink(0, 0, 255) def btn1_release(self): if not self.btn1_was_held: self._mqtt_client.send_message("btn1", "click") self.cycle_effect() self.btn1_was_held = False # Button 2 def btn2_held(self): self.btn2_was_held = True self._mqtt_client.send_message("btn2", "hold") self.strip.blink(0, 0, 255) def btn2_release(self): if not self.btn2_was_held: self._mqtt_client.send_message("btn2", "click") print("Btn2 released") self.btn2_was_held = False def btn3_held(self): self.btn3_was_held = True self._mqtt_client.send_message("btn3", "hold") self.strip.blink(0, 0, 255) def btn3_release(self): if not self.btn3_was_held: self._mqtt_client.send_message("btn3", "click") print("Btn3 released") self.btn3_was_held = False def btn4_held(self): self.btn4_was_held = True self._mqtt_client.send_message("btn4", "hold") self.strip.blink(0, 0, 255) def btn4_release(self): if not self.btn4_was_held: self._mqtt_client.send_message("btn4", "click") print("Btn4 released") self.btn4_was_held = False #Play/Pause TV def btn5_held(self): self.btn5_was_held = True self._mqtt_client.send_message("btn5", "hold") self.strip.blink(0, 0, 255) def btn5_release(self): if not self.btn5_was_held: self._mqtt_client.send_message("btn5", "click") print("Btn5 released") self.btn5_was_held = False # PC On/Off def btn6_held(self): self.btn6_was_held = True self._mqtt_client.send_message("btn6", "hold") self.strip.blink(0, 0, 255) def btn6_release(self): if not self.btn6_was_held: self._mqtt_client.send_message("btn6", "click") print("Btn6 released") self.btn6_was_held = False ########## Command Handler ########## def handle_command(self, command): if command == "unlock": self.open_lock(Config.OPEN_LOCK_TIME) elif command == "lock": self.lock.off() elif command == "fire": self.strip.set_mode(Effects.FIRE) elif command == "cylon": self.strip.set_mode(Effects.CYLON) elif command == "stop_rgb": self.strip.set_mode(Effects.RGB) self.strip.set_colour(0, 10, 0, False) elif command == "devices_on": self.turn_on_devices() elif command == "source_cd": self.remote.press_button(Key.AMP_CD, 1) self.source = 2 elif command == "source_video1": self.remote.press_button(Key.AMP_VIDEO1, 1) self.source = 3 elif command == "source_video2": self.remote.press_button(Key.AMP_VIDEO2, 1) self.source = 4 elif command == "source_aux": self.remote.press_button(Key.AMP_AUX, 1) self.source = 1 elif command == "amp_power": self.remote.press_button(Key.AMP_POWER, 1) elif command == "tv_power": self.remote.press_button(Key.TV_POWER, 1) elif command == "pause": self.remote.press_button(Key.TV_PAUSE, 1) elif command == "play": self.remote.press_button(Key.TV_PLAY, 1) else: self.logger.debug("unrecognized command: " + command) ########## MQTT ########## def _init_mqtt(self): self._mqtt_client = MQTT(secrets.mqtt_broker, secrets.mqtt_port, secrets.mqtt_user, secrets.mqtt_pass, self.logger) self._mqtt_client.start() while self._mqtt_client.connected != True: time.sleep(0.1) self._mqtt_client.send_message("buttons", "Running") self._mqtt_client.send_message("lights/lounge", "update") self._mqtt_client.on_command = self.handle_command ########## Main ########## def run(self): try: pause() except KeyboardInterrupt: self._reader.stop() self._mqtt_client.stop() self.logger.info("App closing")
def move(self, step): self.current_index += step if self.current_index >= len(self.menu_items): self.current_index = 0 elif self.current_index < 0: self.current_index = len(self.menu_items) - 1 print "current index: %i" % self.current_index self.menu_items[self.current_index]() if __name__ == "__main__": rotary_btn = gpiozero.Button(6) rc = RotaryEncoder(19, 13) ui = Sensor_UI() rc.when_rotated = ui.rotary_changed while True: time.sleep(0.01) # ui.identify() # rotary_btn.wait_for_press() # ui.show_temp()