Feather RP2040 with RFM95 Lora (2) and FeatherWing Airlift WiFi: How to use 2 SPI devices?

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
jocelyncloutier
 
Posts: 5
Joined: Tue Apr 04, 2023 10:45 am

Feather RP2040 with RFM95 Lora (2) and FeatherWing Airlift WiFi: How to use 2 SPI devices?

Post by jocelyncloutier »

I have 3 devices:
- (2) Adafruit Feather RP2040 with RFM95 LoRa Radio - 915MHz
- (1) Adafruit AirLift FeatherWing – ESP32 WiFi Co-Processor

Misc:
- CircuitPython
- I updated to latest version of CircuitPython on my Feathers
Adafruit CircuitPython 8.1.0 on 2023-05-22; Adafruit Feather RP2040 RFM with rp2040
- I updated to latest libraries (i.e. adafruit_esp32spi, adafruit_rfm9x, etc)

Good news:
- I am able to send messages between the 2 LORA feathers
- I am able to use WiFI on the ESP32 Feather Wing when connected to one of my Feather Rp2040 LORA

Problem:
- How to use 2 SPI devices at the same time in Circuit Python using libraries adafruit_esp32spi and adafruit_rfm9x???

When I do the second "spi = busio.SPI(board.A0, board.A1, board.A2)" below, I get error
*** SPI peripheral in use


Code Sample

Code: Select all

rfm_cs = digitalio.DigitalInOut(board.RFM_CS)
rfm_reset = digitalio.DigitalInOut(board.RFM_RST)
rfm95 = adafruit_rfm9x.RFM9x(board.SPI(), rfm_cs, rfm_reset, 915.0)


esp32_cs = DigitalInOut(board.D13)
esp32_ready = DigitalInOut(board.D11)
esp32_reset = DigitalInOut(board.D12)

#Note, I am not stacking the feather & featherwing and am using wires to be able to have more flexibility
spi = busio.SPI(board.A0, board.A1, board.A2)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

User avatar
jocelyncloutier
 
Posts: 5
Joined: Tue Apr 04, 2023 10:45 am

Re: Feather RP2040 with RFM95 Lora (2) and FeatherWing Airlift WiFi: How to use 2 SPI devices?

Post by jocelyncloutier »

It has now been almost 2 days since I posted this. It is the first time I try to get technical support from Adafruit so my expectation may not be in line with reality.

Anything else/more I can do to get some support for this issue?

Jocelyn

User avatar
jerryn
 
Posts: 1868
Joined: Sat Sep 14, 2013 9:05 am

Re: Feather RP2040 with RFM95 Lora (2) and FeatherWing Airlift WiFi: How to use 2 SPI devices?

Post by jerryn »

I don't represent Adafruit, but I think I can help you here.
When using multiple SPI devices, they should share the same MISO,MOSI and SCK pins. The CS and any other pins must be unique.
So you can create one instance of:

Code: Select all

spi=board.SPI()
and pass it to both the rfm9x and esp32spi initializations:

Code: Select all

rfm95 = adafruit_rfm9x.RFM9x(spi, rfm_cs, rfm_reset, 915.0)
.
.
.
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
I hope that helps.

User avatar
jerryn
 
Posts: 1868
Joined: Sat Sep 14, 2013 9:05 am

Re: Feather RP2040 with RFM95 Lora (2) and FeatherWing Airlift WiFi: How to use 2 SPI devices?

Post by jerryn »

FYI -- I connected a FEATHER RP2040 RFM95 to an airlift feather wing (just stacked them) and ran this combined simplest:

Code: Select all

import board
import busio
from digitalio import DigitalInOut, Direction
import adafruit_requests as requests
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_esp32spi import adafruit_esp32spi

import adafruit_rfm9x




# 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("ESP32 SPI webclient test")

TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
JSON_URL = "http://api.coindesk.com/v1/bpi/currentprice/USD.json"


# If you have an AirLift Featherwing or ItsyBitsy Airlift:
esp32_cs = DigitalInOut(board.D13)
esp32_ready = DigitalInOut(board.D11)
esp32_reset = DigitalInOut(board.D12)

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

# Define radio parameters.
RADIO_FREQ_MHZ = 915.0  # Frequency of the radio in Mhz. Must match your
# module! Can be a value like 915.0, 433.0, etc.

# Define pins connected to the chip, use these if wiring up the breakout according to the guide:
CS = DigitalInOut(board.RFM_CS)
RESET = DigitalInOut(board.RFM_RST)

# Initialze RFM radio
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, RADIO_FREQ_MHZ)


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"]))

print("Connecting to AP...")
while not esp.is_connected:
    try:
        esp.connect_AP(secrets["ssid"], secrets["password"])
    except OSError as e:
        print("could not connect to AP, retrying: ", e)
        continue
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))
print(
    "IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))
)
print("Ping google.com: %d ms" % esp.ping("google.com"))

# esp._debug = True
print("Fetching text from", TEXT_URL)
r = requests.get(TEXT_URL)
print("-" * 40)
print(r.text)
print("-" * 40)
r.close()

print()
print("Fetching json from", JSON_URL)
r = requests.get(JSON_URL)
print("-" * 40)
print(r.json())
print("-" * 40)
r.close()

print("Done!")
# Note that the radio is configured in LoRa mode so you can't control sync
# word, encryption, frequency deviation, or other settings!

# You can however adjust the transmit power (in dB).  The default is 13 dB but
# high power radios like the RFM95 can go up to 23 dB:
rfm9x.tx_power = 23

# Send a packet.  Note you can only send a packet up to 252 bytes in length.
# This is a limitation of the radio packet size, so if you need to send larger
# amounts of data you will need to break it into smaller send calls.  Each send
# call will wait for the previous one to finish before continuing.
rfm9x.send(bytes("Hello world!\r\n", "utf-8"))
print("Sent Hello World message!")

# Wait to receive packets.  Note that this library can't receive data at a fast
# rate, in fact it can only receive and process one 252 byte packet at a time.
# This means you should only use this for low bandwidth scenarios, like sending
# and receiving a single message at a time.
print("Waiting for packets...")

while True:
    packet = rfm9x.receive()
    # Optionally change the receive timeout from its default of 0.5 seconds:
    # packet = rfm9x.receive(timeout=5.0)
    # If no packet was received during the timeout then None is returned.
    if packet is None:
        # Packet has not been received
        print("Received nothing! Listening again...")
    else:
        # Received a packet!
        # Print out the raw bytes of the packet:
        print("Received (raw bytes): {0}".format(packet))
        # And decode to ASCII text and print it too.  Note that you always
        # receive raw bytes and need to convert to a text format like ASCII
        # if you intend to do string processing on your data.  Make sure the
        # sending side is sending ASCII data before you try to decode!
        packet_text = str(packet, "ascii")
        print("Received (ASCII): {0}".format(packet_text))
        # Also read the RSSI (signal strength) of the last received message and
        # print it.
        rssi = rfm9x.last_rssi
        print("Received signal strength: {0} dB".format(rssi))



It worked as expected:

Code: Select all

Adafruit CircuitPython 8.2.0-beta.0-8-g475ffc392 on 2023-06-02; Adafruit Feather RP2040 RFM with rp2040
>>> 
>>> import rfm9x_esp32spi
ESP32 SPI webclient test
ESP32 found and in idle mode
Firmware vers. bytearray(b'1.7.1\x00')
MAC addr: ['REDACTED']
	REDACTED		RSSI: -75
	REDACTED		RSSI: -93
Connecting to AP...
Connected to REDACTED 	RSSI: -73
My IP address is 10.0.0.138
IP lookup adafruit.com: 104.20.38.240
Ping google.com: 20 ms
Fetching text from http://wifitest.adafruit.com/testwifi/index.html
----------------------------------------
This is a test of Adafruit WiFi!
If you can read this, its working :)
----------------------------------------

Fetching json from http://api.coindesk.com/v1/bpi/currentprice/USD.json
----------------------------------------
{'time': {'updated': 'Jun 5, 2023 12:32:00 UTC', 'updatedISO': '2023-06-05T12:32:00+00:00', 'updateduk': 'Jun 5, 2023 at 13:32 BST'}, 'disclaimer': 'This data was produced from the CoinDesk BANNED Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org', 'bpi': {'USD': {'code': 'USD', 'description': 'United States Dollar', 'rate_float': 26757.1, 'rate': '26,757.1503'}}}
----------------------------------------
Done!
Sent Hello World message!
Waiting for packets...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received (raw bytes): bytearray(b'message number 0')
Received (ASCII): message number 0
Received signal strength: -49 dB
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
Received nothing! Listening again...
edited to add:
the code also works if you replace

Code: Select all

spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
with

Code: Select all

spi = board.SPI()

User avatar
jocelyncloutier
 
Posts: 5
Joined: Tue Apr 04, 2023 10:45 am

Re: Feather RP2040 with RFM95 Lora (2) and FeatherWing Airlift WiFi: How to use 2 SPI devices?

Post by jocelyncloutier »

Jerryn,

Many thanks for feedback and testing. I was able to make it work with my devices.

I thought I needed 2 instances of busio.spi, whereas I can reuse the same one for both device (silly me). It is the smallest things that trips us sometimes.

Bonus for me is that I can "simply" stack the FeatherWing Airlift WiFI on top of the Feather RP2040 with RFM95 and it works.

Jocelyn

Locked
Please be positive and constructive with your questions and comments.

Return to “Feather - Adafruit's lightweight platform”