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()
Esempio n. 2
0
 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
Esempio n. 3
0
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
Esempio n. 4
0
    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)
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 7
0
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())
Esempio n. 8
0
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())
Esempio n. 9
0
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())
Esempio n. 10
0
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()
Esempio n. 11
0
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
Esempio n. 12
0
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())
Esempio n. 13
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
Esempio n. 14
0
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())
Esempio n. 15
0
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)
Esempio n. 16
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
Esempio n. 17
0
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)