Exemple #1
0
class SPIBus(object):
  """SPI bus access."""

  def __init__(self, freq, sck, sdo, sdi=None, spidev=None):
    _mi = Pin(sdi) if sdi else None
    _mo = Pin(sdo)
    _sc = Pin(sck)
    if spidev == None:
      self._spi = SPI(baudrate=freq, sck=_sc, mosi=_mo, miso=_mi)
    elif spidev >= 0:
      self._spi = SPI(spidev, baudrate=freq, sck=_sc, mosi=_mo, miso=_mi)
    else:
      self._spi = SoftSPI(sck=_sc, mosi=_mo, miso=_mi)

  def deinit(self):
    self._spi.deinit()

  @property
  def bus(self):
    return self._spi

  def write_readinto(self, wbuf, rbuf):
    self._spi.write_readinto(wbuf, rbuf)

  def write(self, wbuf):
    self._spi.write(wbuf)
def main():

    def center(font, string, row, color=st7789.WHITE):
        screen = tft.width                        # get screen width
        width = tft.write_width(font, string)     # get the width of the string
        if width and width < screen:              # if the string < display
            col = tft.width // 2 - width // 2     # find the column to center
        else:                                     # otherwise
            col = 0                               # left justify

        tft.write(font, string, col, row, color)  # and write the string

    try:
        spi = SoftSPI(
            baudrate=20000000,
            polarity=1,
            phase=0,
            sck=Pin(18),
            mosi=Pin(19),
            miso=Pin(13))

        tft = st7789.ST7789(
            spi,
            135,
            240,
            reset=Pin(23, Pin.OUT),
            cs=Pin(5, Pin.OUT),
            dc=Pin(16, Pin.OUT),
            backlight=Pin(4, Pin.OUT),
            rotation=1)

        # enable display and clear screen
        tft.fill(st7789.BLACK)

        row = 16

        # center the name of the first font, using the font
        center(noto_sans, "NotoSans", row, st7789.RED)
        row += noto_sans.HEIGHT

        # center the name of the second font, using the font
        center(noto_serif, "NotoSerif", row, st7789.GREEN)
        row += noto_serif.HEIGHT

        # center the name of the third font, using the font
        center(noto_mono, "NotoSansMono", row, st7789.BLUE)
        row += noto_mono.HEIGHT

    finally:
        # shutdown spi
        if 'spi' in locals():
            spi.deinit()
Exemple #3
0
def main():
    '''
    Draw greetings on display cycling thru hershey fonts and colors
    '''
    try:
        # Turn power on display power
        axp = axp202c.PMU()
        axp.enablePower(axp202c.AXP202_LDO2)
        axp.enablePower(axp202c.AXP202_DCDC3)

        # initialize spi port
        spi = SoftSPI(
            2,
            baudrate=32000000,
            polarity=1,
            phase=0,
            bits=8,
            firstbit=0,
            sck=Pin(18, Pin.OUT),
            mosi=Pin(19, Pin.OUT))

        # configure display
        tft = st7789.ST7789(
            spi,
            240,
            240,
            cs=Pin(5, Pin.OUT),
            dc=Pin(27, Pin.OUT),
            backlight=Pin(12, Pin.OUT),
            rotation=2)

        tft.init()
        tft.fill(st7789.BLACK)
        height = tft.height()
        width = tft.width()
        row = 0

        while True:
            row += 32
            color = next(COLORS)
            tft.fill_rect(0, row-16, width, 32, st7789.BLACK)
            tft.draw(next(FONTS), next(GREETINGS), 0, row, color)

            if row > 192:
                row = 0

            utime.sleep(0.25)

    finally:
        # shutdown spi
        if 'spi' in locals():
            spi.deinit()
