Beispiel #1
0
class RadPowerRail:
    def __init__(self, pgpin, analogpin=None):
        self.pg = DigitalInOut(pgpin)
        self.pg.switch_to_input(pull=Pull.UP)
        if analogpin:
            self.mon = AnalogIn(analogpin)
        else:
            self.mon = None
Beispiel #2
0
class DigitalIn(object):
  """Basic digital input."""

  def __init__(self, pin, pull=None):
    self._pin = DigitalInOut(pin)
    if pull == PULL_UP:
      self._pin.switch_to_input(pull=Pull.UP)
    elif pull == PULL_DOWN:
      self._pin.switch_to_input(pull=Pull.DOWN)
    else:
      self._pin.switch_to_input()

  def deinit(self):
    self._pin.deinit()

  @property
  def value(self):
    return self._pin.value
Beispiel #3
0
class SPI(_BitBangIO):
    """Software-based implementation of the SPI protocol over GPIO pins."""
    def __init__(self, clock, MOSI=None, MISO=None):
        """Initialize bit bang (or software) based SPI.  Must provide the SPI
        clock, and optionally MOSI and MISO pin numbers. If MOSI is set to None
        then writes will be disabled and fail with an error, likewise for MISO
        reads will be disabled.
        """
        super().__init__()

        while self.try_lock():
            pass

        self.configure()
        self.unlock()

        # Set pins as outputs/inputs.
        self._sclk = DigitalInOut(clock)
        self._sclk.switch_to_output()

        if MOSI is not None:
            self._mosi = DigitalInOut(MOSI)
            self._mosi.switch_to_output()

        if MISO is not None:
            self._miso = DigitalInOut(MISO)
            self._miso.switch_to_input()

    def configure(self, *, baudrate=100000, polarity=0, phase=0, bits=8):
        """Configures the SPI bus. Only valid when locked."""
        if self._check_lock():
            if not isinstance(baudrate, int):
                raise ValueError("baudrate must be an integer")
            if not isinstance(bits, int):
                raise ValueError("bits must be an integer")
            if bits < 1 or bits > 8:
                raise ValueError("bits must be in the range of 1-8")
            if polarity not in (0, 1):
                raise ValueError("polarity must be either 0 or 1")
            if phase not in (0, 1):
                raise ValueError("phase must be either 0 or 1")
            self._baudrate = baudrate
            self._polarity = polarity
            self._phase = phase
            self._bits = bits
            self._half_period = (1 / self._baudrate) / 2  # 50% Duty Cyle delay

    def _wait(self, start=None):
        """Wait for up to one half cycle"""
        while (start + self._half_period) > monotonic():
            pass
        return monotonic()  # Return current time

    def write(self, buffer, start=0, end=None):
        """Write the data contained in buf. Requires the SPI being locked.
        If the buffer is empty, nothing happens.
        """
        # Fail MOSI is not specified.
        if self._mosi is None:
            raise RuntimeError("Write attempted with no MOSI pin specified.")
        if end is None:
            end = len(buffer)

        if self._check_lock():
            start_time = monotonic()
            for byte in buffer[start:end]:
                for bit_position in range(self._bits):
                    bit_value = byte & 0x80 >> bit_position
                    # Set clock to base
                    if not self._phase:  # Mode 0, 2
                        self._mosi.value = bit_value
                    self._sclk.value = self._polarity
                    start_time = self._wait(start_time)

                    # Flip clock off base
                    if self._phase:  # Mode 1, 3
                        self._mosi.value = bit_value
                    self._sclk.value = not self._polarity
                    start_time = self._wait(start_time)

            # Return pins to base positions
            self._mosi.value = 0
            self._sclk.value = self._polarity

    # pylint: disable=too-many-branches
    def readinto(self, buffer, start=0, end=None, write_value=0):
        """Read into the buffer specified by buf while writing zeroes. Requires the SPI being
        locked. If the number of bytes to read is 0, nothing happens.
        """
        if self._miso is None:
            raise RuntimeError("Read attempted with no MISO pin specified.")
        if end is None:
            end = len(buffer)

        if self._check_lock():
            start_time = monotonic()
            for byte_position, _ in enumerate(buffer[start:end]):
                for bit_position in range(self._bits):
                    bit_mask = 0x80 >> bit_position
                    bit_value = write_value & 0x80 >> bit_position
                    # Return clock to base
                    self._sclk.value = self._polarity
                    start_time = self._wait(start_time)
                    # Handle read on leading edge of clock.
                    if not self._phase:  # Mode 0, 2
                        if self._mosi is not None:
                            self._mosi.value = bit_value
                        if self._miso.value:
                            # Set bit to 1 at appropriate location.
                            buffer[byte_position] |= bit_mask
                        else:
                            # Set bit to 0 at appropriate location.
                            buffer[byte_position] &= ~bit_mask
                    # Flip clock off base
                    self._sclk.value = not self._polarity
                    start_time = self._wait(start_time)
                    # Handle read on trailing edge of clock.
                    if self._phase:  # Mode 1, 3
                        if self._mosi is not None:
                            self._mosi.value = bit_value
                        if self._miso.value:
                            # Set bit to 1 at appropriate location.
                            buffer[byte_position] |= bit_mask
                        else:
                            # Set bit to 0 at appropriate location.
                            buffer[byte_position] &= ~bit_mask

            # Return pins to base positions
            self._mosi.value = 0
            self._sclk.value = self._polarity

    def write_readinto(self,
                       buffer_out,
                       buffer_in,
                       *,
                       out_start=0,
                       out_end=None,
                       in_start=0,
                       in_end=None):
        """Write out the data in buffer_out while simultaneously reading data into buffer_in.
        The lengths of the slices defined by buffer_out[out_start:out_end] and
        buffer_in[in_start:in_end] must be equal. If buffer slice lengths are
        both 0, nothing happens.
        """
        if self._mosi is None:
            raise RuntimeError("Write attempted with no MOSI pin specified.")
        if self._miso is None:
            raise RuntimeError("Read attempted with no MISO pin specified.")
        if out_end is None:
            out_end = len(buffer_out)
        if in_end is None:
            in_end = len(buffer_in)
        if len(buffer_out[out_start:out_end]) != len(
                buffer_in[in_start:in_end]):
            raise RuntimeError("Buffer slices must be equal length")

        if self._check_lock():
            start_time = monotonic()
            for byte_position, _ in enumerate(buffer_out[out_start:out_end]):
                for bit_position in range(self._bits):
                    bit_mask = 0x80 >> bit_position
                    bit_value = (buffer_out[byte_position + out_start]
                                 & 0x80 >> bit_position)
                    in_byte_position = byte_position + in_start
                    # Return clock to 0
                    self._sclk.value = self._polarity
                    start_time = self._wait(start_time)
                    # Handle read on leading edge of clock.
                    if not self._phase:  # Mode 0, 2
                        self._mosi.value = bit_value
                        if self._miso.value:
                            # Set bit to 1 at appropriate location.
                            buffer_in[in_byte_position] |= bit_mask
                        else:
                            # Set bit to 0 at appropriate location.
                            buffer_in[in_byte_position] &= ~bit_mask
                    # Flip clock off base
                    self._sclk.value = not self._polarity
                    start_time = self._wait(start_time)
                    # Handle read on trailing edge of clock.
                    if self._phase:  # Mode 1, 3
                        self._mosi.value = bit_value
                        if self._miso.value:
                            # Set bit to 1 at appropriate location.
                            buffer_in[in_byte_position] |= bit_mask
                        else:
                            # Set bit to 0 at appropriate location.
                            buffer_in[in_byte_position] &= ~bit_mask

            # Return pins to base positions
            self._mosi.value = 0
            self._sclk.value = self._polarity

    # pylint: enable=too-many-branches

    @property
    def frequency(self):
        """Return the currently configured baud rate"""
        return self._baudrate
