Intro to LoraWAN Research
To make LoraWAN networks run with high performance by applying the best knowledge I learnt from IOS, MVIOS and participating in the design of 4G SON.
On a FeatherWing:
3 pins for SPI are Starting from the antenna are:
4 - SPI Microcontroller In Sensor Out (MISO) - input from wing to feather 5 - SPI Microcontroller Out Sensor In (MOSI) - output from feather to wing 6 - SPI Clock (SCK) - output from feather to wing
Also needs a chip select and potential Reset and IRQ lines
Python from PC
export BLINKA_FT232H=1 to tell python to look for FT232 on USB
ipython3
from pyftdi.ftdi import Ftdi
Ftdi().open_from_url('ftdi:///?')
# copy address from error message
Ftdi().open_from_url('ftdi://ftpd:232h:1/1')Then to open RFM module:
import board
import busio
import digitalio
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
cs = digitalio.DigitalInOut(board.D7)
reset = digitalio.DigitalInOut(board.D6)
import adafruit_rfm9x
rfm9x = adafruit_rfm9x.RFM9x(spi, cs, reset, 433.0)
rfm9x.send('Hello world!')
while True:
packet = rfm9x.receive(timeout=5.0)
if packet != None:
pktText = str(packet, ascii)
print(f"Packet Received, RSSI={rfm9x.rssi}, text={pktText}")
else:
print(".",end='',flush=True)
time.sleep(5)FT232H to multiple RFM95x (Featherwings)
| From FT232 | RFM | Name |
|---|---|---|
| 1 | 2 | 3V3 |
| 2 | - | 5V - unused |
| 3 | 4 | GND |
| 4 | 11 | D0/ SCL |
| 5 | 12 | D1/ MOSI/ PICO |
| 6 | 13 | D2/ MISO/ POCI |
| 7 | - | D3/ Dop Not Use |
| 8 | x | D4/ use as CS0 |
| 9 | x | D5/ use as CS1 |
| 10 | x | D6/ use as CS2 |
| 11 | x | D7/ use as CS3 or RESET |
| x | 1 | RST |
| x | 6 | CS - hard wire to CS centre of board |
| x |
After multoiple failures and trying to understand the specs and wiring examples I am now absolutely certain that:
-
FT232H D1/ PICO connects to RFM pin 12 (adjacent to SCL)
-
FT232H D2/ POCI connects to RFM pin 13
-
Connecting FT232H-D4 to Pin RFM pin 7, which is hard-wired to CS via (middle of set of 3 next to RF module). Did work as a chip select.
OLD METHOD - Connecting Raspberry Pi 3+ to RFM95x
| RFM Module | Pi GPIO | Name |
|---|---|---|
| 4 | 8/16 | Ground |
| 2 | 12 | 3.3V |
| 11 | 9 | SCLK |
| 13 | 10 | MISO / POCI |
| 12 | 11 | MOSI / PICO |
| 6 | 13 | INT - using GPIO22 |
| 7 | 14 | Chip Select - using GPIO27 |
| 8 | 15 | Reset - using GPIO17 |
RFM95x pinout is based on details in https://learn.adafruit.com/adafruit-adalogger-featherwing/pinouts
Python install
I could not make debian work, so I had to switch Raspian.
pip3 installs
Install into a venv
- pip3 install adafruit_blinka
- pip3 install adafruit-circuitpython-rfm9x
RFM9x to access RFM95x
import board
import busio
import digitalio
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
cs = digitalio.DigitalInOut(board.D27)
cs.switch_to_output()
reset = digitalio.DigitalInOut(board.D17)
reset.switch_to_output()
import adafruit_rfm9x
rfm9x = adafruit_rfm9x.RFM9x(spi, cs, reset, 433.0)RadioHead header
A 4-byte header defained by RadioHead is used to pass information between the LoRa radio and the controller. It contains:
- 1 byte for the LoRa node ID; if not 0xff then only packets address to this node will be accepted
- 1 byte for destination address
- 1 byte for the identifier used with send_with_ack mode.
- 1 byte for flags, Upper 4 bits reserved for use by Reliable Datagram Mode. Lower 4 bits may be used to pass information
My Protocol
Needs to be compact, include a checksum and the able to command and respond to:
- command to send n packets with known content, to calculate BER
- command to report back receipt of ‘known packets’ with RSSI, SNR and error rate.
- commands to set various config params
- commands to query current config
- periodic polling to confirm link still active - and revert to know good settings if not received.
- commands to query RSSI and SNR
[ PCS = Packet Content Selector ]
| Command | Payload | Response | Description |
|---|---|---|---|
| S-Send | num, PCS | sending report | Send n packets with known content, to calculate BER |
| R-Receive | num, PCS | receive report | Expect n packets with known content, report success |
| C-Config | config | config report | Set config params |
| Q-Query | n/a | config report | Query current config params |
| P-Poll | n/a | poll report | Periodic polling to confirm link still active - and revert to known good settings if not received. |
Packets To Send
Need a set of packets which can be described with a short number and easily generated.
Should be it text or binary?
Generating Text to Send/ Receive
It seems that Python and Micropython have different random number generators, so it cannot be random
Potential for Optimisation
Based on the SX1231 Datasheet (in NextCloud) , plus other sources.
I am ignoimg OOK (On/Off Keying), which although the SX1231 can use this modulation, but it is not LoRa modulation (OOK also has a lower max bitrate of 32.768 kbps).
Symbols are encoded with a chirp. Each chirp transmits as a chirp from fvalue to fhigh , then flow to fvalue . The spreading factor (SF) denotes how many bits are encoded in each symbol, so if SF = 7, there are 2SF values of fvalue between flow and fhigh inclusive.
flow to fhigh are centred on fRF , which is typically 433MHz. It can be configured in steps of approx 61Hz - the frequency is derived using PLL from a 32MHz crystal, which is divided by 219 .
SX1231 default FRF is 14991360 (0xE4C000) -> 14991360 * 32MHz / 219 = 915MHz. FDEV = 5kHz (default). RxBw for FSK is given by RxBw = FOsc / ( 24 x 2 14 ) where 24 and 14 are taken from RegRxBw, default to 5.2 kHz.