Here you will find my recent contribution to LoRa drivers. This post describes the LoRa driver for a Raspberry Pi SBC (Single Board Computer). Additionally, a wrapper written in Python is available making it very easy to use and prototype. Raspberry Pi gets more and more attention. Adding LoRa communication enables it to communicate with IoT devices such as remote thermometers, soil moisture sensors and many more others. You can find HAT boards thatoffer a LoRa module. Here, I describe how to connect and how to use a low-cost LoRa RFM95W module. This particular module comes with different frequency options. However, this post describes the one which uses 868 MHz frequency.
Let’s start with a bit different piece of information. Some time ago I have published a driver for STM32 for a SX1278 LoRa module. This works fine and you can read more about it in a post tiled STM32 HAL driver for LoRa SX1278 wireless module.
Why then write a driver for Raspberry Pi? The reason is quite obvious. Raspberry Pi is a great platform which allows for fast prototyping. Adding a feature to communicate over long distance sounds like a good idea. Moreover, the driver supports Python through C bindings to this script language. Transmitting a data package can be done in only 3 lines: importing LoRa module, initializing device and sending data over the air.
Connect module to RPI
You need to connect power, SPI lines and two additional pins to Raspberry Pi. Below you can find the pinout of LoRa module.
Below a pinout of Raspberry Pi is available.
Using the RFM95W pinout and Raspberry Pi pinout you can connect the module to the mini computer. The connections were gathered in a shape of a table which was attached below.
|RFM95W pin||Raspberry Pi pin||Description|
|3.3V||3V3, pin 1||3V3 power supply|
|GND||GND, pin 6||power ground|
|MISO||GPIO 9 (MISO), pin 21||SPI Master Input Slave Output|
|MOSI||GPIO 10 (MOSI), pin 19||SPI Master Output Slave Input|
|SCK||GPIO 11 (SCLK), pin 23||SPI clock|
|NSS||GPIO 25, pin 22||SPI chip select|
|RESET||GPIO 17, pin 11||LoRa module reset|
|DIO0||GPIO 4 (GPCLK0), pin 7||LoRa status line|
Update Raspberry Pi
Before diving into wireless communication an additional step is needed. Operating system has to be updated and equipped with Python 3 package. Updating OS on RPi is pretty straightforward. Then let’s go ahead and type following
sudo apt update sudo apt dist-upgrade -y sudo apt install -y python3
The LoRa RPi driver makes use of wiringPi library. This should come as default if not you have to install it.
sudo apt install wiringpi
Additionally, you have to enable SPI interface. For this use raspi-tool. This will open a console application, navigate through the menu and enable SPI interface. After that save changes and exit the application. Restart your Raspberry Pi to apply changes.
Compile the driver
Example output is
After identifying the exact Python 3 version make appropriate changes to the Makefile. Proper version has to be set as a constant in Makefile. Thus, if the version is 3.7.1 you only have to put 3.7. This is required to make proper bindings to Python libraries. After the changes following line should be present in the Makefile.
Compile the code. If you only need the library, not the application which acts as sender/receiver, you can invoke following command
If the compilation succeed a loralib.so file should have been created. This is a library which acts as a Python module, therefore it can be imported with import command in Python script. Using it is straightforward, below work example was given.
Test the driver
To test the driver you can do following
Above will import loralib module. If you see an error this is probably due to lacking the loralib library in current working directory. When you start Python interpreter make sure that the library is placed in the same directory from where you are invoking Python. The module is equipped with some function. There are only three so the first one initializes the module, one sends the data and the last but not least receives data.
For more detailed information on what is available got to my GitHub rpeository. the link to the GitHub can be found at the bottom of this post.
To receive some data transmitted by an another LoRa module you have to initialize the driver with init() and then invoke the recv().
loralib.init(1, 868000000, 7) data = loralib.recv() print(data)
init() takes 3 parameters. The first sets the module to receiver mode (0) or transmitter mode (1). The second parameter sets the demanded frequency expressed in Hertz. The third argument is the spread factor. Other parameters like bandwidth and coding ratio were hardcoded and set to 125kHz and 4/5 accordingly.
Please keep in mind that using different frequencies then the radio was designed for can cause very poor reception/transition due to the fact of band pass filters presence in the module. Also, wireless transmission is under government regulation so first check what kind of power, modulation, frequency you can use.
recv() returns a tuplet containing six elements:
- buffer — the actual data
- buffer length
- PRRSI — last packet RSSI (received signal strength indicator) [dBm]
- RRSI — current RSSI [dBm]
- SNR — signal noise ratio
- error — if 0 then no error occurred, if other then 0 then CRC error occurred
If there was a correct reception registered then following should be fulfilled:
data > 0 and data == 0
It translates to two things. The first one checks if there was some data received and the second one checks integrity of received package.
The data can be transmitted with following
loralib.init(0, 868000000, 7) loralib.send(b'hello')
This initializes the LoRa module in sender (transmitter) mode and sends data with send() method. This method accepts a byte array. So before sending a string it has to be encoded.
The full source code and more detailed documentation is available under LoRa-RaspberryPi repository.