class RunGo:

    groundColor_list = ((128, 128, 128), (255, 0, 0), (128, 128, 0),
                        (0, 255, 0), (0, 128, 128), (0, 0, 255), (128, 0, 128))
    groundColor_name = ('White', 'Red', 'Yellow', 'Green', 'Cyan', 'Blue',
                        'Purple')

    def __init__(self, enButtons=True):
        self._buttonA = None
        self._buttonB = None
        self._enbuttons = False
        if enButtons:
            self._enbuttons = True
            self._buttonA = DigitalInOut(board.IO43)
            self._buttonA.switch_to_input(pull=Pull.UP)
            self._db_buttonA = Debouncer(self._buttonA, 0.01, True)
            self._buttonB = DigitalInOut(board.IO44)
            self._buttonB.switch_to_input(pull=Pull.UP)
            self._db_buttonB = Debouncer(self._buttonB, 0.01, True)

        # 3x Neopixels RGB pixels: IO0
        self._pixels = neopixel.NeoPixel( board.IO0, 3,  \
                    brightness=0.5, auto_write=False, pixel_order=neopixel.GRB )
        self._colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]
        for i in range(3):
            self._pixels[i] = self._colors[i]
        self._pixels.show()
        self._pixelsRotationDt = 0.2
        self._pixelsRotationSt = time.monotonic()
        # Sense color Sensor (颜色传感器):  IO7
        self._colorSensor = AnalogIn(board.IO7)
        # Lighting Sensor (光强度传感器):  IO8--leftLightSensor, IO9--rightLightSensor
        self._leftLightSensor = AnalogIn(board.IO8)
        self._rightLightSensor = AnalogIn(board.IO9)
        # left and right head-LED: IO17--rightHeadLED, IO18--leftHeadLED
        self._leftHeadLED = DigitalInOut(board.IO18)
        self._leftHeadLED.direction = Direction.OUTPUT
        self._leftHeadLED.value = 0
        self._rightHeadLED = DigitalInOut(board.IO17)
        self._rightHeadLED.direction = Direction.OUTPUT
        self._rightHeadLED.value = 0
        # Ultrasonic module (超声波模块):  IO11--trig, IO10--echo
        self._timeout = 0.1
        self._trig = DigitalInOut(board.IO11)
        self._trig.direction = Direction.OUTPUT
        self._trig.value = 0
        if _USE_PULSEIO:
            self._echo = PulseIn(board.IO10)
            self._echo.pause()
            self._echo.clear()
        else:
            self._echo = DigitalInOut(board.IO10)
            self._echo.direction = Direction.INPUT
        # Tracking sensors (循迹传感器): IO4--rightTracker, IO3--rightTracker
        self._leftTracker = DigitalInOut(board.IO4)
        self._leftTracker.direction = Direction.INPUT
        self._rightTracker = DigitalInOut(board.IO3)
        self._rightTracker.direction = Direction.INPUT
        # Motor (Right):  IO41--rightMotor1IN, IO42--rightMotor2IN
        self._rightMotor1IN = PWMOut(board.IO41, frequency=100, duty_cycle=0)
        self._rightMotor2IN = PWMOut(board.IO42, frequency=100, duty_cycle=0)
        # Motor (Left):  IO12--leftMotor1IN, IO40--leftMotor2IN
        self._leftMotor1IN = PWMOut(board.IO12, frequency=100, duty_cycle=0)
        self._leftMotor2IN = PWMOut(board.IO40, frequency=100, duty_cycle=0)

    # state of button A
    @property
    def button_A(self):
        """ to check the state of Button-A on the RunGo
        
        this example to check the state of Button-A 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                if car.button_A:
                    print('A be pressed')
                time.sleep(0.05)
        """
        if self._enbuttons:
            return not self._buttonA.value
        else:
            return False

    # state of button B
    @property
    def button_B(self):
        """ to check the state of Button-B on the RunGo
        
        this example to check the state of Button-B 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                if car.button_B:
                    print('B be pressed')
                time.sleep(0.05)
        """
        if self._enbuttons:
            return not self._buttonB.value
        else:
            return False

    def buttons_update(self):
        """ to update the state of Button-A, and Button-B on the RunGo
        
        this example to update the state of Button-A, and Button-B 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.buttons_update()
                if car.button_A_wasPressed:
                    print('A be pressed')
                if car.button_B_wasPressed:
                    print('B be pressed')
        """
        if self._enbuttons:
            self._db_buttonA.read()
            self._db_buttonB.read()
        else:
            pass

    @property
    def button_A_wasPressed(self):
        """ to check the state of Button-A on the RunGo
        
        this example to check the state of Button-A 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.buttons_update()
                if car.button_A_wasPressed:
                    print('A be pressed')
        """
        if self._enbuttons:
            return self._db_buttonA.wasPressed
        else:
            return False

    @property
    def button_A_wasReleased(self):
        """ to check the state of Button-A on the RunGo
        
        this example to check the state of Button-A 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.buttons_update()
                if car.button_A_wasReleased:
                    print('A be released')
        """
        if self._enbuttons:
            return self._db_buttonA.wasReleased
        else:
            return False

    def button_A_pressedFor(self, t_s):
        """ to check the state of Button-A on the RunGo
        
        this example to check the state of Button-A 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.buttons_update()
                if car.button_A_pressedFor(2.0):
                    print('A be preased longly over 2.0 second')
        """
        if self._enbuttons:
            return self._db_buttonA.pressedFor(t_s)
        else:
            return False

    @property
    def button_B_wasPressed(self):
        """ to check the state of Button-B on the RunGo
        
        this example to check the state of Button-B 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.buttons_update()
                if car.button_B_wasPressed:
                    print('B be pressed')
        """
        if self._enbuttons:
            return self._db_buttonB.wasPressed
        else:
            return False

    @property
    def button_B_wasReleased(self):
        """ to check the state of Button-B on the RunGo
        
        this example to check the state of Button-B 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.buttons_update()
                if car.button_B_wasReleased:
                    print('B be released')
        """
        if self._enbuttons:
            return self._db_buttonB.wasReleased
        else:
            return False

    def button_B_pressedFor(self, t_s):
        """ to check the state of Button-B on the RunGo
        
        this example to check the state of Button-B 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.buttons_update()
                if car.button_B_pressedFor(2.0):
                    print('B be preased longly over 2.0 second')
        """
        if self._enbuttons:
            return self._db_buttonB.pressedFor(t_s)
        else:
            return False

    @property
    def pixels(self):
        """ to control the pixels[0..2] on the bottom of RunGo
        
        this example to control the color of three RGB LEDs 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            colors = [(255,0,0), (0,255,0), (0,0,255)]
            while True:
                for i in range(3):
                    car.pixels[i] = colors[i]
                car.pixels.show()
                # round colors
                tc = colors[0]
                colors[0] = colors[1]
                colors[1] = colors[2]
                colors[2] = tc
                time.sleep(0.5)
        """
        return self._pixels

    @property
    def pixelsColor(self):
        c = (self._colors[0], self._colors[1], self._colors[2])
        return c

    @pixelsColor.setter
    def pixelsColor(self, colors):
        ln = min(len(colors), 3)
        for i in range(ln):
            self._pixels[i] = colors[i]
            self._colors[i] = colors[i]
        self._pixels.show()

    def pixelsRotation(self, dt=None):
        if not dt == None:
            self._pixelsRotationDt = dt
        et = time.monotonic()
        if (et - self._pixelsRotationSt) >= self._pixelsRotationDt:
            self._pixelsRotationSt = et
            tc = self._colors[0]
            self._colors[0] = self._colors[1]
            self._colors[1] = self._colors[2]
            self._colors[2] = tc
            for i in range(3):
                self._pixels[i] = self._colors[i]
            self._pixels.show()

    def motor(self, lspeed=50, rspeed=-50):
        """ Dual DC-Motor control interface to achieve forward, backward, turn left and turn right
        
        this example to demostrate car forward, backward, turn left and turn right
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            car.motor(50, 50)   # forward with 50 speed (max-speed: 255)
            time.sleep(1.2)     # runing time (1.2s)
            car.motor(-50, -50) # backward with 50 speed (max-speed: 255)
            time.sleep(1.2)     # runing time (1.2s)
            car.motor(-50, 50)  # turn left with car center
            time.sleep(2.0)     # runing time (2s)
            car.motor(50, -50)  # turn right with car center
            time.sleep(2.0)     # runing time (2s)
            car.stop()
            print("program done!")
        """
        lspeed = min(lspeed, 255)
        lspeed = max(-255, lspeed)
        ldir = 0x01 if lspeed < 0 else 0x00  # 正反转: 0x00,CCW, 0x01,CW
        lspeed = abs(lspeed)
        lspeed = lspeed * 255  # 0~65535
        rspeed = min(rspeed, 255)
        rspeed = max(-255, rspeed)
        rdir = 0x01 if rspeed < 0 else 0x00  # 正反转: 0x00,CCW, 0x01,CW
        rspeed = abs(rspeed)
        rspeed = rspeed * 255  # 0~65535
        if rdir == 0x01:
            self._rightMotor2IN.duty_cycle = rspeed
            self._rightMotor1IN.duty_cycle = 0
        if rdir == 0x0:
            self._rightMotor1IN.duty_cycle = rspeed
            self._rightMotor2IN.duty_cycle = 0
        if ldir == 0x01:
            self._leftMotor1IN.duty_cycle = lspeed
            self._leftMotor2IN.duty_cycle = 0
        if ldir == 0x0:
            self._leftMotor2IN.duty_cycle = lspeed
            self._leftMotor1IN.duty_cycle = 0

    def moveTime(self, mtdir=0, mtspeed=50, mt=2.0):
        """ Dual DC-Motor control interface to achieve forward, backward, turn left and turn right
        
        this example to demostrate car forward, backward, turn left and turn right
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            car.moveTime(0, 50, 1.2)   # forward with 50 speed, and running 1.2s
            car.moveTime(1, 50, 1.2)   # backward with 50 speed, and running 1.2s
            car.moveTime(2, 50, 2.0)   # turn left with car center, , and running 2.0s
            car.moveTime(3, 50, 2.0)   # turn right with car center, , and running 2.0s
            print("program done!")
        """
        if mtdir >= 0 and mtdir <= 3:
            self.move(mtdir, mtspeed)
            time.sleep(mt)
            self.motor(0, 0)

    def move(self, mdir=0, mspeed=50):
        """ Dual DC-Motor control interface to car move(forward, backward, turn left and turn right)
        
        this example to demostrate car move 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            car.move(0, 50)   # forward with 50 speed, and running 1.2s
            time.sleep(1.2)   # runing time (1.2s)
            car.move(1, 50)   # backward with 50 speed, and running 1.2s
            time.sleep(1.2)   # runing time (1.2s)
            car.move(2, 50)   # turn left with car center, , and running 2.0s
            time.sleep(2.0)   # runing time (2.0s)
            car.move(3, 50)   # turn right with car center, , and running 2.0s
            time.sleep(2.0)   # runing time (2.0s)
            car.stop()
            print("program done!")
        """
        sp = abs(mspeed)
        if mdir == 0:  # Forward
            self.motor(sp, sp)
        elif mdir == 1:  # Backward
            self.motor(-sp, -sp)
        elif mdir == 2:  # Rotate-Left
            self.motor(-sp, sp)
        elif mdir == 3:  # Rotate-Right
            self.motor(sp, -sp)

    def stop(self):
        # stop car
        self.motor(0, 0)

    @property
    def leftLightSensor(self):
        """ get the brightness value of the left-lighting-sensor
        
        this example to get the brightness of left lighting sensor 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                print(car.leftLightSensor)
                time.sleep(0.5)
        """
        return self._leftLightSensor.value

    @property
    def rightLightSensor(self):
        """ get the brightness value of the right-lighting-sensor
        
        this example to get the brightness of right lighting sensor 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                print(car.rightLightSensor)
                time.sleep(0.5)
        """
        return self._rightLightSensor.value

    def _getRawRGB_light(self):
        __colorComps = ((255, 0, 0), (0, 255, 0), (0, 0, 255))
        __bt = self._pixels.brightness
        self._pixels.brightness = 1.0
        self._pixels.fill(0x0)
        self._pixels.show()
        __Craw = [0, 0, 0]
        i = 0
        for cc in __colorComps:
            self.pixels[0] = cc
            self.pixels.show()
            time.sleep(0.1)
            __Craw[i] = int(self._colorSensor.value * 255 // (2**16))
            i += 1
            self._pixels.fill(0x0)
            self._pixels.show()
            time.sleep(0.1)
        self._pixels.brightness = __bt
        return __Craw[0], __Craw[1], __Craw[2]

    @staticmethod
    def _rgb2hsv(r, g, b):
        __rR, __rG, __rB = r / 255, g / 255, b / 255
        __Cmax, __Cmin = max(__rR, __rG, __rB), min(__rR, __rG, __rB)
        __Cdelta = __Cmax - __Cmin
        V = __Cmax  # HSV: Value
        if __Cmax == 0.0:
            S = 0.0  # HSV: Saturation
        else:
            S = __Cdelta / __Cmax  # HSV: Saturation
        if __Cdelta == 0.0:
            H = 0  # HSV: Hue
        elif __Cmax == __rR:
            H = 60 * (((__rG - __rB) / __Cdelta) % 6)  # HSV: Hue [--Red++]
        elif __Cmax == __rG:
            H = 60 * (((__rB - __rR) / __Cdelta) + 2)  # HSV: Hue [--Green++]
        else:
            H = 60 * (((__rR - __rG) / __Cdelta) + 4)  # HSV: Hue [--Blue++]
        H = int(H)
        return H, S, V

    @property
    def groundColorID(self):
        rawR, rawG, rawB = self._getRawRGB_light()
        H, S, V = self._rgb2hsv(rawR, rawG, rawB)
        if S < 0.075:
            return 0  # white
        if H < 30 or H >= 330:  # 330~359, 0~29
            return 1  # red
        elif H >= 30 and H < 90:  # 30~89
            return 2  # yellow
        elif H >= 90 and H < 150:  # 90~149
            return 3  # green
        elif H >= 150 and H < 210:  # 150~209
            return 4  # cyan
        elif H >= 210 and H < 270:  # 210~269
            return 5  # blue
        else:  # 270~329
            return 6  # purple

    @property
    def groundColor(self):
        return self.groundColor_name[self.groundColorID]

    @property
    def groundColorValue(self):
        return self.groundColor_list[self.groundColorID]

    @property
    def leftHeadLED(self):
        """ get the status value of the left-head-led
        
        this example to get the state of left head LED 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.leftHeadLED = not car.leftHeadLED
                time.sleep(0.5)
        """
        return self._leftHeadLED.value

    @leftHeadLED.setter
    def leftHeadLED(self, value):
        """ to control the left-head-led on or off
        
        this example to control the state of left head LED 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.leftHeadLED = not car.leftHeadLED
                time.sleep(0.5)
        """
        self._leftHeadLED.value = value

    @property
    def rightHeadLED(self):
        """ get the status value of the right-head-led
        
        this example to get the state of right head LED 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.rightHeadLED = not car.rightHeadLED
                time.sleep(0.5)
        """
        return self._rightHeadLED.value

    @rightHeadLED.setter
    def rightHeadLED(self, value):
        """ to control the right-head-led on or off
        
        this example to control the state of right head LED 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                car.rightHeadLED = not car.rightHeadLED
                time.sleep(0.5)
        """
        self._rightHeadLED.value = value

    @property
    def distance(self):
        """Return the distance measured by the sensor in cm.
        
        This is the function that will be called most often in user code. The
        distance is calculated by timing a pulse from the sensor, indicating
        how long between when the sensor sent out an ultrasonic signal and when
        it bounced back and was received again.
        
        If no signal is received, we'll throw a RuntimeError exception. This means
        either the sensor was moving too fast to be pointing in the right
        direction to pick up the ultrasonic signal when it bounced back (less
        likely), or the object off of which the signal bounced is too far away
        for the sensor to handle. In my experience, the sensor can detect
        objects over 460 cm away.
        
        :return: Distance in centimeters.
        :rtype: float
        this example to control the state of right head LED 
        
        To use with the IoTs2:
        
        .. code-block:: python
            
            import time
            from hiibot_iots2_rungo import RunGo
            car = RunGo()
            while True:
                print(car.distance)
                time.sleep(0.5)
        """
        return self._dist_two_wire(
        )  # at this time we only support 2-wire meausre

    def _dist_two_wire(self):
        if _USE_PULSEIO:
            self._echo.clear()  # Discard any previous pulse values
        self._trig.value = True  # Set trig high
        time.sleep(0.00001)  # 10 micro seconds 10/1000/1000
        self._trig.value = False  # Set trig low
        pulselen = 65535
        ok_echo = True
        timestamp = time.monotonic()
        if _USE_PULSEIO:
            self._echo.resume()
            while not self._echo:
                # Wait for a pulse
                if (time.monotonic() - timestamp) > self._timeout:
                    self._echo.pause()
                    ok_echo = False
                    break  # output a error result vs stop running
                    #raise RuntimeError("Timed out")
            self._echo.pause()
            if ok_echo:
                pulselen = self._echo[0]
        else:
            # OK no hardware pulse support, we'll just do it by hand!
            # hang out while the pin is low
            while not self._echo.value:
                if time.monotonic() - timestamp > self._timeout:
                    break
                    #raise RuntimeError("Timed out")
            timestamp = time.monotonic()
            # track how long pin is high
            while self._echo.value:
                if time.monotonic() - timestamp > self._timeout:
                    break
                    #raise RuntimeError("Timed out")
            pulselen = time.monotonic() - timestamp
            pulselen *= 1000000  # convert to us to match pulseio
        if pulselen >= 65535:
            ok_echo = False
            #raise RuntimeError("Timed out")

        # positive pulse time, in seconds, times 340 meters/sec, then
        # divided by 2 gives meters. Multiply by 100 for cm
        # 1/1000000 s/us * 340 m/s * 100 cm/m * 2 = 0.017
        return pulselen * 0.017

    @property
    def leftTracker(self):
        """
        return l sensor status: True/1, no-reflected signal, maybe just above the black line
                                False/0, the state of the reflected signal
        """
        return self._leftTracker.value

    @property
    def rightTracker(self):
        """
        return r sensor status: True/1, no-reflected signal, maybe just above the black line
                                False/0, the state of the reflected signal
        """
        return self._rightTracker.value

    def tracking(self, lr_mode=0):
        """
        lr_mode: 0, the width of back-line greater than the width between the l and r sensors 
                 3, the width of white-line greater than the width between the l and r sensors
                 1, a barrow back-line be used, and l sensor be used to track
                 2, a barrow back-line be used, and r sensor be used to track
        """
        if lr_mode == 0:
            return self._leftTracker.value and self._rightTracker.value
        elif lr_mode == 1:
            return self._leftTracker.value and not self._rightTracker.value
        elif lr_mode == 2:
            return not self._leftTracker.value and self._rightTracker.value
        elif lr_mode == 3:
            return not self._leftTracker.value and not self._rightTracker.value
        else:
            return False

    def trackSide(self, side=0, lr_mode=1):
        if side == 0 and lr_mode == 0:
            return self._leftTracker.value
        elif side == 0 and lr_mode == 1:
            return not self._leftTracker.value
        elif side == 1 and lr_mode == 0:
            return not self._rightTracker.value
        elif side == 1 and lr_mode == 1:
            return self._rightTracker.value
        else:
            return False
def log_info(*args):
    # out = " ".join([arg if type(arg) == str else repr(arg) for arg in args]) + "\r\n"
    # usb_cdc.data.write(out.encode("utf8"))
    if usb_cdc.console is None and usb_cdc.data is None:
        pass
    else:
        print(*args)


####################################################################
# setup buttons
####################################################################

butA = DigitalInOut(board.IO38)
butA.switch_to_input(Pull.DOWN)
butB = DigitalInOut(board.IO33)
butB.switch_to_input(Pull.DOWN)
but1 = DigitalInOut(board.IO6)
but1.switch_to_input(Pull.DOWN)
but2 = DigitalInOut(board.IO5)
but2.switch_to_input(Pull.DOWN)

buttons = [
    [butA, "BUTA"],
    [butB, "BUTB"],
    [but1, "BUT1"],
    [but2, "BUT2"],
]

####################################################################
Beispiel #6
0
class ESP32:
    """Class to manage ESP32 running NINA firmware for WiFi or Bluetooth."""

    NOT_IN_USE = 0
    """Not currently being used."""
    BOOTLOADER = 1
    """Put ESP32 into bootloader mode."""
    BLUETOOTH = 2
    """HCI Bluetooth mode."""
    WIFI = 3
    """WiFi mode."""
    _MODES = (NOT_IN_USE, BOOTLOADER, BLUETOOTH, WIFI)

    # pylint: disable=invalid-name
    def __init__(self,
                 *,
                 reset: Optional[Pin] = None,
                 reset_high: bool = False,
                 gpio0: Optional[Pin] = None,
                 busy: Optional[Pin] = None,
                 chip_select: Optional[Pin] = None,
                 tx: Optional[Pin] = None,
                 rx: Optional[Pin] = None,
                 spi: Optional[SPI] = None):
        """Create an ESP32 instance, passing the objects needed to reset and communicate
        with the adapter.

        :param reset ~microcontroller.Pin: ESP32 RESET pin.
           If `None`, use ``board.ESP_RESET``.
        :param reset_high bool: True if `reset` is brought high to reset;
            `False` if brought low.
        :param gpio0 ~microcontroller.Pin: ESP32 GPIO0 pin.
           Used for ESP32 boot selection when reset, and as RTS for UART communication.
           If `None`, use ``board.ESP_GPIO0``.
        :param busy ~microcontroller.Pin: ESP32 BUSY pin (sometimes called READY).
           Used as CTS indicator for UART communication.
           If `None`, use ``board.ESP_BUSY``.
        :param chip_select ~microcontroller.Pin: ESP32 CS (chip select) pin.
            Also used for ESP32 mode selection when reset.
            If `None`, use ``board.ESP_CS``.
        :param tx ~microcontroller.Pin: ESP32 TX pin for Bluetooth UART communication.
           If `None`, use ``board.ESP_TX`` when in Bluetooth mode.
        :param rx ~microcontroller.Pin: ESP32 RX pin for Bluetooth UART communication.
           If `None`, use ``board.ESP_RX`` when in Bluetooth mode.
        :param spi busio.SPI: Used for communication with the ESP32.
          If not supplied, ``board.SPI()`` is used when in WiFi mode.
        """
        self._mode = ESP32.NOT_IN_USE

        # We can't use board.ESP_RESET, etc. as defaults, because they may not exist.
        self._reset = DigitalInOut(reset or board.ESP_RESET)
        # Turn off ESP32 by holding reset line
        self._reset.switch_to_output(reset_high)
        self._reset_high = reset_high

        # These will be set to input or input as necessary.
        self._gpio0_rts = DigitalInOut(gpio0 or board.ESP_GPIO0)
        self._busy_cts = DigitalInOut(busy or board.ESP_BUSY)
        self._chip_select = DigitalInOut(chip_select or board.ESP_CS)

        # Used for Bluetooth mode.
        self._tx = tx
        self._rx = rx
        self._uart = None
        self._bleio_adapter = None

        # Used for WiFi mode.
        self._spi = spi

    def reset(self, mode: int, debug: bool = False) -> None:
        """Do hard reset of the ESP32.

        :param mode: One of `ESP32.NOT_IN_USE`, `ESP32.BOOTLOADER`, `ESP32.BLUETOOTH`, `ESP32.WIFI`.
        """
        if mode not in ESP32._MODES:
            raise ValueError("Invalid mode")

        # GPIO0 high means boot from SPI flash.
        # Low means go into bootloader mode.
        self._gpio0_rts.switch_to_output(mode != ESP32.BOOTLOADER)

        if mode == ESP32.NOT_IN_USE:
            # Turn of ESP32 by holding reset line.
            self._reset.switch_to_output(self._reset_high)
            self._mode = mode
            return

        if mode == ESP32.BLUETOOTH:
            self._chip_select.switch_to_output(False)
        elif mode == ESP32.WIFI:
            self._chip_select.switch_to_output(True)

        # Initial mode. Changed if reset is successful.
        self._mode = ESP32.NOT_IN_USE

        # Reset by toggling reset pin for 100ms
        self._reset.switch_to_output(self._reset_high)
        time.sleep(0.1)
        self._reset.value = not self._reset_high

        #  Wait 1 second for startup.
        time.sleep(1.0)

        if mode == ESP32.BOOTLOADER:
            # No startup message expected.
            return

        startup_message = b""
        while self._uart.in_waiting:  # pylint: disable=no-member
            more = self._uart.read()
            if more:
                startup_message += more

        if not startup_message:
            raise RuntimeError("ESP32 did not respond with a startup message")
        if debug:
            try:
                print(startup_message.decode("utf-8"))
            except UnicodeError:
                raise RuntimeError(
                    "Garbled ESP32 startup message") from UnicodeError

        # Everything's fine. Remember mode.
        self._mode = mode

    # pylint: disable=invalid-name
    def start_bluetooth(self, debug: bool = False) -> Adapter:
        """Set up the ESP32 in HCI Bluetooth mode, if it is not already doing something else.

        :param debug bool: Print out some debugging information.
        :return: A `_bleio.Adapter`, to be passed to ``_bleio.set_adapter()``.
        """
        # Will fail with ImportError if _bleio is not on the board.
        # That exception is probably good enough.
        # pylint: disable=import-outside-toplevel
        import _bleio

        if self._mode == ESP32.BLUETOOTH:
            # Already started.
            return _bleio.adapter

        if self._mode == ESP32.WIFI:
            raise RuntimeError("ESP32 is in WiFi mode; use stop_wifi() first")

        # Choose Bluetooth mode.
        self._chip_select.switch_to_output(False)

        self._uart = busio.UART(
            self._tx or board.ESP_TX,
            self._rx or board.ESP_RX,
            baudrate=115200,
            timeout=0,
            receiver_buffer_size=512,
        )

        # Reset into Bluetooth mode.
        self.reset(ESP32.BLUETOOTH, debug=debug)

        self._busy_cts.switch_to_input()
        self._gpio0_rts.switch_to_output()
        # pylint: disable=no-member
        # pylint: disable=unexpected-keyword-arg
        self._bleio_adapter = _bleio.Adapter(uart=self._uart,
                                             rts=self._gpio0_rts,
                                             cts=self._busy_cts)
        self._bleio_adapter.enabled = True
        return self._bleio_adapter

    def stop_bluetooth(self):
        """Stop Bluetooth on the ESP32. Deinitialize the ~busio.UART used for communication"""
        if self._mode != ESP32.BLUETOOTH:
            return
        self._bleio_adapter.enabled = False
        self.reset(ESP32.NOT_IN_USE)
        self._uart.deinit()
        self._uart = None

    def start_wifi(self, debug: bool = False) -> SPI:
        """Start WiFi on the ESP32.

        :return: the ``busio.SPI`` object that will be used to communicate with the ESP32.
        :rtype: busio.SPI
        """
        if self._mode == ESP32.WIFI:
            # Already started.
            return self._spi

        if self._mode == ESP32.BLUETOOTH:
            raise RuntimeError(
                "ESP32 is in Bluetooth mode; use stop_bluetooth() first")

        self.reset(ESP32.WIFI, debug=debug)
        if self._spi is None:
            self._spi = board.SPI()
        return self._spi

    def stop_wifi(self):
        """Stop WiFi on the ESP32.
        The `busio.SPI` object used is not deinitialized, since it may be in use for other devices.
        """
        if self._mode != ESP32.WIFI:
            return
        self.reset(ESP32.NOT_IN_USE)
Beispiel #7
0
try:
    import board
    from digitalio import DigitalInOut
    import adafruit_dotstar
except ImportError:
    print(
        "Blinka not installed? Run 'pip3 install adafruit-circuitpython-dotstar'"
    )
    raise ImportError(
        "Blinka not installed? Run 'pip3 install adafruit-circuitpython-dotstar'"
    )

# Setup button
button = DigitalInOut(board.D17)
button.switch_to_input()

# Setup DotStar LEDs
dots = adafruit_dotstar.DotStar(
    board.D6,
    board.D5,
    3,
    auto_write=True,
    brightness=0.2,
    pixel_order=adafruit_dotstar.BGR,
)
dots.fill(0x000000)

ASSISTANT_API_ENDPOINT = "embeddedassistant.googleapis.com"
END_OF_UTTERANCE = embedded_assistant_pb2.AssistResponse.END_OF_UTTERANCE
DIALOG_FOLLOW_ON = embedded_assistant_pb2.DialogStateOut.DIALOG_FOLLOW_ON
Beispiel #8
0
}

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise
print("Matrix Clock Plus")

# --- Display setup ---
matrix = Matrix()
display = matrix.display
network = Network(status_neopixel=board.NEOPIXEL, debug=False)
button_down = DigitalInOut(board.BUTTON_DOWN)
button_down.switch_to_input(pull=Pull.UP)
button_up = DigitalInOut(board.BUTTON_UP)
button_up.switch_to_input(pull=Pull.UP)

# --- Weather data setup ---
UNITS = "imperial"
DATA_LOCATION = []
DATA_SOURCE = ("http://api.openweathermap.org/data/2.5/weather?q=" +
               secrets["openweather_loc"] + "&units=" + UNITS)
DATA_SOURCE += "&appid=" + secrets["openweather_token"]
current_temp = '0'

# --- Drawing setup ---
group = displayio.Group(max_size=4)  # Create a Group
bitmap = displayio.Bitmap(64, 32,
                          len(color_codes) +
from digitalio import DigitalInOut, Pull
import touchio

print("NeoKey Trinkey HID")

# create the pixel and turn it off
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.1)
pixel.fill(0x0)

time.sleep(1)  # Sleep for a bit to avoid a race condition on some systems
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)  # We're in the US :)

# create the switch, add a pullup, start it with not being pressed
button = DigitalInOut(board.SWITCH)
button.switch_to_input(pull=Pull.DOWN)
button_state = False

# create the captouch element and start it with not touched
touch = touchio.TouchIn(board.TOUCH)
touch_state = False

# print a string on keypress
key_output = "Hello World!\n"

# one character on keypress
# key_output = Keycode.A

# multiple simultaneous keypresses
# key_output = (Keycode.SHIFT, Keycode.A)  # capital A
# key_output = (Keycode.CONTROL, Keycode.ALT, Keycode.DELETE) # three finger salute!
Beispiel #10
0
# Set up keyboard
kbd = Keyboard(usb_hid.devices)

# LED setup, G=Green B=BLUE
ledG = DigitalInOut(board.GP14)
ledB = DigitalInOut(board.GP15)

# LED direction
ledG.direction = Direction.OUTPUT
ledB.direction = Direction.OUTPUT

# Set switch and direction\
switch = []
for x in range(13):
    temp = DigitalInOut(getattr(board,f"GP{x}"))
    temp.switch_to_input(Pull.UP)
    switch.append(temp)
    continue

while True:
    # We could also do "led.value = not switch.value"!
    if switch[0].value:
        ledB.value = False
    else:
        ledB.value = True
        kbd.send(Keycode.F13)
        time.sleep(0.1)
        kbd.release(Keycode.F13)
        
    if switch[1].value:
        ledB.value = False
