First, to tie some threads together, this is a continuation of a LoRA thread by @lsfarm in 2020:
Which @jgskarda followed up as we started working together on LoRA and Particle:
Both of these got a lot of traction and so I wanted to share the progress I have made on this front just as Jeff has so well in his thread. My hope is that this will be useful to others who need to augment the Cellular and WiFi connectivity Particle offers with LoRA either to address coverage issues or to support high density deployments.
I want to thank everyone who has participated in these threads and to call our @jgskarda for his amazing diligence and energy and @rickkas7 who has provided the libraries and support that the solution is built upon.
Compared to @jgskarda’s implementations, my approach is fairly straightforward. Here is what my goal is for this solution:
- To use LoRA to extend the reach of the cellular network to cover locations that would otherwise not connect, primarily in remote parks / recreation areas.
- Make the solution easy enough to install that park staff can do it and the network should run reliably.
- To keep things simple, I limited my solution to 10 nodes and allowed a generous 10 second spacing between transmission windows.
The solution has two parts: a gateway which is located where it can connect to both the cellular network and to the nodes (within about 2000 feet); and, up to 10 nodes which will connect to the gateway and who can relay messages for each other to extend the reach of the network.
Here is how the system operates:
- The gateway is installed in a location with cellular service and put into “connection” mode where it is both connected to Particle and is listening for LoRA messages. This way, I can remotely monitor the installation and configure the network using Particle commands. Once set up, the gateway is put into normal - sleepy - operation.
- The nodes are powered up and installed at their desired locations. Pressing the “user” button will cause them to transmit to the gateway and, they will display signal strength by how many “flashes” they give on the Boron’s RGB led. Nodes take a two step process when set up - they “join” the network and get a node number assigned and then they simply report data. All node properties such as time, node number, sensor type, park opening hours snd reporting frequency are set using these join and data messages. All messages are initiated by the nodes.
- The gateway will build a node ID data file to keep track of nodes who have joined the network and their configuration. Gateways and nodes all sleep until the reporting window when the gateway wakes first and each node wakes in sequence at 10 second intervals. Node data reports are stored using a publish queue and are delivered to Ubidots via a webhook every hour when the gateway connects to Particle via cellular.
- I tried to make this as robust as possible: If a collision occurs, the nodes will follow an exponential back-off to deconflict with up to three tries. If the gateway deems the node connections unhealthy it will reset. If a node fails to connect over two connection periods, it will power cycle and then start trying every minute until it catches the gateway.
- To make it easier to configure the gateways and nodes, I created a method to parse multiple commands for the gateway and the nodes using a single Particle function. With this approach, I can set up each node and gateway with just a few commands.
// These commands will set the gateway's opening time to 6 am and closing to 9pm.
{"cmd":[{"node":0, "var":"6","fn":"open"},{"node":0, "var":"21","fn":"close"}]}
or
//Will reset the data on node 1 and assign it to sensor type 1 (person counter).
{"cmd":[{"node":1,"var":"all","fn":"reset"}, {"node":1, "var":"1","fn":"type"}]}
Hardware:
I designed a variant of my standard Boron / Argon carrier board with a LoRA radio on it as shared here:
This solution is working quite well and it allows me to retrofit existing installations by simply switching out the carrier board and using the LoRA sticker antennae.
Software:
I am trying to get away from writing long - monolithic - code and have taken significant steps in that direction with this project. The software is divided into specific files and almost all functions are implemented using Singleton classes following @rickkas7 amazing tutorial and tools:
Using this approach, I have separated out the main file from persistent storage, Particle functions, LoRA Functions and the pins and IO of the device. My hope is that this approach is easier for others to see what I am doing, easier for me to maintain and written in a way that will make it easier to reuse the code.
One quick word on why Particle is such a great platform for this work and why I chose to use Borons for the gateway and also for the nodes. There are two reasons for this:
- It is possible that the nodes will need to connect to cellular for updates in the future. Using a Boron with a special “connect to cellular” option, makes this possible though I hope to never use it.
- The value of the Particle platform for example:
- This community and the help I have received on this forum
- A clear and well documented API
- Clear and relevant application notes such as the Singleton Class referenced above
- The amazing wealth of the Particle Libraries including the following I used in this project: PublishQueuePosixRK, StoageHelperRK, AB1805_RK, MB85RC256V-FRAM-RK, and @jgskarda’s branch of RF9X-RK. @rickkas7 - you are a rockstar!
I will update this thread with progress as these devices start to be deployed in the coming weeks. Please take a look at the software and hardware repositories below and ask questions or make suggestions for improvements. Again, thank you all for your support.
Github repos for the Gateway and Nodes
and for the hardware: