class Button: def __init__(self, pin): from machine import Pin self.pin = Pin(pin, Pin.IN) def get_presses(self, delay = 1): last_time, last_state, presses = time.time(), 0, 0 while time.time() < last_time + delay: time.sleep_ms(50) if last_state == 0 and self.pin.value() == 1: last_state = 1 if last_state == 1 and self.pin.value() == 0: last_state, presses = 0, presses + 1 return presses def is_pressed(self): return self.pin.value() == 0 def was_pressed(self): last_state = self.pin.value() time.sleep_ms(15) if last_state == 1 and self.pin.value() == 0: return True return False def irq(self, handler, trigger): self.pin.irq(handler = handler, trigger = trigger)
def activate(state): global inPin if(state): inPin = Pin(12, Pin.IN, Pin.PULL_UP) inPin.irq(trigger=Pin.IRQ_RISING, handler=timeUS) # Disables the internal pull-up, therefore preventing any further RISING_EDGE case. else: inPin = Pin(12, Pin.IN)
class PulseCounter: def __init__(self, pin, value=0): # value is in cents self.pin = Pin(pin, mode=Pin.IN) self.value = value self.count = 0 self.total = 0 self.int = self.pin.irq(handler=self._count, trigger=Pin.IRQ_FALLING, priority=7) def _count(self, pin): self.count += 1 self.total += self.value
class PulseCounter: def __init__(self, pin, pull, trigger, debounce_ms): self._pin = Pin(pin, mode=Pin.IN, pull=pull) self._debounce_ms = debounce_ms self._last_count_ms = time.ticks_ms() self._irq = self._pin.irq(trigger=trigger, handler=self._handler) self.counter = 0 def _handler(self, pin): time_ms = time.ticks_ms() if (time_ms - self._last_count_ms > self._debounce_ms): self.counter += 1 self._last_count_ms = time_ms
class Trigger_Monitor(object): ''' Is there a way to change the callback? ''' def __init__(self): # OUTPUT/INPUT self.pins = ['GP16', 'GP13'] self.outputPin = Pin(self.pins[0], mode=Pin.OUT, value=1) self.inputPin = Pin(self.pins[1], mode=Pin.IN, pull=Pin.PULL_UP) self.triggerCount = 0 self._triggerType_ = Pin.IRQ_RISING self.inputIRQ = self.inputPin.irq(trigger=self._triggerType_, handler=self.pinHandler) self.irqState = True def toggleInput(self, time_ms = 5): self.outputPin.toggle() time.sleep_ms(time_ms) def pinHandler(self, pin_o): # global self.pin_irq_count_trigger # global self.pin_irq_count_total # self._triggerType_ # if self._triggerType_ & self.inputIRQ.flags(): # self.pin_irq_count_trigger += 1 self.triggerCount += 1 def getTriggerCount(self): print("Trigger Count: ", self.triggerCount) def resetTriggerCount(self): self.triggerCount = 0 def disableIRQ(self): self.irqState = machine.disable_irq() # Start of critical section def reEnableIRQ(self): machine.enable_irq(True) self.irqState=True
# Complete project details at https://RandomNerdTutorials.com from machine import Pin import machine, neopixel, time # define interrupt handling functions def button_handler(pin): global button_pressed button_pressed = pin # configure pushbuttons as interrupts button1 = Pin(15, Pin.IN) button1.irq(trigger=Pin.IRQ_RISING, handler=button_handler) button2 = Pin(14, Pin.IN) button2.irq(trigger=Pin.IRQ_RISING, handler=button_handler) button3 = Pin(12, Pin.IN) button3.irq(trigger=Pin.IRQ_RISING, handler=button_handler) button4 = Pin(13, Pin.IN) button4.irq(trigger=Pin.IRQ_RISING, handler=button_handler) button_pressed = button1 # LED strip configuration # number of pixels n = 48 # strip control gpio p = 5 np = neopixel.NeoPixel(machine.Pin(p), n) # FUNCTIONS FOR LIGHTING EFFECTS # bounce
#Hardware Platform: FireBeetle-ESP32 #Result: button controls LED ON/OFF. #Hardware Connection: this test needs to connect to an external button module in IO27 and an external LED module in IO25. #The info below shows that irq is available for the current version. # button:IO2 IO4 IO5 IO10 IO12~19 IO23 IO25 # IO26 IO27 IO34 IO35 IO36 IO39 # led: IO0 IO4 IO10 IO12~19 IO21~23 IO25~27 #Except the connection between IO2 and onboard LED, other pins need to connect to external LEDs. from machine import Pin import time import machine value = 1 counter = 0 def func(v): global value, counter time.sleep_ms(50) if (button.value() == 0): #When the button is not pressed, return return while (button.value() == 1 ): #If press the button, it will wait until released time.sleep_ms(100) time.sleep_ms(100) counter += 1 led.value(value) #Set LED value value = 0 if value else 1 #If LED is turn on,it will be shutdown next,otherwise if will turn on next. print("IRQ ", counter) try: led = Pin(25, Pin.OUT) #create LED object from pin25,Set Pin25 to output
is_apmode = 1 print('Wifi_Boot Error') else: try: update_time, ntp_time = time_config() mode = 2 c_error = False is_apmode = 0 print('No Problem in Boot') except: c_error = True mode = 1 is_apmode = 1 print('NTP Get Error') if is_boot == 0: sw1.irq(trigger=Pin.IRQ_FALLING, handler=callback_sw1) sw2.irq(trigger=Pin.IRQ_FALLING, handler=callback_sw2) tim.init(period=1000, mode=Timer.PERIODIC, callback=callback_disp) is_boot = 1 print('is_boot is set') #void loop while True: if is_apmode == 1: for i in range(0, 10): np[i] = (0, 0, 0) np.write() ###AP Mode Activate### print('ap_mode Activating.......') lcd_clear() lcd_write(' AP MODE')
#right button Button2_Pin = 0 #left button button1 = Pin(Button1_Pin, Pin.IN, Pin.PULL_UP) button2 = Pin(Button2_Pin, Pin.IN, Pin.PULL_UP) def callback_b1(p): clear_screen() def callback_b2(p): fill_random_color() button1.irq(trigger=Pin.IRQ_FALLING, handler=callback_b1) #interrupt for right button (button 2) button2.irq(trigger=Pin.IRQ_FALLING, handler=callback_b2) #interrupt for left button (button 1) BLK = Pin(BL_Pin, Pin.OUT) spi = SPI(baudrate=40000000, miso=Pin(MISO_Pin), mosi=Pin(MOSI_Pin, Pin.OUT), sck=Pin(SCLK_Pin, Pin.OUT)) display = st7789.ST7789(spi, 135, 240, cs=Pin(CS_Pin), dc=Pin(DC_Pin), rst=None)
global interrupt_pin interrupt_pin = pin motion_led.value(1) def handleInterrupt4(pin): global motion motion = False global motiontmr motiontmr = time.time() global interrupt_pin interrupt_pin = pin motion_led.value(0) motion_pir.irq(trigger=Pin.IRQ_RISING, handler=handleInterrupt3) #otion_pir.irq(trigger=Pin.IRQ_HIGH_LEVEL, handler=handleInterrupt3) #motion_pir.irq(trigger=Pin.IRQ_FALLING,handler=handleInterrupt4) if __name__ == '__main__': ## setup RTC and sychronize with NTP servers rtc = machine.RTC() ntptime.host = '192.168.1.118' try: ntptime.settime() flg = True print("time set with ntp sync") except: print("error with ntp sync")
class Button: def __init__(self, port): self.p = getPin(port) if self.p[0] == None: return self.last_time = runtime() self.last_state = 0 self.number = 0 self.ButtonTaskList = {} self.his = [] self.button = Pin(self.p[0], Pin.IN, Pin.PULL_DOWN) self.button.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=self._handler) loop = asyncio.get_event_loop() loop.create_task(Cancellable(self._async_handler)()) def event(self, type, time, function): function_name = str(type) + str(time) if not callable(function): print('btn-event->Function cant be call') return self.ButtonTaskList[function_name] = function def _handler(self, source): state = self.button.value() now = runtime() if state == self.last_state: return self.last_state = state self.his.append(runtime()) if len(self.his) < 2: return if self.his[-1] - self.his[-2] > 500: print('hold for ', (self.his[-1] - self.his[-2]) // 1000, 'seconds') self.execute('hold', (self.his[-1] - self.his[-2]) // 1000) self.his.clear() @cancellable async def _async_handler(self): while True: await asyncio.sleep_ms(500) if self.button.value() == 0: if len(self.his) and (runtime() - self.his[-1]) > 500: print('pressed ', len(self.his) // 2) self.execute('pressed', len(self.his) // 2) self.his.clear() def execute(self, type, time): try: function = self.ButtonTaskList.get(str(type) + str(time)) if function == None: raise Exception if str(function).find('generator'): loop = asyncio.get_event_loop() loop.create_task(Cancellable(function)()) else: function() except Exception as err: print('btn-exec->', err) pass
def callback_louder(p): b[0] = s.send(louder) print("change pin", p, b[0]) def callback_quieter(p): b[0] = s.send(quieter) print("change pin", p, b[0]) b = bytearray(2) quieter = umqtt.mtpPublish('sonos/ct', '{"action":"quieter"}') louder = umqtt.mtpPublish('sonos/ct', '{"action":"louder"}') s = socket.socket() p0 = Pin(0, Pin.IN, Pin.PULL_UP) p2 = Pin(2, Pin.IN, Pin.PULL_UP) p0.irq(trigger=Pin.IRQ_RISING, handler=callback_louder) p2.irq(trigger=Pin.IRQ_RISING, handler=callback_quieter) def run(): wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print('connecting to network...') wlan.connect(ssid, pw) while not wlan.isconnected(): pass print('network config:', wlan.ifconfig()) #s = socket.socket() s.connect((host, 1883)) s.send(umqtt.mtpConnect("somename"))
global last_button_press_time # block button press as software debounce if last_button_press_time < time.ticks_ms(): # add 150ms delay between button presses... might be too much, we'll see! last_button_press_time = time.ticks_ms() + 150 # If the pin is in the callback handler dictionary, call the appropriate function if str(pin) in button_handlers: button_handlers[str(pin)]() # else: # # print a debug message if button presses were too quick or a dounce happened # print("Button Bounce - {}ms".format( ( last_button_press_time - time.ticks_ms() ) ) ) # Create all of the triggers for each button pointing to the single callback handler BUT_1.irq(trigger=Pin.IRQ_FALLING, handler=button_press_callback) BUT_2.irq(trigger=Pin.IRQ_FALLING, handler=button_press_callback) BUT_3.irq(trigger=Pin.IRQ_FALLING, handler=button_press_callback) BUT_4.irq(trigger=Pin.IRQ_FALLING, handler=button_press_callback) # create timer for flashing UI flasher = Timer(0) flash_state = False def flasher_update(timer): global flash_state flash_state = not flash_state flasher.init(period=500, mode=Timer.PERIODIC, callback=flasher_update) def flash_text(x,y,text): global flash_state
# # Copyright (c) 2006-2019, RT-Thread Development Team # # SPDX-License-Identifier: MIT License # # Change Logs: # Date Author Notes # 2019-06-13 SummerGift first version # from machine import Pin # Get the GPIO pin number from GPIO index, for details see pin_num example. def pin_num(pin_index): return (ord(pin_index[1]) - ord('A')) * 16 + int(pin_index[2:]) key_0 = Pin(("key_0", pin_num("PD10")), Pin.IN, Pin.PULL_UP) def func(v): print("Hello rt-thread!") key_0.irq(trigger=Pin.IRQ_RISING, handler=func)
# ------------------------------------ # # ttt = thread.start_new_thread(test, ()) # bbb = thread.start_new_thread(blink, ()) thread.start_new_thread(get_dht11, ()) # Boot up flash! oled.fill(1) oled.show() time.sleep_ms(1000) # ------------ Main Loop ------------- # while True: btn.irq(my_func, Pin.IRQ_RISING) # ------------------- if ScreenSelect > 5: gc.collect() ScreenSelect = 0 if ScreenSelect == 0: scralarm() if ScreenSelect == 1: display_dht11() if ScreenSelect == 2: info()
from machine import Pin # Should be simple and short as possible. Cannot allocate memory here. def callback(p): print('pin changed', p) # Pull up resistor p5 = Pin(5, Pin.IN, Pin.PULL_UP) p5.irq(trigger=Pin.IRQ_FALLING, handler=callback)
) # Rename the temporary file with the filename constructed above # The actual function taking a measurement and recording the time def record_dist( sensor, write_file, rtc, datafile ): # requires the sensor, real-time clock, and datafile handles, and whether we are writing a file led = Pin(2, Pin.OUT) led.value(0) t_onboard = rtc.datetime() # Get the time dist = sensor.distance() # take a distance measuremen if write_file == 1: # If saving the data... data_str = '' # Initiate a string to add values to for t in [ t_onboard[0], t_onboard[1], t_onboard[2], t_onboard[4], t_onboard[5], t_onboard[6], t_onboard[7], dist ]: # for each value in the date string plus measurement... data_str += '{} '.format( t) # Combine all of the values into one line df = datafile.write( "%s\n" % data_str) # What that line and a line-break into our file # Whether writing a file or not, print the time and measurement for the user to see print(t_onboard[0], t_onboard[1], t_onboard[2], t_onboard[4], t_onboard[5], t_onboard[6], t_onboard[7], dist) led.value(1) global startSampleFlag p14 = Pin(14, mode=Pin.IN, pull=Pin.PULL_UP) # define my interrupt input p14.irq(trigger=Pin.IRQ_RISING, handler=RunTrigger) # set the trigger
import sys T = 0 contador = 0 tot = 0 t = 0 def my_callback(l): global contador, tot contador = contador + 1 tot = contador inpt = Pin(4, Pin.IN) inpt.irq(trigger=Pin.IRQ_RISING, handler=my_callback) sta_if = network.WLAN(network.STA_IF) sta_if.active(True) label = 'Voltaje' label1 = 'flujo' data = {label: 227} data1 = {label1: 227} red = 'IER' clave = 'acadier2014' unique_id = '0e217ef0-3d47-11ea-9ffe-35550336f914' token = 'zdOPgRd9KqHCcgKYRexa' ap_if = network.WLAN(network.AP_IF)
from machine import Pin import time led = Pin("GP16", Pin.OUT) led.toggle() def log(msg): print(msg) def btnPressed(pin): led.toggle() time.sleep_us(100) btn = Pin("GP17", Pin.IN, Pin.PULL_UP) btn.irq(trigger=Pin.IRQ_FALLING, handler=btnPressed) def home(): global wifi if wifi.mode() != WLAN.STA: wifi.mode(WLAN.STA) wifi.connect(config.HOME_SSID, auth=(WLAN.WPA, config.HOME_PASSWORD)) def tc(): global t, p import theta t = theta.Theta() p = t.connect() if not p: print("Connect failed!") else:
class SX127x: default_parameters = { 'frequency': 868E6, 'tx_power_level': 2, 'signal_bandwidth': 125E3, 'spreading_factor': 8, 'coding_rate': 5, 'preamble_length': 8, 'implicit_header': False, 'sync_word': 0x12, 'enable_CRC': False, 'invert_IQ': False, } frfs = {169E6: (42, 64, 0), 433E6: (108, 64, 0), 434E6: (108, 128, 0), 866E6: (216, 128, 0), 868E6: (217, 0, 0), 915E6: (228, 192, 0)} def __init__(self, spi, pins, parameters=default_parameters): self._spi = spi self._pins = pins self._parameters = parameters self._lock = False # setting pins if "dio_0" in self._pins: self._pin_rx_done = Pin(self._pins["dio_0"], Pin.IN) if "ss" in self._pins: self._pin_ss = Pin(self._pins["ss"], Pin.OUT) if "led" in self._pins: self._led_status = Pin(self._pins["led"], Pin.OUT) # check hardware version init_try = True re_try = 0 while init_try and re_try < 5: version = self.read_register(REG_VERSION) re_try = re_try + 1 if version != 0: init_try = False if version != 0x12: raise Exception('Invalid version.') if __DEBUG__: print("SX version: {}".format(version)) # put in LoRa and sleep mode self.sleep() # config self.set_frequency(self._parameters['frequency']) self.set_signal_bandwidth(self._parameters['signal_bandwidth']) # set LNA boost self.write_register(REG_LNA, self.read_register(REG_LNA) | 0x03) # set auto AGC self.write_register(REG_MODEM_CONFIG_3, 0x04) self.set_tx_power(self._parameters['tx_power_level']) self._implicit_header_mode = None self.implicit_header_mode(self._parameters['implicit_header']) self.set_spreading_factor(self._parameters['spreading_factor']) self.set_coding_rate(self._parameters['coding_rate']) self.set_preamble_length(self._parameters['preamble_length']) self.set_sync_word(self._parameters['sync_word']) self.enable_CRC(self._parameters['enable_CRC']) self.invert_IQ(self._parameters["invert_IQ"]) # set LowDataRateOptimize flag if symbol time > 16ms (default disable on reset) # self.write_register(REG_MODEM_CONFIG_3, self.read_register(REG_MODEM_CONFIG_3) & 0xF7) # default disable on reset bw_parameter = self._parameters["signal_bandwidth"] sf_parameter = self._parameters["spreading_factor"] if 1000 / (bw_parameter / 2**sf_parameter) > 16: self.write_register( REG_MODEM_CONFIG_3, self.read_register(REG_MODEM_CONFIG_3) | 0x08 ) # set base addresses self.write_register(REG_FIFO_TX_BASE_ADDR, FifoTxBaseAddr) self.write_register(REG_FIFO_RX_BASE_ADDR, FifoRxBaseAddr) self.standby() def begin_packet(self, implicit_header_mode = False): self.standby() self.implicit_header_mode(implicit_header_mode) # reset FIFO address and paload length self.write_register(REG_FIFO_ADDR_PTR, FifoTxBaseAddr) self.write_register(REG_PAYLOAD_LENGTH, 0) def end_packet(self): # put in TX mode self.write_register(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX) # wait for TX done, standby automatically on TX_DONE while self.read_register(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK == 0: pass # clear IRQ's self.write_register(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK) self.collect_garbage() def write(self, buffer): currentLength = self.read_register(REG_PAYLOAD_LENGTH) size = len(buffer) # check size size = min(size, (MAX_PKT_LENGTH - FifoTxBaseAddr - currentLength)) # write data for i in range(size): self.write_register(REG_FIFO, buffer[i]) # update length self.write_register(REG_PAYLOAD_LENGTH, currentLength + size) return size def set_lock(self, lock = False): self._lock = lock def println(self, msg, implicit_header = False): self.set_lock(True) # wait until RX_Done, lock and begin writing. self.begin_packet(implicit_header) if isinstance(msg, str): message = msg.encode() self.write(message) self.end_packet() self.set_lock(False) # unlock when done writing self.collect_garbage() def get_irq_flags(self): irq_flags = self.read_register(REG_IRQ_FLAGS) self.write_register(REG_IRQ_FLAGS, irq_flags) return irq_flags def packet_rssi(self): rssi = self.read_register(REG_PKT_RSSI_VALUE) return (rssi - (164 if self._frequency < 868E6 else 157)) def packet_snr(self): snr = self.read_register(REG_PKT_SNR_VALUE) return snr * 0.25 def standby(self): self.write_register(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY) def sleep(self): self.write_register(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP) def set_tx_power(self, level, outputPin = PA_OUTPUT_PA_BOOST_PIN): self._tx_power_level = level if (outputPin == PA_OUTPUT_RFO_PIN): # RFO level = min(max(level, 0), 14) self.write_register(REG_PA_CONFIG, 0x70 | level) else: # PA BOOST level = min(max(level, 2), 17) self.write_register(REG_PA_CONFIG, PA_BOOST | (level - 2)) def set_frequency(self, frequency, freq_table=frfs): self._frequency = frequency self.write_register(REG_FRF_MSB, freq_table[frequency][0]) self.write_register(REG_FRF_MID, freq_table[frequency][1]) self.write_register(REG_FRF_LSB, freq_table[frequency][2]) def set_spreading_factor(self, sf): sf = min(max(sf, 6), 12) self.write_register(REG_DETECTION_OPTIMIZE, 0xc5 if sf == 6 else 0xc3) self.write_register(REG_DETECTION_THRESHOLD, 0x0c if sf == 6 else 0x0a) self.write_register( REG_MODEM_CONFIG_2, (self.read_register(REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0) ) def set_signal_bandwidth(self, sbw): bins = (7.8E3, 10.4E3, 15.6E3, 20.8E3, 31.25E3, 41.7E3, 62.5E3, 125E3, 250E3) bw = 9 if sbw < 10: bw = sbw else: for i in range(len(bins)): if sbw <= bins[i]: bw = i break self.write_register( REG_MODEM_CONFIG_1, (self.read_register(REG_MODEM_CONFIG_1) & 0x0f) | (bw << 4) ) def set_coding_rate(self, denominator): denominator = min(max(denominator, 5), 8) cr = denominator - 4 self.write_register( REG_MODEM_CONFIG_1, (self.read_register(REG_MODEM_CONFIG_1) & 0xf1) | (cr << 1) ) def set_preamble_length(self, length): self.write_register(REG_PREAMBLE_MSB, (length >> 8) & 0xff) self.write_register(REG_PREAMBLE_LSB, (length >> 0) & 0xff) def enable_CRC(self, enable_CRC = False): modem_config_2 = self.read_register(REG_MODEM_CONFIG_2) config = modem_config_2 | 0x04 if enable_CRC else modem_config_2 & 0xfb self.write_register(REG_MODEM_CONFIG_2, config) def invert_IQ(self, invert_IQ): self._parameters["invertIQ"] = invert_IQ if invert_IQ: self.write_register( REG_INVERTIQ, ( ( self.read_register(REG_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_ON ), ) self.write_register(REG_INVERTIQ2, RFLR_INVERTIQ2_ON) else: self.write_register( REG_INVERTIQ, ( ( self.read_register(REG_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ), ) self.write_register(REG_INVERTIQ2, RFLR_INVERTIQ2_OFF) def set_sync_word(self, sw): self.write_register(REG_SYNC_WORD, sw) def set_channel(self, parameters): self.standby() for key in parameters: if key == "frequency": self.set_frequency(parameters[key]) continue if key == "invert_IQ": self.invert_IQ(parameters[key]) continue if key == "tx_power_level": self.set_tx_power(parameters[key]) continue def dump_registers(self): for i in range(128): print("0x{:02X}: {:02X}".format(i, self.read_register(i)), end="") if (i + 1) % 4 == 0: print() else: print(" | ", end="") def implicit_header_mode(self, implicit_header_mode = False): if self._implicit_header_mode != implicit_header_mode: # set value only if different. self._implicit_header_mode = implicit_header_mode modem_config_1 = self.read_register(REG_MODEM_CONFIG_1) config = (modem_config_1 | 0x01 if implicit_header_mode else modem_config_1 & 0xfe) self.write_register(REG_MODEM_CONFIG_1, config) def receive(self, size = 0): self.implicit_header_mode(size > 0) if size > 0: self.write_register(REG_PAYLOAD_LENGTH, size & 0xff) # The last packet always starts at FIFO_RX_CURRENT_ADDR # no need to reset FIFO_ADDR_PTR self.write_register( REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS ) def on_receive(self, callback): self._on_receive = callback if self._pin_rx_done: if callback: self.write_register(REG_DIO_MAPPING_1, 0x00) self._pin_rx_done.irq( trigger=Pin.IRQ_RISING, handler = self.handle_on_receive ) else: self._pin_rx_done.detach_irq() def handle_on_receive(self, event_source): self.set_lock(True) # lock until TX_Done irq_flags = self.get_irq_flags() if (irq_flags == IRQ_RX_DONE_MASK): # RX_DONE only, irq_flags should be 0x40 # automatically standby when RX_DONE if self._on_receive: payload = self.read_payload() self._on_receive(self, payload) elif self.read_register(REG_OP_MODE) != ( MODE_LONG_RANGE_MODE | MODE_RX_SINGLE ): # no packet received. # reset FIFO address / # enter single RX mode self.write_register(REG_FIFO_ADDR_PTR, FifoRxBaseAddr) self.write_register( REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE ) self.set_lock(False) # unlock in any case. self.collect_garbage() return True def received_packet(self, size = 0): irq_flags = self.get_irq_flags() self.implicit_header_mode(size > 0) if size > 0: self.write_register(REG_PAYLOAD_LENGTH, size & 0xff) # if (irq_flags & IRQ_RX_DONE_MASK) and \ # (irq_flags & IRQ_RX_TIME_OUT_MASK == 0) and \ # (irq_flags & IRQ_PAYLOAD_CRC_ERROR_MASK == 0): if (irq_flags == IRQ_RX_DONE_MASK): # RX_DONE only, irq_flags should be 0x40 # automatically standby when RX_DONE return True elif self.read_register(REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE): # no packet received. # reset FIFO address / # enter single RX mode self.write_register(REG_FIFO_ADDR_PTR, FifoRxBaseAddr) self.write_register( REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE ) def read_payload(self): # set FIFO address to current RX address # fifo_rx_current_addr = self.read_register(REG_FIFO_RX_CURRENT_ADDR) self.write_register( REG_FIFO_ADDR_PTR, self.read_register(REG_FIFO_RX_CURRENT_ADDR) ) # read packet length if self._implicit_header_mode: packet_length = self.read_register(REG_PAYLOAD_LENGTH) else: packet_length = self.read_register(REG_RX_NB_BYTES) payload = bytearray() for i in range(packet_length): payload.append(self.read_register(REG_FIFO)) self.collect_garbage() return bytes(payload) def read_register(self, address, byteorder = 'big', signed = False): response = self.transfer(address & 0x7f) return int.from_bytes(response, byteorder) def write_register(self, address, value): self.transfer(address | 0x80, value) def transfer(self, address, value = 0x00): response = bytearray(1) self._pin_ss.value(0) self._spi.write(bytes([address])) self._spi.write_readinto(bytes([value]), response) self._pin_ss.value(1) return response def blink_led(self, times = 1, on_seconds = 0.1, off_seconds = 0.1): for i in range(times): if self._led_status: self._led_status.value(True) sleep(on_seconds) self._led_status.value(False) sleep(off_seconds) def collect_garbage(self): gc.collect() if __DEBUG__: print('[Memory - free: {} allocated: {}]'.format(gc.mem_free(), gc.mem_alloc()))
# S1 and S2 are debounced in hardware # S1, S2 and Key are pulled-high. # GND: GND # Vcc : 3.3v # S1: GP_21 # S2: GP_22 # Key: GP_28 def irq_callback(pin, event=None): if pin == u2if.GP_28 and event == Pin.IRQ_FALLING: print("Key pressed") s1 = Pin(u2if.GP_21, Pin.IN) s2 = Pin(u2if.GP_22, Pin.IN) encoder = Encoder(s1, s2) key = Pin(u2if.GP_28, Pin.IN) key.irq(handler=irq_callback, trigger=Pin.IRQ_FALLING, debounce=True) # software debounced in u2if last_value = encoder.read() while True: # Retrieve all irq recorded and call handler Pin.process_irq() value = encoder.read() if last_value != value: print("Encoder value: %d" % value) last_value = value time.sleep(0.005)
class MPythonPin(): def __init__(self, pin, mode=PinMode.IN, pull=None): if mode not in [PinMode.IN, PinMode.OUT, PinMode.PWM, PinMode.ANALOG, PinMode.OUT_DRAIN]: raise TypeError("mode must be 'IN, OUT, PWM, ANALOG,OUT_DRAIN'") if pin == 4: raise TypeError("P4 is used for light sensor") if pin == 10: raise TypeError("P10 is used for sound sensor") try: self.id = pins_remap_esp32[pin] except IndexError: raise IndexError("Out of Pin range") if mode == PinMode.IN: if pin in [3]: raise TypeError('IN not supported on P%d' % pin) self.Pin = Pin(self.id, Pin.IN, pull) if mode == PinMode.OUT: if pin in [2, 3]: raise TypeError('OUT not supported on P%d' % pin) self.Pin = Pin(self.id, Pin.OUT, pull) if mode == PinMode.OUT_DRAIN: if pin in [2, 3]: raise TypeError('OUT_DRAIN not supported on P%d' % pin) self.Pin = Pin(self.id, Pin.OPEN_DRAIN, pull) if mode == PinMode.PWM: if pin not in [0, 1, 5, 6, 7, 8, 9, 11, 13, 14, 15, 16, 19, 20, 23, 24, 25, 26, 27, 28]: raise TypeError('PWM not supported on P%d' % pin) self.pwm = PWM(Pin(self.id), duty=0) if mode == PinMode.ANALOG: if pin not in [0, 1, 2, 3, 4, 10]: raise TypeError('ANALOG not supported on P%d' % pin) self.adc = ADC(Pin(self.id)) self.adc.atten(ADC.ATTN_11DB) self.mode = mode def irq(self, handler=None, trigger=Pin.IRQ_RISING): if not self.mode == PinMode.IN: raise TypeError('the pin is not in IN mode') return self.Pin.irq(handler, trigger) def read_digital(self): if not self.mode == PinMode.IN: raise TypeError('the pin is not in IN mode') return self.Pin.value() def write_digital(self, value): if self.mode not in [PinMode.OUT, PinMode.OUT_DRAIN]: raise TypeError('the pin is not in OUT or OUT_DRAIN mode') self.Pin.value(value) def read_analog(self): if not self.mode == PinMode.ANALOG: raise TypeError('the pin is not in ANALOG mode') # calibration esp32 ADC calibration_val = 0 val = int(sum([self.adc.read() for i in range(50)]) / 50) if 0 < val <= 2855: calibration_val = 1.023 * val + 183.6 if 2855 < val <= 3720: calibration_val = 0.9769 * val + 181 if 3720 < val <= 4095: calibration_val = 4095 - (4095 - val) * 0.2 return calibration_val def write_analog(self, duty, freq=1000): if not self.mode == PinMode.PWM: raise TypeError('the pin is not in PWM mode') self.pwm.freq(freq) self.pwm.duty(duty)
class SX127x: default_parameters = { "frequency": 869525000, "frequency_offset": 0, "tx_power_level": 14, "signal_bandwidth": 125e3, "spreading_factor": 9, "coding_rate": 5, "preamble_length": 8, "implicitHeader": False, "sync_word": 0x12, "enable_CRC": True, "invert_IQ": False, } def __init__(self, spi, pins, parameters={}): self.spi = spi self.pins = pins self.parameters = parameters self.pin_ss = Pin(self.pins["ss"], mode=Pin.OUT) self.pin_reset = Pin(self.pins["reset"], mode=Pin.OUT) self.manual_reset() self.lock = False self.implicit_header_mode = None self.parameters = SX127x.default_parameters if parameters: self.parameters.update(parameters) # check version version = None for i in range(5): version = self.readRegister(REG_VERSION) if version: break # debug output if version != 0x12: raise Exception('Invalid version.') self._bw = self.parameters["signal_bandwidth"] self._sf = self.parameters["spreading_factor"] # put in LoRa and sleep mode self.sleep() # config self.setFrequency(self.parameters["frequency"]) self.setSignalBandwidth(self.parameters["signal_bandwidth"]) # set LNA boost self.writeRegister(REG_LNA, self.readRegister(REG_LNA) | 0x03) # set auto AGC self.writeRegister(REG_MODEM_CONFIG_3, 0x04) self.setTxPower(self.parameters["tx_power_level"]) self.implicitHeaderMode(self.parameters["implicitHeader"]) self.setSpreadingFactor(self.parameters["spreading_factor"]) self.setCodingRate(self.parameters["coding_rate"]) self.setPreambleLength(self.parameters["preamble_length"]) self.setSyncWord(self.parameters["sync_word"]) self.enableCRC(self.parameters["enable_CRC"]) self.invertIQ(self.parameters["invert_IQ"]) # set LowDataRateOptimize flag if symbol time > 16ms (default disable on reset) # self.writeRegister(REG_MODEM_CONFIG_3, self.readRegister(REG_MODEM_CONFIG_3) & 0xF7) # default disable on reset bw = self.parameters["signal_bandwidth"] sf = self.parameters["spreading_factor"] if 1000 / bw / 2 ** sf > 16: self.writeRegister( REG_MODEM_CONFIG_3, self.readRegister(REG_MODEM_CONFIG_3) | 0x08 ) else: self.writeRegister(REG_MODEM_CONFIG_3, self.readRegister(REG_MODEM_CONFIG_3) & 0xF7) # set base addresses self.writeRegister(REG_FIFO_TX_BASE_ADDR, FifoTxBaseAddr) self.writeRegister(REG_FIFO_RX_BASE_ADDR, FifoRxBaseAddr) self.standby() def manual_reset(self): self.pin_reset.value(1) sleep_ms(100) self.pin_reset.value(0) sleep_ms(100) self.pin_reset.value(1) sleep_ms(100) def beginPacket(self, implicitHeaderMode=False): self.standby() self.implicitHeaderMode(implicitHeaderMode) # reset FIFO address and payload length self.writeRegister(REG_FIFO_ADDR_PTR, FifoTxBaseAddr) self.writeRegister(REG_PAYLOAD_LENGTH, 0) def endPacket(self): # put in TX mode self.writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX) # wait for TX done, standby automatically on TX_DONE start_tx_time = ticks_ms() while (self.readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0: if abs(ticks_diff(ticks_ms(), start_tx_time)) >= self.tx_timeout: self.writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK) raise Exception('TX timeout.') pass # clear IRQ's self.writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK) def write(self, buffer): currentLength = self.readRegister(REG_PAYLOAD_LENGTH) size = len(buffer) # check size size = min(size, (MAX_PKT_LENGTH - FifoTxBaseAddr - currentLength)) # write data for i in range(size): self.writeRegister(REG_FIFO, buffer[i]) # update length self.writeRegister(REG_PAYLOAD_LENGTH, currentLength + size) return size def aquirelock(self, lock=False): self.lock = False def println(self, message, implicitHeader=False, repeat=1): # wait until RX_Done, lock and begin writing self.aquirelock(True) if isinstance(message, str): message = message.encode() self.beginPacket(implicitHeader) self.write(message) self.tx_timeout = self.timeOnAir(len(message)) * 1.5 # ms for i in range(repeat): self.endPacket() # unlock when done writing self.aquirelock(False) self.collectGarbage() def getIrqFlags(self): irqFlags = self.readRegister(REG_IRQ_FLAGS) self.writeRegister(REG_IRQ_FLAGS, irqFlags) return irqFlags def packetRssi(self, rfi="hf"): packet_rssi = self.readRegister(REG_PKT_RSSI_VALUE) return packet_rssi - (157 if rfi == "hf" else 164) def packetSnr(self): val = self.readRegister(REG_PKT_SNR_VALUE) bits = 8 if (val & (1 << (bits - 1))) != 0: val = val - (1 << bits) return val * 0.25 def timeOnAir(self, length): symbolLength = float(float(1 << self._sf) / float(self._bw/1000.0)) de = 0.0 if symbolLength >= 16.0: de = 1.0 ih = float(self.spiGetValue(SX127X_REG_MODEM_CONFIG_1, 0, 0)) crc = float(self.spiGetValue(SX127X_REG_MODEM_CONFIG_2, 2, 2) >> 2) n_pre = float((self.spiGetValue(SX127X_REG_PREAMBLE_MSB) << 8) | self.spiGetValue(SX127X_REG_PREAMBLE_LSB)) n_pay = float(8.0 + max(ceil((8.0 * float(length) - 4.0 * float(self._sf) + 28.0 + 16.0 * crc - 20.0 * ih)/(4.0 * float(self._sf) - 8.0 * de)) * float(self._cr), 0.0)) return symbolLength * (n_pre + n_pay + 4.25) def spiGetValue(self, reg, msb=7, lsb=0): rawValue = self.readRegister(reg) return rawValue & ((0b11111111 << lsb) & (0b11111111 >> (7 - msb))) def standby(self): self.writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY) def sleep(self): self.writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP) def setTxPower(self, level, outputPin=PA_OUTPUT_PA_BOOST_PIN): if not ((level >= 0) and (level <= 20)): raise Exception('Invalid output power.') self.parameters["tx_power_level"] = level if outputPin == PA_OUTPUT_RFO_PIN: # RFO level = min(max(level, 0), 14) self.writeRegister(REG_PA_CONFIG, 0x70 | level) else: # PA BOOST 2...20 are valid values level = min(max(level, 2), 20) dacValue = self.readRegister(REG_PA_DAC) & ~7 ocpValue = 0 if level > 17: dacValue = dacValue | 7 ocpValue = 0x20 | 18 # 150 ma [-30 + 10*value] level = level - 5 # normalize to 15 max else: dacValue = dacValue | 4 ocpValue = 11 # 100 mA [45 + 5*value] level = level - 2 # normalize to 15 max self.writeRegister(REG_PA_CONFIG, PA_BOOST | level) self.writeRegister(REG_PA_DAC, dacValue) self.writeRegister(REG_OCP, ocpValue) def setFrequency(self, frequency): # TODO min max limit frequency = int(frequency) self.parameters["frequency"] = frequency frequency += self.parameters["frequency_offset"] frf = (frequency << 19) // 32000000 self.writeRegister(REG_FRF_MSB, (frf >> 16) & 0xFF) self.writeRegister(REG_FRF_MID, (frf >> 8) & 0xFF) self.writeRegister(REG_FRF_LSB, (frf >> 0) & 0xFF) def setSpreadingFactor(self, sf): sf = min(max(sf, 6), 12) self.writeRegister(REG_DETECTION_OPTIMIZE, 0xC5 if sf == 6 else 0xC3) self.writeRegister(REG_DETECTION_THRESHOLD, 0x0C if sf == 6 else 0x0A) self.writeRegister( REG_MODEM_CONFIG_2, (self.readRegister(REG_MODEM_CONFIG_2) & 0x0F) | ((sf << 4) & 0xF0), ) self._sf = sf bw = self._bw sf = self._sf if 1000 / bw / 2 ** sf > 16: self.writeRegister( REG_MODEM_CONFIG_3, self.readRegister(REG_MODEM_CONFIG_3) | 0x08 ) else: self.writeRegister(REG_MODEM_CONFIG_3, self.readRegister(REG_MODEM_CONFIG_3) & 0xF7) def setSignalBandwidth(self, sbw): bins = ( 7.8e3, 10.4e3, 15.6e3, 20.8e3, 31.25e3, 41.7e3, 62.5e3, 125e3, 250e3, ) bw = 9 if sbw < 10: bw = sbw else: for i in range(len(bins)): if sbw <= bins[i]: bw = i break self.writeRegister( REG_MODEM_CONFIG_1, (self.readRegister(REG_MODEM_CONFIG_1) & 0x0F) | (bw << 4), ) self._bw = sbw bw = self._bw sf = self._sf if 1000 / bw / 2 ** sf > 16: self.writeRegister( REG_MODEM_CONFIG_3, self.readRegister(REG_MODEM_CONFIG_3) | 0x08 ) else: self.writeRegister(REG_MODEM_CONFIG_3, self.readRegister(REG_MODEM_CONFIG_3) & 0xF7) def setCodingRate(self, denominator): denominator = min(max(denominator, 5), 8) cr = denominator - 4 self.writeRegister( REG_MODEM_CONFIG_1, (self.readRegister(REG_MODEM_CONFIG_1) & 0xF1) | (cr << 1), ) self._cr = cr + 4 def setPreambleLength(self, length): self.writeRegister(REG_PREAMBLE_MSB, (length >> 8) & 0xFF) self.writeRegister(REG_PREAMBLE_LSB, (length >> 0) & 0xFF) def enableCRC(self, enable_CRC=False): modem_config_2 = self.readRegister(REG_MODEM_CONFIG_2) config = modem_config_2 | 0x04 if enable_CRC else modem_config_2 & 0xFB self.writeRegister(REG_MODEM_CONFIG_2, config) def invertIQ(self, invertIQ): self.parameters["invertIQ"] = invertIQ if invertIQ: self.writeRegister( REG_INVERTIQ, ( ( self.readRegister(REG_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_ON ), ) self.writeRegister(REG_INVERTIQ2, RFLR_INVERTIQ2_ON) else: self.writeRegister( REG_INVERTIQ, ( ( self.readRegister(REG_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ), ) self.writeRegister(REG_INVERTIQ2, RFLR_INVERTIQ2_OFF) def setSyncWord(self, sw): self.writeRegister(REG_SYNC_WORD, sw) def setChannel(self, parameters): self.standby() for key in parameters: if key == "frequency": self.setFrequency(parameters[key]) continue if key == "invert_IQ": self.invertIQ(parameters[key]) continue if key == "tx_power_level": self.setTxPower(parameters[key]) continue def dumpRegisters(self): # TODO end='' for i in range(128): print("0x{:02X}: {:02X}".format(i, self.readRegister(i)), end="") if (i + 1) % 4 == 0: print() else: print(" | ", end="") def implicitHeaderMode(self, implicitHeaderMode=False): if ( self.implicit_header_mode != implicitHeaderMode ): # set value only if different. self.implicit_header_mode = implicitHeaderMode modem_config_1 = self.readRegister(REG_MODEM_CONFIG_1) config = ( modem_config_1 | 0x01 if implicitHeaderMode else modem_config_1 & 0xFE ) self.writeRegister(REG_MODEM_CONFIG_1, config) def receive(self, size=0): self.implicitHeaderMode(size > 0) if size > 0: self.writeRegister(REG_PAYLOAD_LENGTH, size & 0xFF) # The last packet always starts at FIFO_RX_CURRENT_ADDR # no need to reset FIFO_ADDR_PTR self.writeRegister( REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS ) def listen(self, time=1000): time = min(max(time, 0), 10000) self.receive() start = ticks_ms() while True: if self.receivedPacket(): return self.readPayload() if ticks_ms() - start > time: return None def onReceive(self, callback): self.onReceive = callback if "dio_0" in self.pins: self.pin_rx_done = Pin(self.pins["dio_0"], mode=Pin.IN) if self.pin_rx_done: if callback: self.writeRegister(REG_DIO_MAPPING_1, 0x00) try: self.pin_rx_done.callback( Pin.IRQ_RISING, self.handleOnReceive ) except: self.pin_rx_done.irq( trigger=Pin.IRQ_RISING, handler=self.handleOnReceive ) else: pass # TODO detach irq def handleOnReceive(self, event_source): # lock until TX_Done self.aquirelock(True) irqFlags = self.getIrqFlags() # RX_DONE only, irqFlags should be 0x40 if irqFlags & IRQ_RX_DONE_MASK == IRQ_RX_DONE_MASK: # automatically standby when RX_DONE if self.onReceive: payload = self.readPayload() self.onReceive(self, payload) elif self.readRegister(REG_OP_MODE) != ( MODE_LONG_RANGE_MODE | MODE_RX_SINGLE ): # no packet received. # reset FIFO address / # enter single RX mode self.writeRegister(REG_FIFO_ADDR_PTR, FifoRxBaseAddr) self.writeRegister( REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE ) self.aquirelock(False) # unlock in any case. self.collectGarbage() return True def receivedPacket(self, size=0): irqFlags = self.getIrqFlags() self.implicitHeaderMode(size > 0) if size > 0: self.writeRegister(REG_PAYLOAD_LENGTH, size & 0xFF) # if (irqFlags & IRQ_RX_DONE_MASK) and \ # (irqFlags & IRQ_RX_TIME_OUT_MASK == 0) and \ # (irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK == 0): if ( irqFlags == IRQ_RX_DONE_MASK ): # RX_DONE only, irqFlags should be 0x40 # automatically standby when RX_DONE return True elif self.readRegister(REG_OP_MODE) != ( MODE_LONG_RANGE_MODE | MODE_RX_SINGLE ): # no packet received. # reset FIFO address / # enter single RX mode self.writeRegister(REG_FIFO_ADDR_PTR, FifoRxBaseAddr) self.writeRegister( REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE ) def readPayload(self): # set FIFO address to current RX address # fifo_rx_current_addr = self.readRegister(REG_FIFO_RX_CURRENT_ADDR) self.writeRegister( REG_FIFO_ADDR_PTR, self.readRegister(REG_FIFO_RX_CURRENT_ADDR) ) # read packet length packet_length = 0 if self.implicit_header_mode: packet_length = self.readRegister(REG_PAYLOAD_LENGTH) else: packet_length = self.readRegister(REG_RX_NB_BYTES) payload = bytearray() for i in range(packet_length): payload.append(self.readRegister(REG_FIFO)) self.collectGarbage() return bytes(payload) def readRegister(self, address, byteorder="big", signed=False): response = self.transfer(address & 0x7F) return int.from_bytes(response, byteorder) def writeRegister(self, address, value): self.transfer(address | 0x80, value) def transfer(self, address, value=0x00): response = bytearray(1) self.pin_ss.value(0) self.spi.write(bytes([address])) self.spi.write_readinto(bytes([value]), response) self.pin_ss.value(1) return response def collectGarbage(self): gc.collect()
# gestion du senseur PIR def pir_activated( p ): # print( 'pir activated @ %s' % time.time() ) global last_pir_time, last_pir_msg, fire_pir_alert last_pir_time = time.time() # Faut-il lancer un message MOUV rapidement? # Initialiser le drapeau pour la boucle principale fire_pir_alert = (last_pir_msg == "NONE") # créer les senseurs try: adc = ADS1115( i2c=i2c, address=0x48, gain=0 ) pir_sensor = Pin( PIR_PIN, Pin.IN ) pir_sensor.irq( trigger=Pin.IRQ_RISING, handler=pir_activated ) except Exception as e: print( e ) led_error( step=4 ) try: # annonce connexion objet sMac = hexlify( WLAN().config( 'mac' ) ).decode() q.publish( "connect/%s" % CLIENT_ID , sMac ) except Exception as e: print( e ) led_error( step=5 ) import uasyncio as asyncio def capture_1h():
#亮蓝灯 led = Pin(2, Pin.OUT) led.on() ################################################################ broken_status = 0 #中断处理 def sports(para): global broken_status broken_status = (int)(para) print(broken_status) move_pin1 = Pin(21, Pin.IN, Pin.PULL_DOWN) move_pin1.irq(trigger=Pin.IRQ_RISING, handler=lambda t: sports(1)) move_pin2 = Pin(22, Pin.IN, Pin.PULL_DOWN) move_pin2.irq(trigger=Pin.IRQ_RISING, handler=lambda t: sports(2)) move_pin3 = Pin(23, Pin.IN, Pin.PULL_DOWN) move_pin3.irq(trigger=Pin.IRQ_RISING, handler=lambda t: sports(3)) #adc adc = ADC(Pin(32)) adc.atten(ADC.ATTN_11DB) adc.width(ADC.WIDTH_10BIT) ### while 1:
spreadsheet = Spreadsheet() spreadsheet.set_service_account(sa) spreadsheet.set_id(config.get('google_sheet_id')) spreadsheet.set_range('A:A') # create a handler which takes temperature and humidity and write them to a sheet weather_handler = WeatherHandler(spreadsheet) # initialize the DHT22 sensor which measures temperature and humidity weather = Weather(config.get('dht22_pin'), config.get('measurement_interval'), weather_handler) # initilize a switch which turns on the configuration mode # if the switch changes its state, then the board is going to reboot immediately config_mode_switch = Pin(config.get('config_mode_switch_pin'), Pin.IN) config_mode_switch.irq(lambda pin: util.reboot()) # first, check if the configuration mode is enabled # if so, set up an access point, and then start an HTTP server # the server provides a web form which updates the configuraion of the device # the server runs on http://192.168.4.1:80 if config_mode_switch.value() == 1: from http.server import HttpServer from settings import ConnectionHandler print('enabled configuration mode') access_point = util.start_access_point(ACCESS_POINT_SSID, ACCESS_POINT_PASSWORD) handler = ConnectionHandler(config) ip = access_point.ifconfig()[0] HttpServer(ip, 80, handler).start() util.reboot()
def detect_temp(i2c_0, temp_i2c_id): temp_barr = bytearray(2) i2c_0.readfrom_mem_into(temp_i2c_id, 0x00, temp_barr, addrsize=8) temp_flt = int.from_bytes(temp_barr, 'big', False)/128 # print("Temp:", temp, int.from_bytes(temp_barr, 'big', False)/128) return temp_flt """ START OF PROGRAM ******************************************************************************** """ # Initialize Buttons button1_right = Pin(26, Pin.IN, Pin.PULL_DOWN) button1_right.irq(trigger=Pin.IRQ_FALLING, handler=high_to_low_1_callback) button2_left = Pin(25, Pin.IN, Pin.PULL_DOWN) button2_left.irq(trigger=Pin.IRQ_FALLING, handler=high_to_low_2_callback) # Initialize I2C i2c_0 = I2C(-1, scl=Pin(22), sda=Pin(23), freq=400000) temp_i2c_id, accel_i2c_id = i2c_0.scan() def sessionID_callback(topic, msg): global SESSION_ID global ACK if topic == b"SessionID": SESSION_ID = msg
return "{} {} {}".format(NODE_NAME, message, millisecond) def on_receive(lora, payload): print('lora handler') lora.onReceive(on_receive) # imu settings sensor = MPU9250(-1) sensor.accel_range = 0 sensor.gyro_range = 1 sensor.filter_range = 1 irq_pin = Pin(25, mode=Pin.IN) irq_pin.irq(trigger=Pin.IRQ_RISING, handler=mpu_irq_handler) # display display = Display() # sd cards spi_sd = SPI(1, sck=Pin(23, Pin.OUT), mosi=Pin(13, Pin.OUT), miso=Pin(12, Pin.IN)) sd = SDCard(spi_sd, Pin(21)) os.mount(sd, '/sd') # gps uart = UART(1, rx=34, tx=17) # init with given baudrate uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
def encoderHandler(pin): global position global isHomed position = position + 1 #print ( "Position: ", position, " isHomed: ", isHomed ) def breakerHandler(pin): global position global isHomed print("Homing: ", isHomed, " Postion: ", position) position = 0 if (not isHomed): isHomed = True encoder1.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=encoderHandler) breaker.irq(trigger=Pin.IRQ_RISING, handler=breakerHandler) m1ena = Pin(3, Pin.OUT) m1enb = Pin(4, Pin.OUT) m1pwm = PWM(Pin(5)) m1ena.value(0) m1enb.value(1) m1pwm.freq(500) m1pwm.duty_u16(16000) utime.sleep(3) m1pwm.duty_u16(0)
class SX127x: _default_parameters = { 'tx_power_level': 2, 'signal_bandwidth': 'SF7BW125', 'spreading_factor': 7, 'coding_rate': 5, 'sync_word': 0x34, 'implicit_header': False, 'preamble_length': 8, 'enable_CRC': False, 'invert_IQ': False, } _data_rates = { "SF7BW125": (0x74, 0x72, 0x04), "SF7BW250": (0x74, 0x82, 0x04), "SF8BW125": (0x84, 0x72, 0x04), "SF9BW125": (0x94, 0x72, 0x04), "SF10BW125": (0xA4, 0x72, 0x04), "SF11BW125": (0xB4, 0x72, 0x0C), "SF12BW125": (0xC4, 0x72, 0x0C) } def __init__( self, spi, pins, ttn_config, channel=0, # compatibility with Dragino LG02, set to None otherwise fport=1, lora_parameters=_default_parameters): self._spi = spi self._pins = pins self._parameters = lora_parameters self._lock = False # setting pins if "dio_0" in self._pins: self._pin_rx_done = Pin(self._pins["dio_0"], Pin.IN) self._irq = Pin(self._pins["dio_0"], Pin.IN) if "ss" in self._pins: self._pin_ss = Pin(self._pins["ss"], Pin.OUT) if "led" in self._pins: self._led_status = Pin(self._pins["led"], Pin.OUT) if "reset" in self._pins: self._reset = Pin(self._pins["reset"], Pin.OUT) self._reset.value(False) utime.sleep(1) self._reset.value(True) utime.sleep(1) # check hardware version init_try = True re_try = 0 while init_try and re_try < 5: version = self.read_register(REG_VERSION) re_try = re_try + 1 if __DEBUG__: print("SX version: {}".format(version)) if version == 0x12: init_try = False else: utime.sleep_ms(1000) if version != 0x12: raise Exception('Invalid version.') # Set frequency registers self._rfm_msb = None self._rfm_mid = None self._rfm_lsb = None # init framecounter self.frame_counter = 0 self._fport = fport # Set datarate registers self._sf = None self._bw = None self._modemcfg = None # ttn configuration if "US" in ttn_config.country: from ttn_usa import TTN_FREQS self._frequencies = TTN_FREQS elif ttn_config.country == "AS": from ttn_as import TTN_FREQS self._frequencies = TTN_FREQS elif ttn_config.country == "AU": from ttn_au import TTN_FREQS self._frequencies = TTN_FREQS elif ttn_config.country == "EU": if __DEBUG__: print("ttn configuration using EU frequencies") from ttn_eu import TTN_FREQS self._frequencies = TTN_FREQS else: raise TypeError("Country Code Incorrect/Unsupported") # Give the uLoRa object ttn configuration self._ttn_config = ttn_config # put in LoRa and sleep mode self.sleep() # set channel number self._channel = channel self._actual_channel = channel if self._channel is not None: self.set_frequency(self._channel) # set data rate and bandwidth self.set_bandwidth(self._parameters["signal_bandwidth"]) # set LNA boost self.write_register(REG_LNA, self.read_register(REG_LNA) | 0x03) # set auto AGC self.write_register(REG_MODEM_CONFIG, 0x04) self.implicit_header_mode(self._parameters['implicit_header']) self.set_tx_power(self._parameters['tx_power_level']) self.set_coding_rate(self._parameters['coding_rate']) self.set_sync_word(self._parameters['sync_word']) self.enable_CRC(self._parameters['enable_CRC']) #self.invert_IQ(self._parameters["invert_IQ"]) self.set_preamble_length(self._parameters['preamble_length']) self.set_spreading_factor(self._parameters['spreading_factor']) # set LowDataRateOptimize flag if symbol time > 16ms (default disable on reset) # self.write_register(REG_MODEM_CONFIG, self.read_register(REG_MODEM_CONFIG) & 0xF7) # default disable on reset #bw_parameter = self._parameters["signal_bandwidth"] #sf_parameter = self._parameters["spreading_factor"] #if 1000 / (bw_parameter / 2**sf_parameter) > 16: # self.write_register( # REG_MODEM_CONFIG, # self.read_register(REG_MODEM_CONFIG) | 0x08 # ) # set base addresses self.write_register(REG_FIFO_TX_BASE_ADDR, FifoTxBaseAddr) self.write_register(REG_FIFO_RX_BASE_ADDR, FifoRxBaseAddr) self.standby() def begin_packet(self, implicit_header_mode=False): self.standby() self.implicit_header_mode(implicit_header_mode) #self.write_register(REG_DIO_MAPPING_1, 0x40) # Check for multi-channel configuration if self._channel is None: self._actual_channel = urandom.getrandbits(3) self.set_frequency(self._actual_channel) # reset FIFO address and paload length self.write_register(REG_FIFO_ADDR_PTR, FifoTxBaseAddr) self.write_register(REG_PAYLOAD_LENGTH, 0) def end_packet(self, timeout=5): # put in TX mode self.write_register(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX) start = utime.time() timed_out = False # wait for TX done, standby automatically on TX_DONE #self.read_register(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK == 0 and \ irq_value = self.read_register(REG_IRQ_FLAGS) while not timed_out and \ irq_value & IRQ_TX_DONE_MASK == 0: if utime.time() - start >= timeout: timed_out = True else: irq_value = self.read_register(REG_IRQ_FLAGS) if timed_out: raise RuntimeError("Timeout during packet send") # clear IRQ's self.write_register(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK) self.collect_garbage() def write(self, buffer, buffer_length): # update length self.write_register(REG_PAYLOAD_LENGTH, buffer_length) # write data for i in range(buffer_length): self.write_register(REG_FIFO, buffer[i]) def set_lock(self, lock=False): self._lock = lock def send_data(self, data, data_length, frame_counter, timeout=5): if __DEBUG__: print("data:", ubinascii.hexlify(data)) # Data packet enc_data = bytearray(data_length) lora_pkt = bytearray(64) # Copy bytearray into bytearray for encryption enc_data[0:data_length] = data[0:data_length] # Encrypt data (enc_data is overwritten in this function) self.frame_counter = frame_counter aes = AES(self._ttn_config.device_address, self._ttn_config.app_key, self._ttn_config.network_key, self.frame_counter) enc_data = aes.encrypt(enc_data) # Construct MAC Layer packet (PHYPayload) # MHDR (MAC Header) - 1 byte lora_pkt[ 0] = REG_DIO_MAPPING_1 # MType: unconfirmed data up, RFU / Major zeroed # MACPayload # FHDR (Frame Header): DevAddr (4 bytes) - short device address lora_pkt[1] = self._ttn_config.device_address[3] lora_pkt[2] = self._ttn_config.device_address[2] lora_pkt[3] = self._ttn_config.device_address[1] lora_pkt[4] = self._ttn_config.device_address[0] # FHDR (Frame Header): FCtrl (1 byte) - frame control lora_pkt[5] = 0x00 # FHDR (Frame Header): FCnt (2 bytes) - frame counter lora_pkt[6] = self.frame_counter & 0x00FF lora_pkt[7] = (self.frame_counter >> 8) & 0x00FF # FPort - port field lora_pkt[8] = self._fport # Set length of LoRa packet lora_pkt_len = 9 if __DEBUG__: print("PHYPayload", ubinascii.hexlify(lora_pkt)) # load encrypted data into lora_pkt lora_pkt[lora_pkt_len:lora_pkt_len + data_length] = enc_data[0:data_length] if __DEBUG__: print("PHYPayload with FRMPayload", ubinascii.hexlify(lora_pkt)) # Recalculate packet length lora_pkt_len += data_length # Calculate Message Integrity Code (MIC) # MIC is calculated over: MHDR | FHDR | FPort | FRMPayload mic = bytearray(4) mic = aes.calculate_mic(lora_pkt, lora_pkt_len, mic) # Load MIC in package lora_pkt[lora_pkt_len:lora_pkt_len + 4] = mic[0:4] # Recalculate packet length (add MIC length) lora_pkt_len += 4 if __DEBUG__: print("PHYPayload with FRMPayload + MIC", ubinascii.hexlify(lora_pkt)) self.send_packet(lora_pkt, lora_pkt_len, timeout) def send_packet(self, lora_packet, packet_length, timeout): """ Sends a LoRa packet using the SX1276 module. """ self.set_lock(True) # wait until RX_Done, lock and begin writing. self.begin_packet() # Fill the FIFO buffer with the LoRa payload self.write(lora_packet, packet_length) # Send the package self.end_packet(timeout) self.set_lock(False) # unlock when done writing self.blink_led() self.collect_garbage() def get_irq_flags(self): irq_flags = self.read_register(REG_IRQ_FLAGS) if __DEBUG__: irq_dict = dict( rx_timeout=irq_flags >> 7 & 0x01, rx_done=irq_flags >> 6 & 0x01, crc_error=irq_flags >> 5 & 0x01, valid_header=irq_flags >> 4 & 0x01, tx_done=irq_flags >> 3 & 0x01, cad_done=irq_flags >> 2 & 0x01, fhss_change_ch=irq_flags >> 1 & 0x01, cad_detected=irq_flags >> 0 & 0x01, ) print(irq_dict) self.write_register(REG_IRQ_FLAGS, irq_flags) return irq_flags def packet_rssi(self): # TODO rssi = self.read_register(REG_PKT_RSSI_VALUE) return rssi #return (rssi - (164 if self._frequency < 868E6 else 157)) def packet_snr(self): snr = self.read_register(REG_PKT_SNR_VALUE) return snr * 0.25 def standby(self): self.write_register(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY) utime.sleep_ms(10) def sleep(self): self.write_register(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP) utime.sleep_ms(10) def set_tx_power(self, level, outputPin=PA_OUTPUT_PA_BOOST_PIN): self._tx_power_level = level if (outputPin == PA_OUTPUT_RFO_PIN): # RFO level = min(max(level, 0), 14) self.write_register(REG_PA_CONFIG, 0x70 | level) else: # PA BOOST level = min(max(level, 2), 17) self.write_register(REG_PA_CONFIG, PA_BOOST | (level - 2)) def set_frequency(self, channel): self.write_register(REG_FRF_MSB, self._frequencies[channel][0]) self.write_register(REG_FRF_MID, self._frequencies[channel][1]) self.write_register(REG_FRF_LSB, self._frequencies[channel][2]) def set_coding_rate(self, denominator): denominator = min(max(denominator, 5), 8) cr = denominator - 4 self.write_register( REG_FEI_MSB, (self.read_register(REG_FEI_MSB) & 0xf1) | (cr << 1)) def set_preamble_length(self, length): self.write_register(REG_PREAMBLE_MSB, (length >> 8) & 0xff) self.write_register(REG_PREAMBLE_LSB, (length >> 0) & 0xff) def set_spreading_factor(self, sf): sf = min(max(sf, 6), 12) self.write_register(REG_DETECTION_OPTIMIZE, 0xc5 if sf == 6 else 0xc3) self.write_register(REG_DETECTION_THRESHOLD, 0x0c if sf == 6 else 0x0a) self.write_register(REG_FEI_LSB, (self.read_register(REG_FEI_LSB) & 0x0f) | ((sf << 4) & 0xf0)) def set_bandwidth(self, datarate): try: sf, bw, modemcfg = self._data_rates[datarate] self.write_register(REG_FEI_LSB, sf) self.write_register(REG_FEI_MSB, bw) self.write_register(REG_MODEM_CONFIG, modemcfg) except KeyError: raise KeyError("Invalid or Unsupported Datarate.") def enable_CRC(self, enable_CRC=False): modem_config_2 = self.read_register(REG_FEI_LSB) config = modem_config_2 | 0x04 if enable_CRC else modem_config_2 & 0xfb self.write_register(REG_FEI_LSB, config) def invert_IQ(self, invert_IQ): self._parameters["invertIQ"] = invert_IQ if invert_IQ: self.write_register( REG_INVERTIQ, ((self.read_register(REG_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_ON), ) self.write_register(REG_INVERTIQ2, RFLR_INVERTIQ2_ON) else: self.write_register( REG_INVERTIQ, ((self.read_register(REG_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF), ) self.write_register(REG_INVERTIQ2, RFLR_INVERTIQ2_OFF) def set_sync_word(self, sw): self.write_register(REG_SYNC_WORD, sw) def dump_registers(self): for i in range(128): print("0x{:02X}: {:02X}".format(i, self.read_register(i)), end="") if (i + 1) % 4 == 0: print() else: print(" | ", end="") def implicit_header_mode(self, implicit_header_mode=False): self._implicit_header_mode = implicit_header_mode modem_config_1 = self.read_register(REG_FEI_MSB) config = (modem_config_1 | 0x01 if implicit_header_mode else modem_config_1 & 0xfe) self.write_register(REG_FEI_MSB, config) def receive(self, size=0): self.implicit_header_mode(size > 0) if size > 0: self.write_register(REG_PAYLOAD_LENGTH, size & 0xff) # The last packet always starts at FIFO_RX_CURRENT_ADDR # no need to reset FIFO_ADDR_PTR self.write_register(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS) def on_receive(self, callback): self._on_receive = callback if self._pin_rx_done: if callback: print("callback attached") self.write_register(REG_DIO_MAPPING_1, 0x00) self._pin_rx_done.irq(trigger=Pin.IRQ_RISING, handler=self.handle_on_receive) else: self._pin_rx_done.detach_irq() def handle_on_receive(self, event_source): self.set_lock(True) # lock until TX_Done aes = AES(self._ttn_config.device_address, self._ttn_config.app_key, self._ttn_config.network_key, self.frame_counter) # irqFlags = self.getIrqFlags() should be 0x50 if (self.get_irq_flags() & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0: if self._on_receive: payload = self.read_payload() self.set_lock(False) # unlock when done reading data = aes.decrypt_payload(payload) self._on_receive(self, data) self.set_lock(False) # unlock in any case. self.collect_garbage() """ def handle_on_receive(self, event_source): self.set_lock(True) # lock until TX_Done aes = AES( self._ttn_config.device_address, self._ttn_config.app_key, self._ttn_config.network_key, self.frame_counter ) irq_flags = self.get_irq_flags() if (irq_flags == IRQ_RX_DONE_MASK): # RX_DONE only, irq_flags should be 0x40 # automatically standby when RX_DONE print("yeah" + str(irq_flags)) if self._on_receive: payload = self.read_payload() data = aes.decrypt_payload(payload) self._on_receive(self, data) elif self.read_register(REG_OP_MODE) != ( MODE_LONG_RANGE_MODE | MODE_RX_SINGLE ): print("nada" + str(irq_flags)) # no packet received. # reset FIFO address / # enter single RX mode self.write_register(REG_FIFO_ADDR_PTR, FifoRxBaseAddr) self.write_register( REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE ) self.set_lock(False) # unlock in any case. self.collect_garbage() return True """ def received_packet(self, size=0): irq_flags = self.get_irq_flags() self.implicit_header_mode(size > 0) if size > 0: self.write_register(REG_PAYLOAD_LENGTH, size & 0xff) #if (irq_flags & IRQ_RX_DONE_MASK) and \ # (irq_flags & IRQ_RX_TIME_OUT_MASK == 0) and \ # (irq_flags & IRQ_PAYLOAD_CRC_ERROR_MASK == 0): if (irq_flags == IRQ_RX_DONE_MASK): # RX_DONE only, irq_flags should be 0x40 # automatically standby when RX_DONE return True elif self.read_register(REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE): # no packet received. # reset FIFO address / # enter single RX mode self.write_register(REG_FIFO_ADDR_PTR, FifoRxBaseAddr) self.write_register(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE) def read_payload(self): # set FIFO address to current RX address # fifo_rx_current_addr = self.read_register(REG_FIFO_RX_CURRENT_ADDR) self.write_register(REG_FIFO_ADDR_PTR, self.read_register(REG_FIFO_RX_CURRENT_ADDR)) # read packet length if self._implicit_header_mode: packet_length = self.read_register(REG_PAYLOAD_LENGTH) else: packet_length = self.read_register(REG_RX_NB_BYTES) payload = bytearray() for i in range(packet_length): payload.append(self.read_register(REG_FIFO)) self.collect_garbage() return bytes(payload) def read_register(self, address, byteorder='big', signed=False): response = self.transfer(address & 0x7f) return int.from_bytes(response, byteorder) def write_register(self, address, value): self.transfer(address | 0x80, value) def transfer(self, address, value=0x00): response = bytearray(1) self._pin_ss.value(0) self._spi.write(bytes([address])) self._spi.write_readinto(bytes([value]), response) self._pin_ss.value(1) return response def blink_led(self, times=1, on_seconds=0.1, off_seconds=0.1): for i in range(times): if self._led_status: self._led_status.value(True) utime.sleep(on_seconds) self._led_status.value(False) utime.sleep(off_seconds) def collect_garbage(self): gc.collect()
from pubsub import PubSub pubsub = PubSub(100) pubsub.start() ####################################################################################### from machine import Pin def irq_handler(pin): pubsub.publish('button', pin) button_0 = Pin(0, Pin.IN) button_0.irq(trigger=Pin.IRQ_FALLING, handler=irq_handler) ####################################################################################### from machine import Timer tim = Timer(-1) tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t: pubsub.publish('timer')) ####################################################################################### class Counter: def __init__(self): self.value = 0
class EPD(object): MAX_READ = 45 SW_NORMAL_PROCESSING = 0x9000 EP_FRAMEBUFFER_SLOT_OVERRUN = 0x6a84 # too much data fed in EP_SW_INVALID_LE = 0x6c00 # Wrong expected length EP_SW_INSTRUCTION_NOT_SUPPORTED = 0x6d00 # bad instr EP_SW_WRONG_PARAMETERS_P1P2 = 0x6a00 EP_SW_WRONG_LENGTH = 0x6700 DEFAULT_SLOT=0 # always the *oldest*, should wear-level then I think def __init__(self, debug=False, baud=100000): # From datasheet # Bit rate – up to 12 MHz1 # ▪ Polarity – CPOL = 1; clock transition high-to-low on the leading edge and low-to-high on the # trailing edge # ▪ Phase – CPHA = 1; setup on the leading edge and sample on the trailing edge # ▪ Bit order – MSB first # ▪ Chip select polarity – active low self.spi = SPI(0) try: self.spi.init(mode=SPI.MASTER, baudrate=baud, bits=8, polarity=1, phase=1, firstbit=SPI.MSB, pins=('GP31', 'GP16', 'GP30')) # CLK, MOSI, MISO except AttributeError: self.spi.init(baudrate=baud, bits=8, polarity=1, phase=1, firstbit=SPI.MSB, pins=('GP31', 'GP16', 'GP30')) # CLK, MOSI, MISO # These are all active low! self.tc_en_bar = Pin('GP4', mode=Pin.OUT) self.disable() self.tc_busy_bar = Pin('GP5', mode=Pin.IN) self.tc_busy_bar.irq(trigger=Pin.IRQ_RISING) # Wake up when it changes self.tc_cs_bar = Pin('GP17', mode=Pin.ALT, alt=7) self.debug = debug def enable(self): self.tc_en_bar.value(0) # Power up time.sleep_ms(5) while self.tc_busy_bar() == 0: machine.idle() # will it wake up here? # /tc_busy goes high during startup, low during init, then high when not busy def disable(self): self.tc_en_bar.value(1) # Off def send_command(self, ins, p1, p2, data=None, expected=None): # These command variables are always sent cmd = struct.pack('3B', ins, p1, p2) # Looks like data is only sent with the length (Lc) if data: assert len(data) <= 251 # Thus speaks the datasheet cmd += struct.pack('B', len(data)) cmd += data # Expected data is either not present at all, 0 for null-terminated, or a number for fixed if expected is not None: cmd += struct.pack('B', expected) if self.debug: print("Sending: " + hexlify(cmd).decode()) self.spi.write(cmd) # Wait for a little while time.sleep_us(15) # This should take at most 14.5us while self.tc_busy_bar() == 0: machine.idle() # Request a response if expected is not None: if expected > 0: result_bytes = self.spi.read(2 + expected) else: result_bytes = self.spi.read(EPD.MAX_READ) strlen = result_bytes.find(b'\x00') result_bytes = result_bytes[:strlen] + result_bytes[strlen+1:strlen+3] else: result_bytes = self.spi.read(2) if self.debug: print("Received: " + hexlify(result_bytes).decode()) (result,) = struct.unpack_from('>H', result_bytes[-2:]) if result != EPD.SW_NORMAL_PROCESSING: raise ValueError("Bad result code: 0x%x" % result) return result_bytes[:-2] @staticmethod def calculate_checksum(data, skip=16): """ Initial checksum value is 0x6363 :param data: :param skip: Skip some data as slices are expensive :return: """ acc = 0x6363 for byte in data: if skip > 0: skip -= 1 else: acc ^= byte acc = ((acc >> 8) | (acc << 8)) & 0xffff acc ^= ((acc & 0xff00) << 4) & 0xffff acc ^= (acc >> 8) >> 4 acc ^= (acc & 0xff00) >> 5 return acc def get_sensor_data(self): # GetSensorData val = self.send_command(0xe5, 1, 0, expected=2) (temp,) = struct.unpack(">H", val) return temp def get_device_id(self): return self.send_command(0x30, 2, 1, expected=0x14) def get_system_info(self): return self.send_command(0x31, 1, 1, expected=0) def get_system_version_code(self): return self.send_command(0x31, 2, 1, expected=0x10) def display_update(self, slot=0, flash=True): cmd = 0x86 if flash: cmd = 0x24 self.send_command(cmd, 1, slot) def reset_data_pointer(self): self.send_command(0x20, 0xd, 0) def image_erase_frame_buffer(self, slot=0): self.send_command(0x20, 0xe, slot) def get_checksum(self, slot): cksum_val = self.send_command(0x2e, 1, slot, expected=2) (cksum,) = struct.unpack(">H", cksum_val) return cksum def upload_image_data(self, data, slot=0, delay_us=1000): self.send_command(0x20, 1, slot, data) time.sleep_us(delay_us) def upload_whole_image(self, img, slot=0): """ Chop up chunks and send it :param img: Image to send in EPD format :param slot: Slot framebuffer number to use :param delay_us: Delay between packets? 450us and the Tbusy line never comes back :return: """ total = len(img) idx = 0 try: while idx < total - 250: chunk = img[idx:idx+250] self.upload_image_data(chunk, slot) del chunk idx += 250 self.upload_image_data(img[idx:], slot) except KeyboardInterrupt: print("Stopped at user request at position: %d (%d)" % (idx, (idx // 250))) except ValueError as e: print("Stopped at position: %d (%d) - %s" % (idx, (idx // 250), e))
with open(filepath, "r") as f: return f.readlines() return [] def uninstall(): import os os.chdir("dumb_cup") for item in os.listdir(): print(type(item)) try: os.remove(item) except: os.rmdir(item) btn_state = BTN_UNPRESSED btn.irq(on_btn) ##################### # Volume coefficient ##################### def vol_cof(): lines = fs_read_cali() for value in lines: if "empty" in value: empty_val = float(value.split("=")[1][0:-1]) elif "full" in value: full_val = float(value.split("=")[1][0:-1]) return (empty_val, full_val) ##################### # Check Liquid Level
pin0 = Pin(pins[0], mode=Pin.OUT, value=1) pin1 = Pin(pins[1], mode=Pin.IN, pull=Pin.PULL_UP) def pin_handler (pin_o): global pin_irq_count_trigger global pin_irq_count_total global _trigger if _trigger & pin1_irq.flags(): pin_irq_count_trigger += 1 pin_irq_count_total += 1 pin_irq_count_trigger = 0 pin_irq_count_total = 0 _trigger = Pin.IRQ_FALLING pin1_irq = pin1.irq(trigger=_trigger, handler=pin_handler) for i in range (0, 10): pin0.toggle() time.sleep_ms(5) print(pin_irq_count_trigger == 5) print(pin_irq_count_total == 5) pin_irq_count_trigger = 0 pin_irq_count_total = 0 _trigger = Pin.IRQ_RISING pin1_irq = pin1.irq(trigger=_trigger, handler=pin_handler) for i in range (0, 200): pin0.toggle() time.sleep_ms(5) print(pin_irq_count_trigger == 100) print(pin_irq_count_total == 100)
def rtc_attach_interrupt(rtc_callback): irq = Pin(37, mode=Pin.IN) irq.irq(handler=rtc_callback, trigger=Pin.IRQ_FALLING) return irq
# 引脚 button = Pin(USER_BUTTON, Pin.IN) # 定义按键按下的值 (取决于按键模块的设计, 有可能相反) # BTN_DOWN = 0 # 按键按下对应的取值 # BTN_UP = 1 # 按键抬起对应的状态 counter = 0 # 计数器 def counter_callback(pin): ''' 计数器回调函数 ''' global counter # 添加软件消抖 utime.sleep_ms(150) if pin.value() == 0: counter += 1 print("Counter += 1 ; Counter = %d" % (counter)) button.irq(trigger=Pin.IRQ_FALLING, handler=counter_callback) print("按下按键, 会计数哦") while True: print("do something...") utime.sleep_ms(500)
class osd: def __init__(self): self.screen_x = const(64) self.screen_y = const(20) self.cwd = "/" self.init_fb() self.exp_names = " KMGTE" self.mark = bytearray([32,16,42]) # space, right triangle, asterisk self.read_dir() self.spi_read_irq = bytearray([1,0xF1,0,0,0,0,0]) self.spi_read_btn = bytearray([1,0xFB,0,0,0,0,0]) self.spi_result = bytearray(7) self.spi_enable_osd = bytearray([0,0xFE,0,0,0,1]) self.spi_write_osd = bytearray([0,0xFD,0,0,0]) self.spi_channel = const(2) self.spi_freq = const(3000000) self.init_pinout_sd() #self.spi=SPI(self.spi_channel, baudrate=self.spi_freq, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=Pin(self.gpio_sck), mosi=Pin(self.gpio_mosi), miso=Pin(self.gpio_miso)) self.init_spi() alloc_emergency_exception_buf(100) self.enable = bytearray(1) self.timer = Timer(3) self.irq_handler(0) self.irq_handler_ref = self.irq_handler # allocation happens here self.spi_request = Pin(0, Pin.IN, Pin.PULL_UP) self.spi_request.irq(trigger=Pin.IRQ_FALLING, handler=self.irq_handler_ref) def init_spi(self): self.spi=SPI(self.spi_channel, baudrate=self.spi_freq, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=Pin(self.gpio_sck), mosi=Pin(self.gpio_mosi), miso=Pin(self.gpio_miso)) self.cs=Pin(self.gpio_cs,Pin.OUT) self.cs.off() # init file browser def init_fb(self): self.fb_topitem = 0 self.fb_cursor = 0 self.fb_selected = -1 @micropython.viper def init_pinout_sd(self): self.gpio_cs = const(5) self.gpio_sck = const(16) self.gpio_mosi = const(4) self.gpio_miso = const(12) @micropython.viper def irq_handler(self, pin): p8result = ptr8(addressof(self.spi_result)) self.cs.on() self.spi.write_readinto(self.spi_read_irq, self.spi_result) self.cs.off() btn_irq = p8result[6] if btn_irq&0x80: # btn event IRQ flag self.cs.on() self.spi.write_readinto(self.spi_read_btn, self.spi_result) self.cs.off() btn = p8result[6] p8enable = ptr8(addressof(self.enable)) if p8enable[0]&2: # wait to release all BTNs if btn==1: p8enable[0]&=1 # clear bit that waits for all BTNs released else: # all BTNs released if (btn&0x78)==0x78: # all cursor BTNs pressed at the same time self.show_dir() # refresh directory p8enable[0]=(p8enable[0]^1)|2; self.osd_enable(p8enable[0]&1) if p8enable[0]==1: if btn==9: # btn3 cursor up self.start_autorepeat(-1) if btn==17: # btn4 cursor down self.start_autorepeat(1) if btn==1: self.timer.deinit() # stop autorepeat if btn==33: # btn6 cursor left self.updir() if btn==65: # btn6 cursor right self.select_entry() def start_autorepeat(self, i:int): self.autorepeat_direction=i self.move_dir_cursor(i) self.timer_slow=1 self.timer.init(mode=Timer.PERIODIC, period=500, callback=self.autorepeat) def autorepeat(self, timer): if self.timer_slow: self.timer_slow=0 self.timer.init(mode=Timer.PERIODIC, period=30, callback=self.autorepeat) self.move_dir_cursor(self.autorepeat_direction) self.irq_handler(0) # catch stale IRQ def select_entry(self): if self.direntries[self.fb_cursor][1]: # is it directory oldselected = self.fb_selected - self.fb_topitem self.fb_selected = self.fb_cursor try: self.cwd = self.fullpath(self.direntries[self.fb_cursor][0]) except: self.fb_selected = -1 self.show_dir_line(oldselected) self.show_dir_line(self.fb_cursor - self.fb_topitem) self.init_fb() self.read_dir() self.show_dir() else: self.change_file() def updir(self): if len(self.cwd) < 2: self.cwd = "/" else: s = self.cwd.split("/")[:-1] self.cwd = "" for name in s: if len(name) > 0: self.cwd += "/"+name self.init_fb() self.read_dir() self.show_dir() def fullpath(self,fname): if self.cwd.endswith("/"): return self.cwd+fname else: return self.cwd+"/"+fname def change_file(self): oldselected = self.fb_selected - self.fb_topitem self.fb_selected = self.fb_cursor try: filename = self.fullpath(self.direntries[self.fb_cursor][0]) except: filename = False self.fb_selected = -1 self.show_dir_line(oldselected) self.show_dir_line(self.fb_cursor - self.fb_topitem) if filename: if filename.endswith(".bit"): self.spi_request.irq(handler=None) self.timer.deinit() self.enable[0]=0 self.osd_enable(0) self.spi.deinit() tap=ecp5.ecp5() tap.prog_stream(open(filename,"rb"),blocksize=1024) if filename.endswith("_sd.bit"): os.umount("/sd") for i in bytearray([2,4,12,13,14,15]): p=Pin(i,Pin.IN) a=p.value() del p,a result=tap.prog_close() del tap gc.collect() #os.mount(SDCard(slot=3),"/sd") # BUG, won't work self.init_spi() # because of ecp5.prog() spi.deinit() self.spi_request.irq(trigger=Pin.IRQ_FALLING, handler=self.irq_handler_ref) self.irq_handler(0) # handle stuck IRQ if filename.endswith(".z80"): self.enable[0]=0 self.osd_enable(0) import ld_zxspectrum s=ld_zxspectrum.ld_zxspectrum(self.spi,self.cs) s.loadz80(filename) del s gc.collect() if filename.endswith(".nes"): import ld_zxspectrum s=ld_zxspectrum.ld_zxspectrum(self.spi,self.cs) s.ctrl(1) s.ctrl(0) s.load_stream(open(filename,"rb"),addr=0,maxlen=0x101000) del s gc.collect() self.enable[0]=0 self.osd_enable(0) if filename.endswith(".ora") or filename.endswith(".orao"): self.enable[0]=0 self.osd_enable(0) import ld_orao s=ld_orao.ld_orao(self.spi,self.cs) s.loadorao(filename) del s gc.collect() if filename.endswith(".vsf"): self.enable[0]=0 self.osd_enable(0) import ld_vic20 s=ld_vic20.ld_vic20(self.spi,self.cs) s.loadvsf(filename) del s gc.collect() if filename.endswith(".prg"): self.enable[0]=0 self.osd_enable(0) import ld_vic20 s=ld_vic20.ld_vic20(self.spi,self.cs) s.loadprg(filename) del s gc.collect() @micropython.viper def osd_enable(self, en:int): pena = ptr8(addressof(self.spi_enable_osd)) pena[5] = en&1 self.cs.on() self.spi.write(self.spi_enable_osd) self.cs.off() @micropython.viper def osd_print(self, x:int, y:int, i:int, text): p8msg=ptr8(addressof(self.spi_write_osd)) a=0xF000+(x&63)+((y&31)<<6) p8msg[2]=i p8msg[3]=a>>8 p8msg[4]=a self.cs.on() self.spi.write(self.spi_write_osd) self.spi.write(text) self.cs.off() @micropython.viper def osd_cls(self): p8msg=ptr8(addressof(self.spi_write_osd)) p8msg[3]=0xF0 p8msg[4]=0 self.cs.on() self.spi.write(self.spi_write_osd) self.spi.read(1280,32) self.cs.off() # y is actual line on the screen def show_dir_line(self, y): if y < 0 or y >= self.screen_y: return mark = 0 invert = 0 if y == self.fb_cursor - self.fb_topitem: mark = 1 invert = 1 if y == self.fb_selected - self.fb_topitem: mark = 2 i = y+self.fb_topitem if i >= len(self.direntries): self.osd_print(0,y,0,"%64s" % "") return if self.direntries[i][1]: # directory self.osd_print(0,y,invert,"%c%-57s D" % (self.mark[mark],self.direntries[i][0])) else: # file mantissa = self.direntries[i][2] exponent = 0 while mantissa >= 1024: mantissa >>= 10 exponent += 1 self.osd_print(0,y,invert,"%c%-57s %4d%c" % (self.mark[mark],self.direntries[i][0], mantissa, self.exp_names[exponent])) def show_dir(self): for i in range(self.screen_y): self.show_dir_line(i) def move_dir_cursor(self, step): oldcursor = self.fb_cursor if step == 1: if self.fb_cursor < len(self.direntries)-1: self.fb_cursor += 1 if step == -1: if self.fb_cursor > 0: self.fb_cursor -= 1 if oldcursor != self.fb_cursor: screen_line = self.fb_cursor - self.fb_topitem if screen_line >= 0 and screen_line < self.screen_y: # move cursor inside screen, no scroll self.show_dir_line(oldcursor - self.fb_topitem) # no highlight self.show_dir_line(screen_line) # highlight else: # scroll if screen_line < 0: # cursor going up screen_line = 0 if self.fb_topitem > 0: self.fb_topitem -= 1 self.show_dir() else: # cursor going down screen_line = self.screen_y-1 if self.fb_topitem+self.screen_y < len(self.direntries): self.fb_topitem += 1 self.show_dir() def read_dir(self): self.direntries = [] ls = sorted(os.listdir(self.cwd)) for fname in ls: stat = os.stat(self.fullpath(fname)) if stat[0] & 0o170000 == 0o040000: self.direntries.append([fname,1,0]) # directory else: self.direntries.append([fname,0,stat[6]]) # file gc.collect()
print('Conecte-se em http://{}'.format(sta.ifconfig()[0])) oledShowIP(sta.ifconfig()[0]) # ========= CONFIGURAÇÃO SENSOR PIR ============ motion = False if PIR: def handle_interrupt(pin): global motion motion = True global interrupt_pin interrupt_pin = pin pir = Pin(14, Pin.IN) pir.irq(trigger=Pin.IRQ_RISING, handler=handle_interrupt) # ============ CONFIGURAÇÃO WEB SERVER =============== app = picoweb.WebApp(__name__) tempo_fim = 0 fim = True @app.route("/") def index(req, resp): global motion if motion: led.on() print('Sensor PIR detectou movimentos próximos a luz UV') oledUvcInf(False) yield from picoweb.start_response(resp)
# I2C for senzor BME280 and inicialization i2c = I2C(scl=Pin(18), sda=Pin(23), freq=10000) bme = BME280.BME280(i2c=i2c) # Init Led led = machine.Pin(5, machine.Pin.OUT) # Register a new hardware timer. timer = Timer(0) # Setup the button input pin with a pull-up resistor. button = Pin(19, Pin.IN, Pin.PULL_UP) # Register an interrupt on rising button input. button.irq(debounce, Pin.IRQ_RISING) try: client = connect_and_subscribe() except OSError as e: restart_and_reconnect() while True: try: client.check_msg() if (time.time() - last_message) > message_interval: payload = {} payload["temp"] = bme.temperature payload["pres"] = bme.pressure client.publish(topic_pub, json.dumps(payload)) state = led.value()
print("debounced", p, b[0]) return b[0] = c.sock.send(quieter) print("change pin", p, b[0]) def callback_play_pause(p): if b[0]: print("debounced", p, b[0]) return b[0] = c.sock.send(play_pause) print("change pin", p, b[0]) p0 = Pin(0, Pin.IN, Pin.PULL_UP) p2 = Pin(2, Pin.IN, Pin.PULL_UP) p13 = Pin(13, Pin.IN, Pin.PULL_UP) p0.irq(trigger=Pin.IRQ_RISING, handler=callback_louder) p2.irq(trigger=Pin.IRQ_RISING, handler=callback_quieter) p13.irq(trigger=Pin.IRQ_RISING, handler=callback_play_pause) def wrap(text,lim): lines = [] pos = 0 line = [] for word in text.split(): if pos + len(word) < lim + 1: line.append(word) pos+= len(word) + 1 else: lines.append(' '.join(line)) line = [word] pos = len(word)
def switch_push_init(): global push1, push2 push2 = Pin('PA10', Pin.IN, Pin.PULL_UP) push2.irq(exti15_10_irqhandler, Pin.IRQ_RISING, 1) push1 = Pin('PA9', Pin.IN, Pin.PULL_UP) push1.irq(exti9_5_irqhandler, Pin.IRQ_RISING, 2)
from machine import Pin def callback(p): mypin.value(mypin.value() ^ 1) btn = Pin(5, Pin.IN, Pin.PULL_UP) mypin = Pin(4, Pin.OUT) btn.irq(trigger=Pin.IRQ_FALLING, handler=callback) while 1: pass
# Complete project details at https://RandomNerdTutorials.com from machine import Pin from time import sleep motion = False def handle_interrupt(pin): global motion motion = True global interrupt_pin interrupt_pin = pin led = Pin(12, Pin.OUT) pir = Pin(14, Pin.IN) pir.irq(trigger=Pin.IRQ_RISING, handler=handle_interrupt) while True: if motion: print('Motion detected! Interrupt caused by:', interrupt_pin) led.value(1) sleep(20) led.value(0) print('Motion stopped!') motion = False