class Ohmite:
    """
    Types: 0 = round, 1 = long , 2 = short
    """

    # expect _wiper, _ref, _v_1, _v_2, _v_3, _type=0):
    # or _wiper, _ref, _v_1, _v_2,  _type=(1/2):
    #
    def __init__(self, *args, **kwargs):
        if "type" in kwargs:
            self._type = kwargs["type"]
        else:
            self._type = 0

        self._ref = DigitalInOut(args[1])
        self._ANALOG_RESOLUTION = 65536
        self._VOLTAGE = 3.3
        if self._type == 0:  # this is a round sensor
            self._ZERO_OFFSET = 800
            self._READ_RANGE = 1450
            self._wiper = AnalogIn(args[0])
            self._d0 = DigitalInOut(args[2])
            self._d120 = DigitalInOut(args[3])
            self._d240 = DigitalInOut(args[4])
            self._ZERO_OFFSET = 800
            self._READ_RANGE = 1450
            self._LENGTH = 120
        else:  # this is a linear sensor
            self._wiper_pin = args[0]
            self._wiper = DigitalInOut(args[0])
            self._v1 = DigitalInOut(args[2])
            self._v2 = DigitalInOut(args[3])
            if self._type == 1:
                self._ZERO_OFFSET = 200
                self._READ_RANGE = 2600
                self._LENGTH = 100
            else:
                self._ZERO_OFFSET = 500
                self._READ_RANGE = 1900
                self._LENGTH = 55
        # print(args, kwargs)

    def begin(self):
        if self._type == 0:
            self._ref.direction = Direction.OUTPUT
            self._ref.value = 1
            self._d0.direction = Direction.OUTPUT
            self._d0.value = 1
            self._d120.direction = Direction.OUTPUT
            self._d120.value = 1
            self._d240.direction = Direction.OUTPUT
            self._d240.value = 0
        else:
            self._v1.direction = Direction.OUTPUT
            self._v1.value = 0
            self._v2.direction = Direction.OUTPUT
            self._v2.value = 0
            self._wiper.direction = Direction.OUTPUT
            self._wiper.value = 0
            self._ref.direction = Direction.OUTPUT
            self._ref.value = 0

    # Generic command
    def get_position(self, tail_to_tip=True):
        if self._type == 0:
            return self._get_round_position()
        if self._type == 1 or self._type == 2:
            return self._get_linear_position(tail_to_tip)

    def get_force(self):
        if self._type == 0:
            return self._get_round_force()
        if self._type == 1 or self._type == 2:
            return self._get_linear_force()

    # Linear sensors
    def _get_linear_position(self, tail_to_tip=True):
        self._wiper.deinit()
        l_wiper = AnalogIn(self._wiper_pin)
        self._ref.switch_to_input(pull=Pull.DOWN)

        if tail_to_tip:  # Read from tail end
            self._v1.value = 1
            time.sleep(0.001)
            value = self._get_voltage(l_wiper)
            self._v1.value = 0
        else:
            self._v2.value = 1
            time.sleep(0.001)
            value = self._get_voltage(l_wiper)
            self._v2.value = 0

        l_wiper.deinit()
        self._wiper = DigitalInOut(self._wiper_pin)
        self._wiper.direction = Direction.OUTPUT
        self._wiper.value = 0
        self._ref.switch_to_output(value=False)
        return self._get_millimeters(value)

    def _get_millimeters(self, voltage):
        value = int((((voltage * 1000) - self._ZERO_OFFSET) * self._LENGTH) /
                    self._READ_RANGE)
        if value < 0:
            value = 0
        if value > self._LENGTH:
            value = self._LENGTH
        return value

    # this is method 3 from the implementation guide.
    # Section 4.2.3, page 5
    # https://www.mouser.com/pdfdocs/Ohmite-FSP-Integration-Guide-V1-0_27-03-18.pdf
    def _get_linear_force(self):
        self._wiper.deinit()
        l_wiper = AnalogIn(self._wiper_pin)
        self._ref.value = 0
        self._v1.switch_to_output(value=True)
        self._v2.switch_to_input()
        time.sleep(0.001)
        wiper_1 = l_wiper.value

        self._v2.switch_to_output(value=True)
        self._v1.switch_to_input()
        time.sleep(0.001)
        wiper_2 = l_wiper.value

        l_wiper.deinit()
        self._wiper = DigitalInOut(self._wiper_pin)
        self._wiper.direction = Direction.OUTPUT
        self._wiper.value = 0
        self._v1.direction = Direction.OUTPUT
        self._v1.value = 0
        self._v2.value = 0

        return ((
            (wiper_1 + wiper_2) / 2) * self._VOLTAGE) / self._ANALOG_RESOLUTION

    # Round sensor helpers

    def _calc_position(self, low, high, off):
        # off should be the DX pin  Disable
        off.switch_to_input()
        high.value = 1
        low.value = 0
        time.sleep(0.001)
        wiper_v = self._get_voltage(self._wiper)
        # print(wiper_v)
        # Convert to milli volts and apply offsets to wiper_v
        _angle = ((((wiper_v * 1000) - self._ZERO_OFFSET) * self._LENGTH) /
                  self._READ_RANGE)
        # print(angle)
        # off should be reset to output
        off.switch_to_output(value=False)

        return int(_angle)

    def _get_round_position(self):
        # Read analog voltage on D 1
        self._d0.value = 1
        self._d120.value = 1
        self._d240.value = 0
        time.sleep(0.001)
        d3 = self._wiper.value

        self._d0.value = 0
        self._d120.value = 1
        self._d240.value = 1
        time.sleep(0.001)
        d1 = self._wiper.value

        self._d0.value = 1
        self._d120.value = 0
        self._d240.value = 1
        time.sleep(0.001)
        d2 = self._wiper.value

        _angle = 0
        # which voltage is the lowest:
        # print(d1, d2, d3, f1)
        if d1 < d2 and d1 < d3:
            if d2 < d3:
                # d1 and d2
                # print ("d1:d2")
                _angle = self._calc_position(self._d0, self._d120, self._d240)
            else:
                # d1 and d3
                # print("d1:d3")
                _angle = self._calc_position(self._d240, self._d0, self._d120)
                _angle = _angle + 240

        if d2 < d1 and d2 < d3:
            if d1 < d3:
                # print ("d2:d1")
                _angle = self._calc_position(self._d0, self._d120, self._d240)
            else:
                # print ("d2:d3")
                _angle = self._calc_position(self._d120, self._d240, self._d0)
                _angle = _angle + 120

        if d3 < d1 and d3 < d2:
            if d1 < d2:
                # print ("d3:d1")
                _angle = self._calc_position(self._d240, self._d0, self._d120)
                _angle = _angle + 240
            else:
                # print ("d3:d2")
                _angle = self._calc_position(self._d120, self._d240, self._d0)
                _angle = _angle + 120

        if _angle < 0 or _angle > 360:
            _angle = 0

        return _angle

    def _get_round_force(self):
        # read force
        self._d0.value = 1
        self._d120.value = 1
        self._d240.value = 1
        self._ref.switch_to_output(value=False)
        time.sleep(0.001)
        _f = self._get_voltage(self._wiper)
        self._ref.switch_to_input()
        return _f

    def _get_voltage(self, pin):
        return (pin.value * self._VOLTAGE) / self._ANALOG_RESOLUTION
Beispiel #12
0
import adafruit_requests as requests
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_esp32spi import adafruit_esp32spi
import busio
from secrets import secrets

esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

water_sensor = AnalogIn(board.A0)
force_sensor = AnalogIn(board.A1)
button = DigitalInOut(board.D12)
button.switch_to_input(pull=Pull.UP)
switch = DigitalInOut(board.D7)
switch.direction = Direction.OUTPUT
switch.value = False
transistorOutput = AnalogIn(board.A5)

requests.set_socket(socket, esp)

#if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
#    print("ESP32 found and in idle mode")
#print("Firmware vers.", esp.firmware_version)
#print("MAC addr:", [hex(i) for i in esp.MAC_address])

#for ap in esp.scan_networks():
#    print("\t%s\t\tRSSI: %d" % (str(ap["ssid"], "utf-8"), ap["rssi"]))
Beispiel #13
0
class RadJTAG:
    def __init__(self, fn="radboot.bin"):
        self.fn = fn
        self.tck = DigitalInOut(board.TCK)
        self.tms = DigitalInOut(board.TMS)
        self.tdi = DigitalInOut(board.TDI)
        self.tdo = DigitalInOut(board.TDO)
        self.tck.switch_to_output(value=False)
        self.tms.switch_to_output(value=False)
        self.tdi.switch_to_output(value=False)
        self.tdo.switch_to_input()

    def clock(self, tdi=False):
        self.tdi.value = tdi
        self.tck.value = True
        self.tck.value = False

    def idcode(self):
        self.tms.value = True
        self.clock()
        # select-DR
        self.tms.value = False
        self.clock()
        # capture-DR
        self.clock()
        # now in shift-DR.
        # Data appears on TDO *now*
        # data is clocked into TDI *at next clock*
        val = 0
        for i in range(32):
            val |= int(self.tdo.value) << i
            # could exit at 32 here if I felt like it
            self.clock()
        self.tms.value = True
        self.clock()
        self.clock()
        self.tms.value = False
        self.clock()
        return val

    def shiftir(self, value):
        # assume we start in RTI
        self.tms.value = True
        self.clock()
        # Select-DR
        self.clock()
        # Select-IR
        self.tms.value = False
        self.clock()
        # capture-ir
        self.clock()
        # shift-ir
        for i in range(5):
            self.clock(value & 0x1)
            value = value >> 1
        self.tms.value = True
        self.clock(value & 0x1)
        # exit1-IR : now go to RTI
        self.clock()
        # update-IR
        self.tms.value = False
        self.clock()
        # RTI

    def begin(self):
        # TLR
        self.tms.value = True
        self.tdi.value = True
        for i in range(5):
            self.clock()
        # go to RTI
        self.tms.value = False
        self.tdi.value = False
        self.clock()

    def config(self):
        # Config sequence is simple, just:
        # JPROGRAM
        self.shiftir(0x0b)
        # NOOP
        self.shiftir(0x14)
        # wait at least 0.1 sec
        time.sleep(0.1)
        # Can shift in 0x14 and look
        # at the IR output. As far as I can
        # tell, Xilinx just checks
        # DONE=0 and INIT=1.
        # now shift in CONFIG
        self.shiftir(0x05)
Beispiel #14
0
class Locomotive(Drivetrain):
    """This class relies soley on one `Solenoid` object controlling 2 solenoids in tandem. Like
    with a locomotive train, applied force is alternated between the 2 solenoids using a
    boolean-ized pressure sensor or switch to determine when the applied force is alternated.

    :param ~drivetrain.motor.Solenoid solenoids: This object has 1 or 2 solenoids attached. It
        will be used to apply the force for propulsion.

    :param ~microcontroller.Pin switch: This should be the (`board` module's)
        :py:class:`~microcontroller.Pin` that is connected to the sensor that will be used to
        determine when the force for propulsion should be alternated between solenoids.

    .. note:: There is no option to control the speed in this drivetrain class due to the nature of
        using solenoids for propulsion. Electronic solenoids apply either their full force or none
        at all. We currently are not supporting dynamic linear actuators (in which the force
        applied can vary) because they are basically motors simulating linear motion via a gear box
        controlling a shaft's extension/retraction. This may change when we support servos though.
    """
    def __init__(self, solenoids, switch):
        if isinstance(solenoids, (BiMotor, PhasedMotor, StepperMotor)):
            raise ValueError('this drivetrain only uses a 1 Solenoid object')
        super(Locomotive, self).__init__([solenoids])
        if MICROPY:
            self._switch = machine.Pin(switch, machine.Pin.IN)
        else:
            self._switch = DigitalInOut(switch)
            self._switch.switch_to_input()
        self._is_forward = True
        self._is_in_motion = False
        self._cancel_thread = not IS_THREADED
        self._moving_thread = None

    def stop(self):
        """This function stops the process of alternating applied force between the solenoids."""
        if IS_THREADED:
            self._stop_thread()
        self._is_in_motion = False

    def _stop_thread(self):
        if self._moving_thread is not None:
            self._cancel_thread = True
            self._moving_thread.join()
            self._cancel_thread = False
        self._moving_thread = None

    def go(self, forward):
        """This function starts the process of alternating applied force between the solenoids
        with respect to the specified direction.

        :param bool forward: `True` cylces the forces in a way that invokes a forward motion.
            `False` does the same but invokes a force in the backward direction.

        .. note:: Since we are talking about applying linear force to a wheel or axle, the
            direction is entirely dependent on the physical orientation of the solenoids. In
            other words, the armature of one solenoid should be attached to the wheel(s) or
            axle(s) in a position that is always opposite the position of the other solenoid's
            armature on the same wheel(s) or axel(s).
        """
        self._is_forward = forward
        self._is_in_motion = True
        self.stop()
        if IS_THREADED:
            self._moving_thread = Thread(target=self._move)
            self._moving_thread.start()
        else:
            self.sync()

    def _move(self):
        do_while = True
        while do_while:
            self.sync()
            do_while = not self._cancel_thread

    def sync(self):
        """This function should be used at least once in the application's main loop. It will
        trigger the alternating of each solenoid's applied force. This IS needed on MCUs
        (microcontroller units) that can't use the threading module."""
        alternate = (1 if self._switch.value else -1) * \
            (-1 if self._is_forward else 1)
        self._motors[0].go(alternate)

    @property
    def is_cellerating(self):
        """This attribute contains a `bool` indicating if the drivetrain's applied force via
        solenoids is in the midst of alternating. (read-only)"""
        if self._moving_thread is not None or self._is_in_motion:
            return True
        return False
