def __init__(self, chan, cs, xdim, ydim): self.spi = SPI(chan, SPI.MASTER, baudrate=1000000, polarity=0, phase=0, firstbit=SPI.LSB) self.xdim = xdim self.ydim = ydim if not isinstance(cs, Pin): cs = Pin(cs) cs.value(0) cs.init(Pin.OUT_PP) self.cs = cs self.usleep = udelay self.lines = [bytearray(xdim//8) for i in range(ydim)] self.changed = set()
def declare_channel(self, channel, direction): try: self.available_pins.index(channel) if self._find_channel(channel): return ; pin = Pin(channel) if direction: pin.init(Pin.OUT_PP) else: pin.init(Pin.IN, Pin.PULL_UP) self.channels += [pin] except: pass
class GroveUltrasonic(object): def __init__(self, pin): self.dio = Pin(pin) def value(self): dt=-1 while dt<0: self.dio.init(Pin.OUT) self.dio.value(0) utime.sleep_us(2) self.dio.value(1) utime.sleep_us(10) self.dio.value(0) self.dio.init(Pin.IN) dt = time_pulse_us(self.dio, 1, 100000) return (dt / 29 / 2) # cm
def write_frame(self): """ Send a DMX frame """ # DMX needs a 88us low to begin a frame, # 77uS us used because of time it takes to init pin dmx_uart = Pin(tx_pins[self.port], Pin.OUT_PP) dmx_uart.value(0) udelay(74) dmx_uart.value(1) # Now turn into a UART port and send DMX data dmx_uart = UART(self.port) dmx_uart.init(250000, bits=8, parity=None, stop=2) #send bytes dmx_uart.write(self.dmx_message) #Delete as its going to change anyway del (dmx_uart)
class Pushbutton(PushbuttonBase): def __init__(self, pin, pullup=PULL_UP_ENABLED, defaultState=DEFAULT_STATE_HIGH): #self._pin = pin self._pin = Pin("Y7", Pin.IN) self._pullup = pullup self._defaultstate = defaultState initialized = True # This class is always initialised and doens't need to initialised before # button if (self._pullup == PULL_UP_ENABLED): self._pin.init(Pin.IN, Pin.PULL_UP) else: self._pin.init(Pin.IN, Pin.PULL_NONE) time.sleep_us(5) def isPressed(self): return (self._pin.value() != self._defaultstate)
def init(timer_id=2, nc_pin='Y3', gnd_pin='Y4', vcc_pin='Y1', data_pin='Y2'): global nc global gnd global vcc global data global micros global timer # Leave the pin unconnected if nc_pin is not None: nc = Pin(nc_pin) nc.init(Pin.OUT_OD) nc.high() # Make the pin work as GND if gnd_pin is not None: gnd = Pin(gnd_pin) gnd.init(Pin.OUT_PP) gnd.low() # Make the pin work as power supply if vcc_pin is not None: vcc = Pin(vcc_pin) vcc.init(Pin.OUT_PP) vcc.high() # Configure the pid for data communication data = Pin(data_pin) # Save the ID of the timer we are going to use timer = timer_id # setup the 1uS timer micros = pyb.Timer(timer, prescaler=83, period=0x3fffffff) # 1MHz ~ 1uS # Prepare interrupt handler ExtInt(data, ExtInt.IRQ_FALLING, Pin.PULL_UP, None) ExtInt(data, ExtInt.IRQ_FALLING, Pin.PULL_UP, edge)
from pyb import Pin p = Pin('X1', Pin.IN) print(p) print(p.name()) print(p.pin()) print(p.port()) p = Pin('X1', Pin.IN, Pin.PULL_UP) p = Pin('X1', Pin.IN, pull=Pin.PULL_UP) p = Pin('X1', mode=Pin.IN, pull=Pin.PULL_UP) print(p) print(p.value()) p.init(p.IN, p.PULL_DOWN) p.init(p.IN, pull=p.PULL_DOWN) p.init(mode=p.IN, pull=p.PULL_DOWN) print(p) print(p.value()) p.init(p.OUT_PP) p.low() print(p.value()) p.high() print(p.value()) p.value(0) print(p.value()) p.value(1) print(p.value()) p.value(False) print(p.value())
pin = Pin(pin_map[0], mode=Pin.OPEN_DRAIN, pull=Pin.PULL_UP) pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_DOWN) pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_NONE) pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_UP) pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.LOW_POWER) pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.MED_POWER) pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.HIGH_POWER) pin = Pin(pin_map[0], mode=Pin.OUT, drive=pin.LOW_POWER) pin = Pin(pin_map[0], Pin.OUT, Pin.PULL_DOWN) pin = Pin(pin_map[0], Pin.ALT, Pin.PULL_UP) pin = Pin(pin_map[0], Pin.ALT_OPEN_DRAIN, Pin.PULL_UP) test_pin_af() # try the entire af range on all pins # test pin init and printing pin = Pin(pin_map[0]) pin.init(mode=Pin.IN) print(pin) pin.init(Pin.IN, Pin.PULL_DOWN) print(pin) pin.init(mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.LOW_POWER) print(pin) pin.init(mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.HIGH_POWER) print(pin) # test value in OUT mode pin = Pin(pin_map[0], mode=Pin.OUT) pin.value(0) pin.toggle() # test toggle print(pin()) pin.toggle() # test toggle again print(pin())
from pyb import Pin p = Pin('X1') print(p) print(p.name()) print(p.pin()) print(p.port()) p = Pin('X1', Pin.IN, Pin.PULL_UP) #p = Pin('X1', Pin.IN, pull=Pin.PULL_UP) print(p.value()) p.init(p.IN, p.PULL_DOWN) #p.init(p.IN, pull=p.PULL_DOWN) print(p.value()) p.init(p.OUT_PP) p.low() print(p.value()) p.high() print(p.value()) p.value(0) print(p.value()) p.value(1) print(p.value()) p.value(False) print(p.value()) p.value(True) print(p.value())
class RS485(object): def __init__(self, uart_num, pin_rw, dev_id): self.error = [] self.uart = UART(uart_num) self.uart.init(57600, bits=8, parity=0, timeout=10, read_buf_len=64) self.pin_rw = Pin(pin_rw) self.pin_rw.init(Pin.OUT_PP) self.pin_rw.value(0) self.dev_id = dev_id self.file_parts = 0 self.file_parts_i = 1 self.file_is_open = False def check_lan(self): res = [] uart = self.uart try: buf = uart.readall() if buf: buf = buf.decode("utf-8") LED(2).toggle() for pack in buf.split(chr(0x0)): if pack: try: data = False data = loads(pack) if len(data) > 0 and data[0] == self.dev_id: if data[2][0] == "SET_CONFIG_FILE": res = [data] if data[2][2] == False: self.file_parts = data[2][1] self.file_parts_i = 1 self._write_config(True, '') self.file_is_open = True else: if self.file_is_open: if self.file_parts_i == data[2][1]: self._write_config(False, data[2][2]) if self.file_parts_i == self.file_parts: self.file_is_open = False self.file_parts_i += 1 else: res = [[self.dev_id, 3]] self.error += ["Error 3 %s" % (data)] self.file_is_open = False break else: res = [[self.dev_id, 3]] self.error += ["Error 4 DATA: %s" % (data)] break else: self.file_is_open = False res = [data] except Exception as e: res = [[self.dev_id, 3]] if data: self.error += ["Error 1 {}".format(e.args) + " DATA: %s" % (data)] else: self.error += ["Error 1 {}".format(e.args) + " PACK: %s" % (pack)] LED(4).on() except Exception as e: res = [[self.dev_id, 3]] self.error += ["Error 2 {}".format(e.args)] LED(4).on() return res def send_pack(self, pack_type, pack_data): pin_rw = self.pin_rw.value uart = self.uart pin_rw(1) try: buf = [self.dev_id, pack_type, pack_data] data = dumps(buf).encode("utf-8") data += bytearray([0x0]) uart.write(data) except: #print("Возникла ошибка при отправке пакета") #print(data) LED(3).on() pin_rw(0) def _write_config(self, is_start, data): if is_start: f = open("config.py", "w") else: f = open("config.py", "a") try: f.write(data) except: pass f.close()
from pyb import ADC, I2S, Timer, I2C, Pin pot = ADC('Y12') hpctl = Pin('Y11') hpctl.init(hpctl.OUT_PP) hpctl.high() i2c = I2C(2, I2C.MASTER) # i2c.init(i2c.MASTER) # Might do a 'try' here to make sure both i2c devices are working: l = i2c.scan() for i in l: print(i) #> [26, 96] # Set Headphone Amp chip registers: i2c.mem_write( 0xc0, 96, 1 ) # control register: enable both amplifier channels, activate stereo mode i2c.mem_write(0x35, 96, 2) # volume register; unmute both channels, set gain to ~0dB i2c.mem_write(0x00, 96, 3) # output tri-state register; set both channels to output mode # Set codec registers: # THe SSM2604 uses a register addressing scheme that does not map directly to the uPy # mem_read / mem_write methods. # There are a total of 11 9-bit registers (R0-R9 and R15) which are selected using a # 7-bit address. Register writes are constructed using the 'send' method: # i2c.send('0b<7-bit register address><9-bit register data>', 26) # Register reads can use 'mem_read' but the register address must be multiplied by 2
class Encoder(): """ Abstracts a quadrature encoder to give a tick count. The count is a signed integer starting at zero. It wraps the count from the attached timer to give a seamless and continuous tick count. Overflows of the internal timer counter register should be adequatly handled. If overflows or weird behaviour occurs around the overflow points, try increasing Encoder.HYSTERESIS. Note: Only works on pin pairs 'X1' & 'X2', 'X9' & 'X10', or 'Y1', 'Y2'. The timer will be automatically selected. Both Timer 2 and 5 work for 'X1' & 'X2', but Timer 5 is preferred because Timer 2 is used for LED PWM but both can be used by changing the values of Encoder.AF_MAP. """ # Constant for decoding in single line mode SINGLE_MODE = Timer.ENC_A # Constant for decoding in quad mode DUAL_MODE = Timer.ENC_AB # Maps alternate pin function descriptions to the required timer number TIMER_MAP = {'AF1_TIM2': 2, 'AF2_TIM4': 4, 'AF2_TIM5': 5, 'AF3_TIM8': 8} # Maps pin names to the alternate function to use AF_MAP = {'X1' : 'AF2_TIM5', 'X2': 'AF2_TIM5', 'X9': 'AF2_TIM4', 'X10': 'AF2_TIM4', 'Y1': 'AF3_TIM8', 'Y2': 'AF3_TIM8'} # Defines the pin pairs that must be used PIN_PAIRS = [['X1','X9','Y1'],['X2','X10','Y2']] # Hysteresis value to overflow detection HYSTERESIS = 12 # One full rotation of encoder def __init__(self, pinA, pinB, mode = DUAL_MODE): """ Instantiate an Encoder object. Initalises the Pins, Timer and TimerChannel for use as a quadrature decoder. Registers an overflow callback to elegantly handle counter register overflows. pinA: Any valid value taken by pyb.Pin constructor pinB: Any valid value taken by pyb.Pin constructor mode: Mode to use for decoding (Encoder.SINGLE_MODE or Encoder.DUAL_MODE) raises: Any exception thrown by pyb.Pin, pyb.Timer, pyb.Timer.channel or Exception if pins are not compatible pairs """ self._chA = Pin(pinA) self._chB = Pin(pinB) self._ticks = 0 # Check pins are compatible self._checkPins(pinA, pinB) # init pins for alternate encoder function af = self.AF_MAP[self._chA.names()[1]] channel = self.TIMER_MAP[af] af = getattr(Pin, af) self._chA.init(Pin.AF_PP, pull = Pin.PULL_NONE, af = af) self._chB.init(Pin.AF_PP, pull = Pin.PULL_NONE, af = af) # init timer self._timer = Timer(channel, prescaler = 0, period = 100000) # init encoder mode # self._channel = self._timer.channel(1, mode) self._timer.channel(1, mode) # setup overflow callback self._timer.callback(self._overflow) # init count register to middle of count self._timer.counter(self._timer.period()//2) self._lastRead = self._timer.counter() def _checkPins(self, pinA, pinB): """ Check that two pins can be used for a decoding and are on the same timer. """ try: if pinA in self.PIN_PAIRS[0]: if self.PIN_PAIRS[0].index(pinA) != self.PIN_PAIRS[1].index(pinB): raise Exception() elif pinA in self.PIN_PAIRS[1]: if self.PIN_PAIRS[0].index(pinB) != self.PIN_PAIRS[1].index(pinA): raise Exception() else: raise Exception() except: raise Exception(pinA + ' & ' + pinB + ' are not on the same Timer') def ticks(self, ticks = None): """ Get or set the current tick count. Ticks is a signed integer. """ if ticks is not None: # set ticks to desired value self._ticks = ticks else: # retrieve latest count and update internals count = self._timer.counter() self._ticks = self._ticks + (count - self._lastRead) self._lastRead = count return self._ticks def _overflow(self, timer): """ Timer overflow callback to gracefully handle overflow events. If weird things are occurring, try increasing the HYSTERESIS value. """ count = timer.counter() if 0 <= count <= self.HYSTERESIS: # overflow self._ticks = self._ticks + (timer.period() - self._lastRead + count) self._lastRead = count elif (timer.period() - self.HYSTERESIS) <= count <= timer.period(): # underflow self._ticks = self._ticks - (self._lastRead + timer.period() - count) self._lastRead = count else: # hysteresis not big enough #LED(1).on() # turn on inbuilt red led to show error pass
class Grove4Digit(object): def __init__(self, clk,dio): self.clk = Pin(clk,Pin.OUT,Pin.PULL_UP) self.dio = Pin(dio,Pin.OUT,Pin.PULL_UP) def value(self): return self.button.value() def start(self): self.clk.value(1) self.dio.value(1) self.dio.value(0) self.clk.value(0) def stop(self): self.clk.value(0) self.dio.value(0) self.clk.value(1) self.dio.value(1) def writeByte(self,data): for _ in range(8): self.clk.value(0) if data & 0x01: self.dio.value(1) else: self.dio.value(0) data >>= 1 utime.sleep_us(1) self.clk.value(1) utime.sleep_us(1) self.clk.value(0) self.dio.value(1) self.clk.value(1) self.dio.init(Pin.IN,Pin.PULL_UP) utime.sleep_ms(50) ack = self.dio.value() if (ack == 0): self.dio.init(Pin.OUT,Pin.PULL_UP) self.dio.value(0) utime.sleep_ms(50) self.dio.init(Pin.OUT,Pin.PULL_UP) utime.sleep_ms(50) def display(self,data,brightness=BRIGHT_DEFAULT,colon=False): self.start() self.writeByte(ADDR_AUTO) self.stop() self.start() self.writeByte(STARTADDR) if len(data) < 4: data = data + ' ' for i in range(4): self.writeByte(charmap[data[i]] | 0x80 * colon) self.stop() if brightness > BRIGHT_HIGHEST: brightness = BRIGHT_HIGHEST if brightness < BRIGHT_DARKEST: brightness = BRIGHT_DARKEST self.start() self.writeByte(0x88 + brightness) self.stop() def clear(self): self.display(' ',4,0)
class Encoder(): """ Abstracts a quadrature encoder to give a tick count. The count is a signed integer starting at zero. It wraps the count from the attached timer to give a seamless and continuous tick count. Overflows of the internal timer counter register should be adequatly handled. If overflows or weird behaviour occurs around the overflow points, try increasing Encoder.HYSTERESIS. Note: Only works on pin pairs 'X1' & 'X2', 'X9' & 'X10', or 'Y1', 'Y2'. The timer will be automatically selected. Both Timer 2 and 5 work for 'X1' & 'X2', but Timer 5 is preferred because Timer 2 is used for LED PWM but both can be used by changing the values of Encoder.AF_MAP. """ # Constant for decoding in single line mode SINGLE_MODE = Timer.ENC_A # Constant for decoding in quad mode DUAL_MODE = Timer.ENC_AB # Maps alternate pin function descriptions to the required timer number TIMER_MAP = {'AF1_TIM2': 2, 'AF2_TIM4': 4, 'AF2_TIM5': 5, 'AF3_TIM8': 8} # Maps pin names to the alternate function to use AF_MAP = { 'X1': 'AF2_TIM5', 'X2': 'AF2_TIM5', 'X9': 'AF2_TIM4', 'X10': 'AF2_TIM4', 'Y1': 'AF3_TIM8', 'Y2': 'AF3_TIM8' } # Defines the pin pairs that must be used PIN_PAIRS = [['X1', 'X9', 'Y1'], ['X2', 'X10', 'Y2']] # Hysteresis value to overflow detection HYSTERESIS = 12 # One full rotation of encoder def __init__(self, pinA, pinB, mode=DUAL_MODE): """ Instantiate an Encoder object. Initalises the Pins, Timer and TimerChannel for use as a quadrature decoder. Registers an overflow callback to elegantly handle counter register overflows. pinA: Any valid value taken by pyb.Pin constructor pinB: Any valid value taken by pyb.Pin constructor mode: Mode to use for decoding (Encoder.SINGLE_MODE or Encoder.DUAL_MODE) raises: Any exception thrown by pyb.Pin, pyb.Timer, pyb.Timer.channel or Exception if pins are not compatible pairs """ self._chA = Pin(pinA) self._chB = Pin(pinB) self._ticks = 0 # Check pins are compatible self._checkPins(pinA, pinB) # init pins for alternate encoder function af = self.AF_MAP[self._chA.names()[1]] channel = self.TIMER_MAP[af] af = getattr(Pin, af) self._chA.init(Pin.AF_PP, pull=Pin.PULL_NONE, af=af) self._chB.init(Pin.AF_PP, pull=Pin.PULL_NONE, af=af) # init timer self._timer = Timer(channel, prescaler=0, period=100000) # init encoder mode # self._channel = self._timer.channel(1, mode) self._timer.channel(1, mode) # setup overflow callback self._timer.callback(self._overflow) # init count register to middle of count self._timer.counter(self._timer.period() // 2) self._lastRead = self._timer.counter() def _checkPins(self, pinA, pinB): """ Check that two pins can be used for a decoding and are on the same timer. """ try: if pinA in self.PIN_PAIRS[0]: if self.PIN_PAIRS[0].index(pinA) != self.PIN_PAIRS[1].index( pinB): raise Exception() elif pinA in self.PIN_PAIRS[1]: if self.PIN_PAIRS[0].index(pinB) != self.PIN_PAIRS[1].index( pinA): raise Exception() else: raise Exception() except: raise Exception(pinA + ' & ' + pinB + ' are not on the same Timer') def ticks(self, ticks=None): """ Get or set the current tick count. Ticks is a signed integer. """ if ticks is not None: # set ticks to desired value self._ticks = ticks else: # retrieve latest count and update internals count = self._timer.counter() self._ticks = self._ticks + (count - self._lastRead) self._lastRead = count return self._ticks def _overflow(self, timer): """ Timer overflow callback to gracefully handle overflow events. If weird things are occurring, try increasing the HYSTERESIS value. """ count = timer.counter() if 0 <= count <= self.HYSTERESIS: # overflow self._ticks = self._ticks + (timer.period() - self._lastRead + count) self._lastRead = count elif (timer.period() - self.HYSTERESIS) <= count <= timer.period(): # underflow self._ticks = self._ticks - (self._lastRead + timer.period() - count) self._lastRead = count else: # hysteresis not big enough #LED(1).on() # turn on inbuilt red led to show error pass
class Button(object): ''' This button can handle short and long press ''' def __init__(self, pin, timerId=6, thresholdTime=1000, lowOnPress=False): ''' Constructor @param pin: Pin object where the button is @param timerId: (default=6) Timer to determine the long press @param thresholdTime: Waiting time to determine a long press as milliseconds @param lowOnPress: Indicates whether the value is 0 when the button is pressed (pull-down) The user (blue) button on the NUCLEO-L476RG board must have this parameter as True, but for the case of the NUCLEO-F767ZI board, this parameter must be False ''' self._pin = Pin(pin) self._pin.init(mode=Pin.IN) self._pin.irq(handler=self._onPinIrq) self._lowOnPress = lowOnPress self._thresholdTime = thresholdTime self._pressTime = 0 self._timer = Timer(timerId) self._shortPressHandler = None self._longPressHandler = None self._isTimeout = False def _onPinIrq(self, _): self._pin.irq(handler=None) self._timer.callback(None) self._timer.deinit() #debounce signal sleep_ms(50) if self._pin.value() == (1 if self._lowOnPress else 0): if not self._isTimeout: schedule(self._shortPressHandler, self) else: self._isTimeout = False self._timer.init(freq=1000 / self._thresholdTime, callback=self._onTimeout) self._pin.irq(handler=self._onPinIrq) def _onTimeout(self, t): t.deinit() self._isTimeout = True schedule(self._longPressHandler, self) def setShortPressHandler(self, handler): ''' Sets the handler for short press ''' self._shortPressHandler = handler return self def setLongPressHandler(self, handler): ''' Sets the handler for long press ''' self._longPressHandler = handler return self def cleanup(self): ''' Releases resources Deinits the timer and removes handler for the pin's IRQ ''' self._timer.deinit() self._pin.irq(handler=None)