Over the last couple of months I have been working on a Proof of Concept(PoC) project for a customer which uses Seeed LoRa-E5 (STM32WLE5JC) modules so I had a couple of spare dev kits on my desk.
I have also been porting some of my Windows 10 IoT Core projects to.NET Core 5 so they work on Raspberry PI3/4 devices running on the RaspberryPiOS. This got me thinking that LoRaWAN connectivity for reasonably powerful devices like a Raspberry PI could be useful for some specialised applications.
After some experimentation with the System.IO.PortsNuGet Package. I decided to do a.NET Core 5 version of my Seeed LoRa-E5 library.
The process of installing the.NET Core ARM32/64 runtimes on RaspberryPI devices has been documented in detail by many other authors so I won't cover it here.
I predominately use Microsoft Visual Studio 2019 (rather than Visual Studio Code) so I spent some time exploring tooling to make deployments and debugging easier. To improve the development experience I use
- The Raspberry Debugger which provides a really smooth, runtime installation, application deployment, and debugging experience for Visual Studio 2019.
- XRDP for remote access as the RPI device is running headless in the garage at the back of my property. (I do this to reduce the signal strength reported at the RAK7258 gateway in my home office).
I used a jeweler's screwdriver lift up the locking tabs on the Grove connector for the transmit and receive wires so I could swap them around.(I mark cross over cables with a knot so it is obvious they have been modified)
There are some subtle differences between the nanoFramework/TinyCLR serial port libraries.
// set parameters
serialDevice.BaudRate = baudRate;
serialDevice.Parity = serialParity;
serialDevice.StopBits = stopBitCount;
serialDevice.Handshake = Handshake.None;
serialDevice.DataBits = dataBits;
serialDevice.NewLine = "\r\n";
atCommandExpectedResponse = string.Empty;
serialDevice.Open();
serialDevice.WatchChar = '\n';
serialDevice.DataReceived += SerialDevice_DataReceived;
//Ignoring the return from this is intentional
this.SendCommand("+LOWPOWER: WAKEUP", "AT+LOWPOWER: WAKEUP", SendTimeoutMinimum);
For example the nanoFramework has watchChar so it is easier to filter calls to the DataReceived event
private static void SerialDevice_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
switch (e.EventType)
{
case SerialData.Chars:
//Debug.WriteLine("RX SerialData.Chars");
break;
case SerialData.WatchChar:
Debug.WriteLine("RX: SerialData.WatchChar");
SerialPort serialDevice = (SerialPort)sender;
// Uncomment this to see buffer size ebb and flow
//Debug.WriteLine($"RX: SerialData.WatchChar Bytes:{serialDevice.BytesToRead}");
string response = serialDevice.ReadExisting();
Debug.WriteLine($"RX :{response.Trim()} bytes:{response.Length} read from {serialDevice.PortName}");
break;
default:
Debug.Assert(false, $"e.EventType {e.EventType} unknown");
break;
}
}
But.Net Core does not
private static void SerialDevice_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort serialPort = (SerialPort)sender;
switch (e.EventType)
{
case SerialData.Chars:
string response = serialPort.ReadExisting();
Debug.WriteLine($"RX:{response.Trim()} bytes:{response.Length}");
break;
case SerialData.Eof:
Debug.WriteLine("RX :EoF");
break;
default:
Debug.Assert(false, $"e.EventType {e.EventType} unknown");
break;
}
}
The TinyCLR serial port library only supports the sending of byte arrays so the AT Commands have to be converted.
while (true)
{
byte[] txBuffer = UTF8Encoding.UTF8.GetBytes(ATCommand);
int txByteCount = serialDevice.Write(txBuffer);
Debug.WriteLine($"TX: {txByteCount} bytes");
...
}
These implementation details are just just different "philosophical" approaches so weren't a major issue.
I have assumed that readers are familiar with LoRaWAN, configuring LoRaWAN modules, and LoRaWAN networking.
The configuration of The Things Network(TTN) Gateways, Applications and Devices has been covered in detail in several other Hackster.IO projects so I won't repeat it here.
This project is a summary of a series of posts on my blog where I cover the construction of the Seeed LoRa-E5 LoRaWAN library in significantly more detail.
This library is intended as "plumbing" for.NET developers building LoRaWAN connected applications for.Net Core powered devices.
The Github repository includes a sample application which shows how to send and receive messages with the library and the different configuration options supported.
FootnoteThe RaspberryDebugger extension for Visual Studio 2019 makes deployment and debugging of .NET Core projects on RaspberryPI devices a "friction free" process. It works so well I was inspired downloaded the RaspberryDebugger code(Bonus it complied first time) and am working on fixes for a couple of issues.
Comments