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()
adc.atten(ADC.ATTN_11DB) # set 11dB input attenuation (voltage range roughly 0.0v - 3.6v) adc.width(ADC.WIDTH_9BIT) # set 9 bit return values (returned range 0-511) adc.read() # read value using the newly configured attenuation and width # Software SPI bus from machine import Pin, SoftSPI # construct a SoftSPI bus on the given pins # polarity is the idle state of SCK # phase=0 means sample on the first edge of SCK, phase=1 means the second spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4)) spi.init(baudrate=200000) # set the baudrate spi.read(10) # read 10 bytes on MISO spi.read(10, 0xFF) # read 10 bytes while outputting 0xff on MOSI buf = bytearray(50) # create a buffer spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case) spi.readinto(buf, 0xFF) # read into the given buffer and output 0xff on MOSI spi.write(b"12345") # write 5 bytes on MOSI buf = bytearray(4) # create a buffer spi.write_readinto(b"1234", buf) # write to MOSI and read from MISO into the buffer spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf # Hardware SPI