Exemple #4
0
class NRF24L01:

    SCK = 5
    MOSI = 4
    MISO = 0

    def __init__(self, ce, csn, spi=None, baudrate=400000, payload_size=16):
        self._csn = Pin(csn) if type(csn) == int else csn
        self._ce = Pin(ce) if type(ce) == int else ce
        self._payload_size = payload_size
        self._spi = spi

        self._init_spi(baudrate)

        self._ce.init(Pin.OUT, value=0)
        self._csn.init(Pin.OUT, value=1)

        self._buf = bytearray(1)
        self._write_reg(SETUP_AW, FIVE_BYTE_ADDRESS)
        if self._read_reg(SETUP_AW) != FIVE_BYTE_ADDRESS:
            print('Failed to set address width!')

        self._flush_tx()
        self._flush_rx()

    def _write_reg(self, reg, data):
        self._csn(0)
        self._spi.readinto(self._buf, 0x20 | reg)
        ret = self._buf[0]
        self._spi.readinto(self._buf, data)
        self._csn(1)
        return ret

    def _write_reg_bytes(self, reg, data):
        self._csn(0)
        self._spi.readinto(self._buf, 0x20 | reg)
        self._spi.write(data)
        self._csn(1)
        return self._buf[0]

    def _read_reg(self, reg):
        self._csn(0)
        self._spi.readinto(self._buf, 0x00 | reg)
        self._spi.readinto(self._buf)
        self._csn(1)
        return self._buf[0]

    def read_reg(self, reg):
        return bin(self._read_reg(reg))

    def _init_spi(self, baudrate):
        if self._spi is None:
            self._spi = SoftSPI(baudrate=baudrate, polarity=0, phase=0,
                                sck=Pin(self.SCK), mosi=Pin(self.MOSI),
                                miso=Pin(self.MISO))
        self._spi.init(baudrate=baudrate)

    def _flush_rx(self):
        self._csn(0)
        self._spi.readinto(self._buf, FLUSH_RX)
        self._csn(1)

    def _flush_tx(self):
        self._csn(0)
        self._spi.readinto(self._buf, FLUSH_TX)
        self._csn(1)

    def set_channel(self, channel):
        self._write_reg(RF_CH, channel)

    def set_speed(self, speed):
        self._write_reg(RF_SETUP, self._read_reg(RF_SETUP) | speed)

    def set_power(self, power):
        self._write_reg(RF_SETUP, self._read_reg(RF_SETUP) | power)

    def _get_address(self, address):
        # Ensure that address is in byte-format
        if type(address) == list:
            address = bytes(address)
        elif type(address) == str:
            address = binascii.unhexlify(address)
        return address

    # Set both RX and TX address to the given value.
    # Default pipe used is PIPE 0
    def open_tx_pipe(self, address):
        address = self._get_address(address)

        self._write_reg_bytes(RX_ADDR_P0, address)
        self._write_reg_bytes(TX_ADDR, address)
        # Must enable RX pipe by writing data-length to it (CAN'T be 0)
        self._write_reg(RX_PW_P0, self._payload_size)
        self._ce(0)


    # Default pipe is PIPE 0
    def open_rx_pipe(self, address):
        address = self._get_address(address)
        # Set RX address
        self._write_reg_bytes(RX_ADDR_P0, address)
        # Nbr of bytes in RX payload
        self._write_reg(RX_PW_P0, self._payload_size)
        # Enable RX
        self._write_reg(EN_RXADDR, self._read_reg(EN_RXADDR) | ERX_P0)

        self._write_reg(EN_AA, self._read_reg(EN_AA) & ~ENAA_P0)

    def enable_auto_ack(self):
        self._write_reg(EN_AA, self._read_reg(EN_AA) | ENAA_P0)

    # The parameter crc is the ammount of bytes to be used.
    # Only 1 or 2 is accepted.
    def set_crc(self, crc):
        # read config reg (wihtout the current CRC value)
        config = self._read_reg(CONFIG) & ~CRC
        if crc == 1:
            config |= CRC_ENA
        elif crc == 2:
            config |= CRC_ENA | CRC
        self._write_reg(CONFIG, config)

    def start_listening(self):
        # Power-up and enable RX
        self._write_reg(CONFIG, self._read_reg(CONFIG) | PWR_UP | PRIM_RX)
        self._write_reg(STATUS,
                        self._read_reg(STATUS) | RX_DR | TX_DS | MAX_RT)

        # Flush fifos and set CE HIGH to start listening.
        self._flush_rx()
        self._flush_tx()
        self._ce(1)

    def stop_listening(self):
        self._ce(0)
        self._flush_rx()
        self._flush_tx()

    def read(self):
        # Read the data from the payload reg
        self._ce(0)
        self._csn(0)            # R_RX_PAYLOAD = 0x61
        self._spi.readinto(self._buf, 0x61)
        data = self._spi.read(self._payload_size)

        # Must toggle CE here as well, to disable receiver temporarly
        self._ce(1)
        self._csn(1)

        # Clear RX ready flag when done
        self._write_reg(STATUS, self._read_reg(STATUS) | RX_DR)
        return data

    def send(self, buf, timeout=500):
        self._send_start(buf)
        start = time.ticks_ms()
        result = None
        while (result is None and
               time.ticks_diff(time.ticks_ms(), start) < timeout):
            result = self._send_done()

        print('result: %s' % result)

    def _send_done(self):
        status = self._read_reg(STATUS)
        if not (status & (TX_DS | MAX_RT)):
            # Haven't finished yet
            return None

        # Transmission is over, clear the interrupt bits in the status-reg
        self._write_reg(STATUS, status | RX_DR | TX_DS | MAX_RT)

        if status & TX_DS:
            # Successfull send
            return 1
        else:
            # MAX attempts have passed, return 2 to indicate failure
            return 2

    def _send_start(self, buf):
        # Power-up and enable TX
        self._write_reg(CONFIG, (self._read_reg(CONFIG) | PWR_UP) & ~PRIM_RX)
        time.sleep_us(200)

        # Send the data
        self._csn(0)             # W_TX_PAYLOAD = 0xA0
        self._spi.readinto(self._buf, 0xA0)
        self._spi.write(buf)
        # Need to pad the rest of the packet if data ist too small.
        if len(buf) < self._payload_size:
            self._spi.write(b'\x00' * (self._payload_size - len(buf)))

        self._csn(1)

        # Toggle the ce-signal to send that data
        self._ce(1)
        time.sleep_us(15)   # MINIMUM 10 us according to datasheet
        self._ce(0)

    def close(self):
        self._spi.deinit()
Exemple #5
0
touch = Pin(TOUCH, Pin.IN)
touch_pwr = Pin(TOUCH_PWR, Pin.OUT, value=0)

spi = SoftSPI(baudrate=27000000, sck=Pin(18), mosi=Pin(23), miso=Pin(32))
dc = Pin(19)
rst = Pin(4)
cs = Pin(5)

pwr_on.value(1)
touch_pwr.value(0)

oled_pwr.value(1)
display = ssd1306.SSD1306_SPI(128, 64, spi, dc, rst, cs)
display.poweron()
display.text('Hello', 0, 0, 1)
display.show()

while (1):
    SoftSPI.deinit(spi)
    touch_pwr = Pin(TOUCH_PWR, Pin.OUT, value=1)
    time.sleep_ms(20)
    touched = (touch.value() == 1)
    spi = SoftSPI(baudrate=27000000, sck=Pin(18), mosi=Pin(23), miso=Pin(32))
    if (touched):
        display.fill_rect(0, 0, 100, 16, 0)
        display.text('Hello Tammy', 0, 0, 1)
    else:
        display.fill_rect(0, 0, 100, 16, 0)
        display.text('Hello world', 0, 0, 1)
    display.show()
Exemple #6
0
def main():
    global m_selected_device, m_selected_device_idx, m_all_devices, m_env_data, m_has_update, m_tim0
    global CLOCKMODE
    mqtt_client = None
    hasNetwork = initNetwork(secrets.SSID, secrets.PASS)
    spi = initSPI()
    display = initDisplay(spi)
    bignum = Writer(display, largedigits, verbose=False)
    wris = Writer(display, smallfont, verbose=False)
    wrisc = Writer(display, tinyfont, verbose=False)
    if hasNetwork:
        mqtt_client = initMQTT()
        ntptime.settime()
    powerOn()
    display.poweron()
    adc = initADC()
    batt_lvl = readBatteryLevel(adc)
    display.fill(0)
    wris.set_textpos(display, 0, 0)
    wris.printstring('Weather 1.0')
    if hasNetwork:
        display.text('WiFi', 0, 48, 1)
    if mqtt_client is not None:
        display.text('WiFi+MQTT', 0, 48, 1)
    display.show()
    time.sleep(2)
    was_touched = False
    virgin = True
    touch_start_time = 0
    m_tim0 = None
    while 1:
        mc = False
        if mqtt_client is not None:
            mqtt_client.check_msg()
            # mc = mqtt_client.connect(clean_session=False)
            mc = True
        # Touch power overlapped with MISO, need to take SPI away fist
        SoftSPI.deinit(spi)
        touch = initTouch()
        time.sleep_ms(50)
        # We only act when finger lifted
        touched = (touch.value() == 1)
        if (touched and not was_touched):
            touch_start_time = time.time()
        released = (not touched and was_touched)
        was_touched = touched
        if not released and touched:
            if (touch_start_time > 0) and (
                (time.time() - touch_start_time) > 3):
                # Hold for 5 seconds, a long touch
                if not CLOCKMODE:
                    touch_start_time = 0
                    CLOCKMODE = True
                else:
                    CLOCKMODE = False
                    touch_start_time = 0
                    virgin = True
                    if m_tim0 is not None:
                        m_tim0.deinit()
                        m_tim0 = None
        elif released and (
            (time.time() - touch_start_time) <= 3) and CLOCKMODE:
            if CLOCKMODE:
                touch_start_time = 0
                m_tim0 = Timer(0)
                m_tim0.init(period=2000,
                            mode=Timer.ONE_SHOT,
                            callback=lambda t: set_clockMode())
                virgin = True
            CLOCKMODE = False
        # We are done, SPI again
        spi = initSPI()
        if (released or virgin) and not CLOCKMODE:
            if m_tim0 is not None:
                m_tim0.deinit()
                m_tim0 = Timer(0)
                m_tim0.init(period=2000,
                            mode=Timer.ONE_SHOT,
                            callback=lambda t: set_clockMode())
            if len(m_all_devices) > 0:
                if not virgin:
                    # First touch will not move pointer forward
                    m_selected_device_idx = m_selected_device_idx + 1
                    if m_selected_device_idx >= len(m_all_devices):
                        m_selected_device_idx = 0
                    m_has_update = False
                if released:
                    virgin = False  # Touched, no longer virgin
                m_selected_device = m_all_devices[m_selected_device_idx]
        (temp, humi, pres, lux) = m_env_data[m_selected_device]
        #            display.fill_rect(0, 0, 127, 16, 0)
        if not CLOCKMODE:
            display.fill(0)
            #            display.text(m_selected_device, 0, 0, 1)
            if (config.STYLE == 0):
                if (temp is not None):
                    display.text(temp, 8, 16, 1)
                if (humi is not None):
                    display.text(humi, 64, 16, 1)
                if (pres is not None):
                    display.text(pres, 8, 32, 1)
                if (lux is not None):
                    display.text(lux, 64, 32, 1)
            else:
                row = 24
                if (temp is not None):
                    bignum.set_textpos(display, col=0, row=row)
                    bignum.printstring(str(temp) + '"c')
                if (humi is not None):
                    wris.set_textpos(display,
                                     col=config.DISPLAY_WIDTH -
                                     wris.stringlen('{:s}%'.format(humi)),
                                     row=row + 10)
                    wris.printstring('{:s}%'.format(humi))
        else:
            print_clock(display, bignum, wris)
            if temp is not None:
                temp = '{:d}'.format(round(float(temp)))
                wris.set_textpos(display,
                                 col=config.DISPLAY_WIDTH -
                                 wris.stringlen(temp),
                                 row=42)
                wris.printstring(temp)

        batt_lvl = readBatteryLevel(adc)
        print_status(display, hasNetwork, mqtt_client is not None,
                     m_has_update, batt_lvl)

    if mqtt_client is not None:
        mqtt_client.disconnect()
