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()
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()
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()
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()
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()
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)