Transmit Basic
Next step was proving I could send a message to an Arduino device running the LoRaSimpleNode example from the SandeepMistry Arduino LoRa library.
My first attempt didn’t have much range so I tried turning on the PA_BOOST pin (in RegPaConfig) which improved the range and Received Signal Strength Indication (RSSI).
There was quite a bit of code to configure the SX127X to Transmit messages. I had to put the device into sleep mode (RegOpMode), set the frequency to 915MHz(RegFrMsb, RegFrMid, RegFrLsb), and set the output power(RegPaConfig). Then for each message reset the pointer to the start of the message buffer(RegFifoTxBaseAddress, RegFifoAddrPtr), load the message into the buffer (RegPayloadLength), then turn on the transmitter(RegOpMode), and then finally poll (RegIrqFlags) until the message was sent(TxDone).
class Program
{
static void Main(string[] args)
{
Byte regOpMode;
ushort preamble;
byte[] frequencyBytes;
// M2M device has reset pin uses non standard chip select
SX127XDevice sX127XDevice = new SX127XDevice(chipSelectLine: 1, chipSelectLogicalPinNumber: 25, resetPin: 17);
// Put device into LoRa + Sleep mode
sX127XDevice.WriteByte(0x01, 0b10000000); // RegOpMode
// Set the frequency to 915MHz
byte[] frequencyWriteBytes = { 0xE4, 0xC0, 0x00 }; // RegFrMsb, RegFrMid, RegFrLsb
sX127XDevice.WriteBytes(0x06, frequencyWriteBytes);
// More power PA Boost
sX127XDevice.WriteByte(0x09, 0b10000000); // RegPaConfig
while (true)
{
sX127XDevice.WriteByte(0x0E, 0x0); // RegFifoTxBaseAddress
// Set the Register Fifo address pointer
sX127XDevice.WriteByte(0x0D, 0x0); // RegFifoAddrPtr
string messageText = "Hello LoRa from .NET Core!";
// load the message into the fifo
byte[] messageBytes = UTF8Encoding.UTF8.GetBytes(messageText);
foreach (byte b in messageBytes)
{
sX127XDevice.WriteByte(0x0, b); // RegFifo
}
// Set the length of the message in the fifo
sX127XDevice.WriteByte(0x22, (byte)messageBytes.Length); // RegPayloadLength
Debug.WriteLine($"Sending {messageBytes.Length} bytes message \"{messageText}\"");
/// Set the mode to LoRa + Transmit
sX127XDevice.WriteByte(0x01, 0b10000011); // RegOpMode
// Wait until send done, no timeouts in PoC
Debug.WriteLine("Send-wait");
byte IrqFlags = sX127XDevice.ReadByte(0x12); // RegIrqFlags
while ((IrqFlags & 0b00001000) == 0) // wait until TxDone cleared
{
Thread.Sleep(10);
IrqFlags = sX127XDevice.ReadByte(0x12); // RegIrqFlags
Debug.Write(".");
}
Debug.WriteLine("");
sX127XDevice.WriteByte(0x12, 0b00001000); // clear TxDone bit
Debug.WriteLine("Send-Done");
Thread.Sleep(30000);
}
}
}
Loaded '/usr/lib/dotnet/shared/Microsoft.NETCore.App/5.0.4/System.Memory.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Sending 26 bytes message "Hello LoRa from .NET Core!"
Send-wait
....
Send-Done
Sending 26 bytes message "Hello LoRa from .NET Core!"
Send-wait
...
Send-Done
Sending 26 bytes message "Hello LoRa from .NET Core!"
Send-wait
...
Send-Done
Sending 26 bytes message "Hello LoRa from .NET Core!"
Send-wait
...
Send-Done
Sending 26 bytes message "Hello LoRa from .NET Core!"
Send-wait
...
Send-Done
Sending 26 bytes message "Hello LoRa from .NET Core!"
Send-wait
...
Send-Done
Sending 26 bytes message "Hello LoRa from .NET Core!"
Send-wait
...
Send-Done
Summary
In this iteration I sent a message from my .Net Core 5 dotnet/iot powered Raspberry PI to a Dragino LoRa Shield 915MHz on a Seeeduino V4.2 device. Every so often the payload was corrupted becuase I had not enabled the payload Cyclic Redundancy Check(CRC) functionality.