Beispiel #15
0
class I2C(_BitBangIO):
    """Software-based implementation of the I2C protocol over GPIO pins."""
    def __init__(self, scl, sda, *, frequency=400000, timeout=1):
        """Initialize bitbang (or software) based I2C.  Must provide the I2C
        clock, and data pin numbers.
        """
        super().__init__()

        # Set pins as outputs/inputs.
        self._scl = DigitalInOut(scl)
        self._scl.switch_to_output()
        self._scl.value = 1

        # SDA flips between being input and output
        self._sda = DigitalInOut(sda)
        self._sda.switch_to_output()
        self._sda.value = 1

        self._delay = 1 / frequency / 2
        self._timeout = timeout

    def scan(self):
        """Perform an I2C Device Scan"""
        found = []
        if self._check_lock():
            for address in range(0, 0x80):
                if self._probe(address):
                    found.append(address)
        return found

    def writeto(self, address, buffer, *, start=0, end=None, stop=True):
        """Write data from the buffer to an address"""
        if end is None:
            end = len(buffer)
        if self._check_lock():
            self._write(address, buffer[start:end], stop)

    def readfrom_into(self, address, buffer, *, start=0, end=None):
        """Read data from an address and into the buffer"""
        if end is None:
            end = len(buffer)

        if self._check_lock():
            readin = self._read(address, end - start)
            for i in range(end - start):
                buffer[i + start] = readin[i]

    def writeto_then_readfrom(self,
                              address,
                              buffer_out,
                              buffer_in,
                              *,
                              out_start=0,
                              out_end=None,
                              in_start=0,
                              in_end=None,
                              stop=True):
        """Write data from buffer_out to an address and then
        read data from an address and into buffer_in
        """
        if out_end is None:
            out_end = len(buffer_out)
        if in_end is None:
            in_end = len(buffer_in)
        if self._check_lock():
            self.writeto(address,
                         buffer_out,
                         start=out_start,
                         end=out_end,
                         stop=stop)
            self.readfrom_into(address, buffer_in, start=in_start, end=in_end)

    def _scl_low(self):
        self._scl.value = 0

    def _sda_low(self):
        self._sda.value = 0

    def _scl_release(self):
        """Release and let the pullups lift"""
        # Use self._timeout to add clock stretching
        self._scl.value = 1

    def _sda_release(self):
        """Release and let the pullups lift"""
        # Use self._timeout to add clock stretching
        self._sda.value = 1

    def _set_values(self, *, scl, sda, delay=None):
        if delay is None:
            delay = self._delay
        self._scl.value = scl
        self._scl.value = sda
        sleep(delay)

    def _start(self):
        self._sda_release()
        self._scl_release()
        sleep(self._delay)
        self._sda_low()
        sleep(self._delay)

    def _stop(self):
        self._scl_low()
        sleep(self._delay)
        self._sda_low()
        sleep(self._delay)
        self._scl_release()
        sleep(self._delay)
        self._sda_release()
        sleep(self._delay)

    def _repeated_start(self):
        self._scl_low()
        sleep(self._delay)
        self._sda_release()
        sleep(self._delay)
        self._scl_release()
        sleep(self._delay)
        self._sda_low()
        sleep(self._delay)

    def _write_byte(self, byte):
        for bit_position in range(8):
            self._scl_low()
            sleep(self._delay)
            if byte & (0x80 >> bit_position):
                self._sda_release()
            else:
                self._sda_low()
            sleep(self._delay)
            self._scl_release()
            sleep(self._delay)
        self._scl_low()
        sleep(self._delay * 2)

        self._scl_release()
        sleep(self._delay)

        self._sda.switch_to_input()
        ack = self._sda.value
        self._sda.switch_to_output()
        sleep(self._delay)

        self._scl_low()

        return not ack

    def _read_byte(self, ack=False):
        self._scl_low()
        sleep(self._delay)

        data = 0
        self._sda.switch_to_input()
        for _ in range(8):
            self._scl_release()
            sleep(self._delay)
            data = (data << 1) | int(self._sda.value)
            sleep(self._delay)
            self._scl_low()
            sleep(self._delay)
        self._sda.switch_to_output()

        if ack:
            self._sda_low()
        else:
            self._sda_release()
        sleep(self._delay)
        self._scl_release()
        sleep(self._delay)
        return data & 0xFF

    def _probe(self, address):
        self._start()
        ok = self._write_byte(address << 1)
        self._stop()
        return ok > 0

    def _write(self, address, buffer, transmit_stop):
        self._start()
        if not self._write_byte(address << 1):
            raise RuntimeError(
                "Device not responding at 0x{:02X}".format(address))
        for byte in buffer:
            self._write_byte(byte)
        if transmit_stop:
            self._stop()

    def _read(self, address, length):
        self._start()
        if not self._write_byte(address << 1 | 1):
            raise RuntimeError(
                "Device not responding at 0x{:02X}".format(address))
        buffer = bytearray(length)
        for byte_position in range(length):
            buffer[byte_position] = self._read_byte(
                ack=(byte_position != length - 1))
        self._stop()
        return buffer
Beispiel #16
0
from adafruit_led_animation.animation.solid import Solid
from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.animation.pulse import Pulse
from adafruit_led_animation.helper import PixelSubset
from adafruit_led_animation.group import AnimationGroup
from adafruit_led_animation.color import RED, ORANGE, WHITE

ORANGE_DIM = 0x801400  # half value version
RED_DIM = 0x800000

#  ---Set Volume Max Here---
VOLUME_MULT = 0.65  # 1 = full volume, 0.1 is very quiet, 0 is muted

#  ---SWITCH/BUTTON SETUP---
mode_switch = DigitalInOut(board.D9)
mode_switch.switch_to_input(pull=Pull.UP)
mode_state = mode_switch.value
trig_button = DigitalInOut(board.A4)
trig_button.switch_to_input(pull=Pull.UP)
alt_button = DigitalInOut(board.A5)
alt_button.switch_to_input(pull=Pull.UP)

#  ---ACCELEROMETER SETUP---
# Set up accelerometer on I2C bus, 4G range:
i2c = busio.I2C(board.SCL, board.SDA)
int1 = DigitalInOut(board.D6)
accel = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)

#  ---SPEAKER SETUP---
enable = DigitalInOut(board.D10)
enable.direction = Direction.OUTPUT
Beispiel #17
0
import board
from time import sleep
from digitalio import DigitalInOut, Pull, Direction
import neopixel
from random import randint, choice
import audioio
from microcontroller import reset

btn_a = DigitalInOut(board.BUTTON_A)
btn_a.switch_to_input(pull=Pull.DOWN)
btn_b = DigitalInOut(board.BUTTON_B)
btn_b.switch_to_input(pull=Pull.DOWN)

spkrenable = DigitalInOut(board.SPEAKER_ENABLE)
spkrenable.switch_to_output()
spkrenable.value = True

np = neopixel.NeoPixel(board.A1, 64, brightness=.3, auto_write=0)

PICTURES = [
    'main_screen_1.txt', '3.txt', '2.txt', '1.txt', 'go.txt', 'game1.txt',
    'heart.txt', 'end.txt', 'a.txt', 'main_screen_2.txt'
]

R, G, B, Y, M, W, T, O, BL  = (64, 0, 0), (0, 32, 0), (0, 0, 32), (32, 32, 0), (32, 0, 32),\
(20, 20, 20), (0, 32, 32), (42, 10, 0), (0, 0, 0)
COLORS = [R, G, B, Y, M, W, T, O]
FLOOR = [56, 57, 58, 59, 60, 61, 62, 63]
PAD_pos, DIG = 58, 51

color = choice(COLORS)
Beispiel #18
0
class FeatherS2:
    def __init__(self):
        # the boot button !
        self._boot = DigitalInOut(board.IO0)
        self._boot.switch_to_input(pull=Pull.UP)

        # pin 13 and on-board RGB
        self._led13 = DigitalInOut(board.LED)
        self._led13.direction = Direction.OUTPUT
        self._dotstar = adafruit_dotstar.DotStar(board.APA102_SCK,
                                                 board.APA102_MOSI,
                                                 1,
                                                 brightness=0.5,
                                                 auto_write=True)

        # the second LDO
        self._ldo2 = DigitalInOut(board.LDO2)
        self._ldo2.direction = Direction.OUTPUT

        # ambient light sensor
        self._light = analogio.AnalogIn(board.AMB)

    """Reading the on-board multipurpose button known as boot"""

    @property
    def boot(self):
        return not self._boot.value

    """The pin 13 is blue"""

    @property
    def blue_led(self):
        return self._led13.value

    @blue_led.setter
    def blue_led(self, value):
        #set the internal LED IO13 to it's inverse state
        self._led13.value = value

    """Set the power for the second on-board LDO to allow no current draw when not needed."""

    @property
    def ldo2(self):
        return self._ldo2.value

    @ldo2.setter
    def ldo2(self, state):
        # Set the LDO2 power pin on / off
        self._ldo2.value = state
        # A small delay to let the IO change state
        time.sleep(0.035)

    """Old style convenience function for enabling LDO2"""

    def enable_LDO2(self, state):
        self.ldo2 = state

    """On board RGB LED, otherwise used for Circuitpython status"""

    @property
    def dot(self):
        return self._dotstar

    """Color wheel to allow for cycling through the rainbow of RGB colors."""

    @staticmethod
    def wheel(wheel_pos):
        wheel_pos = wheel_pos % 255
        if wheel_pos < 85:
            return 255 - wheel_pos * 3, 0, wheel_pos * 3
        elif wheel_pos < 170:
            wheel_pos -= 85
            return 0, wheel_pos * 3, 255 - wheel_pos * 3
        else:
            wheel_pos -= 170
            return wheel_pos * 3, 255 - wheel_pos * 3, 0

    """Light, the friendly light sensor (516-52686) - make a percent version ? (0-100)"""

    @property
    def light(self):
        return self._light.value
Beispiel #19
0
# Copy this as 'boot.py' in your Pico's CIRCUITPY drive
# from https://gist.github.com/Neradoc/8056725be1c209475fd09ffc37c9fad4
# Useful in case Pico locks up (which it's done a few times on me)
#
import board
import time
from digitalio import DigitalInOut, Pull

import time
led = DigitalInOut(board.LED)
led.switch_to_output()

safe = DigitalInOut(board.GP14)
safe.switch_to_input(Pull.UP)


def reset_on_pin():
    if safe.value is False:
        import microcontroller
        microcontroller.on_next_reset(microcontroller.RunMode.SAFE_MODE)
        microcontroller.reset()


led.value = False
for x in range(16):
    reset_on_pin()
    led.value = not led.value
    time.sleep(0.1)
Beispiel #20
0
IMAGE_DURATION = (1, 0.5, 10)
IMAGE_FOLDER = (
    "/bmps",
    "/bmps2",
    "/bmps3",
)
# pylint: disable=invalid-name
# --- Display setup ---
matrix = Matrix(bit_depth=6)
display = matrix.display
ACCEL = adafruit_lis3dh.LIS3DH_I2C(busio.I2C(board.SCL, board.SDA),
                                   address=0x19)
_ = ACCEL.acceleration  # Dummy reading to blow out any startup residue

pin_down = DigitalInOut(board.BUTTON_DOWN)
pin_down.switch_to_input(pull=Pull.UP)
button_down = Debouncer(pin_down)
pin_up = DigitalInOut(board.BUTTON_UP)
pin_up.switch_to_input(pull=Pull.UP)
button_up = Debouncer(pin_up)

ALIGN_RIGHT = True
auto_advance = True

i = 0
NUM_FOLDERS = 2  #first folder is numbered 0

slideshow = SlideShow(
    display,
    None,
    folder=IMAGE_FOLDER[i],
Beispiel #21
0
class Badge:
    BTN_UP = 1 << 0
    BTN_LEFT = 1 << 1
    BTN_DOWN = 1 << 2
    BTN_RIGHT = 1 << 3
    BTN_ACTION = 1 << 4

    def __init__(self):
        self._up = DigitalInOut(board.UP_BUTTON)
        self._up.switch_to_input(pull=Pull.UP)
        self._down = DigitalInOut(board.DOWN_BUTTON)
        self._down.switch_to_input(pull=Pull.UP)
        self._left = DigitalInOut(board.LEFT_BUTTON)
        self._left.switch_to_input(pull=Pull.UP)
        self._right = DigitalInOut(board.RIGHT_BUTTON)
        self._right.switch_to_input(pull=Pull.UP)
        self._action = DigitalInOut(board.ACTION_BUTTON)
        self._action.switch_to_input(pull=Pull.UP)
        self._battery = AnalogIn(board.BATTERY_SENSE)
        self._led = DigitalInOut(board.LED)
        self._led.switch_to_output(value=True)
        self._vibration = DigitalInOut(board.VIBRATION_MOTOR)
        self._vibration.switch_to_output()
        self._pixels = neopixel.NeoPixel(board.NEOPIXEL, 4)
        self._i2c = None
        self._lis3dh = None
        self._spi = None
        self._display_bus = None
        self._display = None
        self._sound = None
        self._midi = None
        self._gamepad = None

    @property
    def up(self):
        """``True`` when the up button is pressed. ``False`` if not."""
        return not self._up.value

    @property
    def down(self):
        """``True`` when the down button is pressed. ``False`` if not."""
        return not self._down.value

    @property
    def left(self):
        """``True`` when the left button is pressed. ``False`` if not."""
        return not self._left.value

    @property
    def right(self):
        """``True`` when the right button is pressed. ``False`` if not."""
        return not self._right.value
    
    @property
    def action(self):
        """``True`` when the action button is pressed. ``False`` if not."""
        return not self._action.value

    @property
    def gamepad(self):
        if not self._gamepad:
            import gamepad
            self._gamepad = gamepad.GamePad(
                self._up, self._left, self._down, self._right, self._action
            )
        return self._gamepad
    
    @property
    def back_led(self):
        """The LED at the back of the board"""
        return not self._led.value

    @back_led.setter
    def back_led(self, value):
        self._led.value = not value

    @property
    def vibration(self):
        """Set to ``True`` to start vibrating"""
        return self._vibration.value

    @vibration.setter
    def vibration(self, value):
        self._vibration.value = value

    @property
    def pixels(self):
        """Array with the values of the 4 neopixels at the top of the board.

        See `neopixel.NeoPixel` for more info.

        .. code-block:: python
          from badgeio import badge
          import time

          badge.pixels.brightness = 0.5
          while True:
            badge.pixels[0] = (255, 0, 0) # Red
            time.sleep(0.5)
            badge.pixels[0] = (0, 255, 0) # Green
            time.sleep(0.5)
        """
        return self._pixels

    @property
    def i2c(self):
        """direct access to the I2C bus"""
        if not self._i2c:
            self._i2c = board.I2C()
        return self._i2c

    @property
    def spi(self):
        """direct access to the SPI bus"""
        if not self._spi:
            self._spi = board.SPI()
        return self._spi

    @property 
    def display_bus(self):
        if not self._display_bus:
            self._display_bus = displayio.FourWire(self.spi, command=board.DISP_DC, chip_select=board.DISP_CS,
                                                   reset=board.DISP_RESET, baudrate=1000000)
        return self._display_bus

    @property
    def display(self):
        if not self._display:
            displayio.release_displays()
            self._display = display.Display(self.display_bus, width=296, height=128, rotation=270,
                                                   seconds_per_frame=5, busy_pin=board.DISP_BUSY, swap_rams=True,
                                                   black_bits_inverted=False)
        return self._display

    @property
    def acceleration(self):
        """Obtain acceleration as a tuple with 3 elements: (x, y, z)"""
        if not self._lis3dh:
            import adafruit_lis3dh
            self._lis3dh = adafruit_lis3dh.LIS3DH_I2C(self.i2c, address=0x18)
        return self._lis3dh.acceleration

    @property
    def battery_voltage(self):
        """The battery voltage (if currently operating off the battery)"""
        return (self._battery.value * 3.3) / 65536
    
    def show_bitmap(self, path, pixel_shader=displayio.ColorConverter()):
        """Draws the bitmap from the given file. Must be in .bmp format"""
        image = displayio.OnDiskBitmap(open(path, "rb"))
        grid = displayio.TileGrid(image, pixel_shader=pixel_shader)
        group = displayio.Group(max_size=1)
        group.append(grid)
        self.display.show(group)
        while self.display.time_to_refresh > 0:
            pass
        self.display.refresh()