Exemple #7
0
def main():
    try:
        # Turn power on display power
        axp = axp202c.PMU()
        axp.enablePower(axp202c.AXP202_LDO2)

        # initialize spi port
        spi = SoftSPI(2,
                      baudrate=32000000,
                      polarity=1,
                      phase=0,
                      bits=8,
                      firstbit=0,
                      sck=Pin(18, Pin.OUT),
                      mosi=Pin(19, Pin.OUT))

        # configure display
        tft = st7789.ST7789(spi,
                            240,
                            240,
                            cs=Pin(5, Pin.OUT),
                            dc=Pin(27, Pin.OUT),
                            backlight=Pin(12, Pin.OUT),
                            rotation=2)

        # enable display
        tft.init()
        tft.fill(st7789.BLACK)
        time.sleep(2)

        while True:
            # say Hello! and show off some colors
            tft.fill(st7789.BLUE)
            tft.text(font, "Hello!", 76, 96, st7789.WHITE, st7789.BLUE)
            time.sleep(1)
            tft.fill(0)
            for _ in range(2):
                for i in range(256):
                    j = i % 64
                    tft.rect(68 - j, 96 - j, j * 2 + 104, j * 2 + 32, wheel(i))
                    tft.text(font, "Hello!", 76, 96, wheel(i))

            time.sleep(1)

            # display some random letters
            tft.fill(0)
            col_max = tft.width() - font.WIDTH
            row_max = tft.height() - font.HEIGHT

            for i in range(5):
                for c in range(0, 255):
                    tft.text(font, c, random.randint(0, col_max),
                             random.randint(0, row_max), random_color())
                    time.sleep(0.005)

            time.sleep(1)

            # write hello! randomly on display running through each rotation
            for rotation in range(9):
                tft.fill(0)
                tft.rotation(rotation % 4 + 2)
                col_max = tft.width() - font.WIDTH * 6
                row_max = tft.height() - font.HEIGHT

                for _ in range(250):
                    tft.text(font, "Hello!", random.randint(0, col_max),
                             random.randint(0, row_max), random_color(),
                             random_color())

    finally:
        # shutdown spi
        spi.deinit()
        # turn off display power
        axp.disablePower(axp202c.AXP202_LDO2)