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.