.NET Core SX127X library Arduino LoRaSetSpread

“Playing nice” with Arduino-LoRa Samples

The arduino-LoRa library comes with a number of samples showing how to configure a SX127X device. The LoRaSetSpread sample sets the RegModemtConfig2 (masking out previous CodingRate and ImplicitHeaderModeOn with 0xFF) to configure spreading Factor (bits 4-7) to 8 which is 256 chips/symbol.

..
void setup() {
  Serial.begin(9600);                   // initialize serial
  while (!Serial);

  Serial.println("LoRa Duplex - Set spreading factor");

  // override the default CS, reset, and IRQ pins (optional)
  LoRa.setPins(csPin, resetPin, irqPin); // set CS, reset, IRQ pin

  if (!LoRa.begin(915E6)) {             // initialize ratio at 915 MHz
    Serial.println("LoRa init failed. Check your connections.");
    while (true);                       // if failed, do nothing
  }

  LoRa.setSpreadingFactor(8);           // ranges from 6-12,default 7 see API docs
  Serial.println("LoRa init succeeded.");
}

In my library I use an enumeration to represent the different spreading factors to make configuration easier for humans. (the _ prefix is due to the C# language syntax)

// RegModemConfig2
public enum RegModemConfig2SpreadingFactor : byte
{
	_64ChipsPerSymbol = 0b01100000,
	_128ChipsPerSymbol = 0b01110000,
	_256ChipsPerSymbol = 0b10000000,
	_512ChipsPerSymbol = 0b10010000,
	_1024ChipsPerSymbol = 0b10100000,
	_2048ChipsPerSymbol = 0b10110000,
	_4096ChipsPerSymbol = 0b11000000,
}
private const RegModemConfig2SpreadingFactor RegModemConfig2SpreadingFactorDefault = RegModemConfig2SpreadingFactor._128ChipsPerSymbol;

The SX127X.NetCore only sets the spreadingFactor, symbolTimeout, txContinuousMode, or rxPayloadCrcOn registers if any of them is different from their defaults.

// Set regModemConfig2 if any of the settings not defaults
if ((spreadingFactor != RegModemConfig2SpreadingFactorDefault) || (txContinuousMode != false) | (rxPayloadCrcOn != false) || (symbolTimeout != SymbolTimeoutDefault))
{
	byte RegModemConfig2Value = (byte)spreadingFactor;
	if (txContinuousMode)
	{
		RegModemConfig2Value |= RegModemConfig2TxContinuousModeOn;
	}
	if (rxPayloadCrcOn)
	{
		RegModemConfig2Value |= RegModemConfig2RxPayloadCrcOn;
	}
	// Get the MSB of SymbolTimeout
	byte[] symbolTimeoutBytes = BitConverter.GetBytes(symbolTimeout);

	// Only the zeroth & second bit of byte matter
	symbolTimeoutBytes[1] &= SymbolTimeoutMsbMask;
	RegModemConfig2Value |= symbolTimeoutBytes[1];
	this.WriteByte((byte)Registers.RegModemConfig2, RegModemConfig2Value);
}

I modified the SX127X.NetCore SX127XLoRaDeviceClient to change the SpreadingFactor to _256ChipsPerSymbol (0b10000000) to match the Arduino client.

...
#if UPUTRONICS_RPIPLUS_CS0 && !UPUTRONICS_RPIPLUS_CS1
	SX127XDevice sX127XDevice = new SX127XDevice(SX127XDevice.ChipSelectLine.CS0, 25);
#endif
#if UPUTRONICS_RPIPLUS_CS1 && UPUTRONICS_RPIPLUS_CS0
	SX127XDevice sX127XDevice = new SX127XDevice(SX127XDevice.ChipSelectLine.CS1, 16);
#endif

	sX127XDevice.Initialise(
		SX127XDevice.RegOpModeMode.ReceiveContinuous,
		Frequency,
		paBoost: true,
#if LORA_SET_SYNCWORD
		syncWord: 0xF3,
		invertIQTX: true,
		rxDoneignoreIfCrcMissing: false
#endif
#if LORA_SET_SPREAD
		spreadingFactor: SX127XDevice.RegModemConfig2SpreadingFactor._256ChipsPerSymbol,
		invertIQTX: true,
		rxDoneignoreIfCrcMissing: false
   );

#if DEBUG
	sX127XDevice.RegisterDump();
#endif
...

In the Visual Studio output window I could see that RegModemConfig2(0x1E) was set to 0x80.

Register dump
Register 0x01 - Value 0X85 - Bits 10000101
Register 0x02 - Value 0X1a - Bits 00011010
Register 0x03 - Value 0X0b - Bits 00001011
Register 0x04 - Value 0X00 - Bits 00000000
Register 0x05 - Value 0X52 - Bits 01010010
Register 0x06 - Value 0Xe4 - Bits 11100100
Register 0x07 - Value 0Xc0 - Bits 11000000
Register 0x08 - Value 0X00 - Bits 00000000
Register 0x09 - Value 0Xcf - Bits 11001111
Register 0x0a - Value 0X09 - Bits 00001001
Register 0x0b - Value 0X2b - Bits 00101011
Register 0x0c - Value 0X20 - Bits 00100000
Register 0x0d - Value 0X00 - Bits 00000000
Register 0x0e - Value 0X80 - Bits 10000000
Register 0x0f - Value 0X00 - Bits 00000000
Register 0x10 - Value 0X00 - Bits 00000000
Register 0x11 - Value 0X00 - Bits 00000000
Register 0x12 - Value 0X00 - Bits 00000000
Register 0x13 - Value 0X00 - Bits 00000000
Register 0x14 - Value 0X00 - Bits 00000000
Register 0x15 - Value 0X00 - Bits 00000000
Register 0x16 - Value 0X00 - Bits 00000000
Register 0x17 - Value 0X00 - Bits 00000000
Register 0x18 - Value 0X04 - Bits 00000100
Register 0x19 - Value 0X00 - Bits 00000000
Register 0x1a - Value 0X00 - Bits 00000000
Register 0x1b - Value 0X3d - Bits 00111101
Register 0x1c - Value 0X00 - Bits 00000000
Register 0x1d - Value 0X72 - Bits 01110010
Register 0x1e - Value 0X80 - Bits 10000000
Register 0x1f - Value 0X64 - Bits 01100100
Register 0x20 - Value 0X00 - Bits 00000000
Register 0x21 - Value 0X08 - Bits 00001000
Register 0x22 - Value 0X01 - Bits 00000001
Register 0x23 - Value 0Xff - Bits 11111111
Register 0x24 - Value 0X00 - Bits 00000000
Register 0x25 - Value 0X00 - Bits 00000000
Register 0x26 - Value 0X04 - Bits 00000100
Register 0x27 - Value 0X00 - Bits 00000000
Register 0x28 - Value 0X00 - Bits 00000000
Register 0x29 - Value 0X00 - Bits 00000000
Register 0x2a - Value 0X00 - Bits 00000000
Register 0x2b - Value 0X00 - Bits 00000000
Register 0x2c - Value 0X0d - Bits 00001101
Register 0x2d - Value 0X50 - Bits 01010000
Register 0x2e - Value 0X14 - Bits 00010100
Register 0x2f - Value 0X45 - Bits 01000101
Register 0x30 - Value 0X55 - Bits 01010101
Register 0x31 - Value 0Xc3 - Bits 11000011
Register 0x32 - Value 0X05 - Bits 00000101
Register 0x33 - Value 0X37 - Bits 00110111
Register 0x34 - Value 0X1c - Bits 00011100
Register 0x35 - Value 0X0a - Bits 00001010
Register 0x36 - Value 0X03 - Bits 00000011
Register 0x37 - Value 0X0a - Bits 00001010
Register 0x38 - Value 0X42 - Bits 01000010
Register 0x39 - Value 0X12 - Bits 00010010
Register 0x3a - Value 0X49 - Bits 01001001
Register 0x3b - Value 0X19 - Bits 00011001
Register 0x3c - Value 0X00 - Bits 00000000
Register 0x3d - Value 0Xaf - Bits 10101111
Register 0x3e - Value 0X00 - Bits 00000000
Register 0x3f - Value 0X00 - Bits 00000000
Register 0x40 - Value 0X00 - Bits 00000000
Register 0x41 - Value 0X00 - Bits 00000000
Register 0x42 - Value 0X12 - Bits 00010010

Loaded '/usr/lib/dotnet/shared/Microsoft.NETCore.App/5.0.4/System.Text.Encoding.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Loaded '/usr/lib/dotnet/shared/Microsoft.NETCore.App/5.0.4/Microsoft.Win32.Primitives.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
10:04:22-RX PacketSnr 11.8 Packet RSSI -45dBm RSSI -109dBm 15 byte message "HeLoRa World! 2"
10:04:31-RX PacketSnr 11.5 Packet RSSI -45dBm RSSI -104dBm 15 byte message "HeLoRa World! 4"
10:04:32-TX To 0x48 From 0x65 Count 108 28 bytes message Hello LoRa from .NET Core! 1
10:04:32-TX Done
10:04:41-RX PacketSnr 12.0 Packet RSSI -45dBm RSSI -104dBm 15 byte message "HeLoRa World! 6"
10:04:42-TX To 0x48 From 0x65 Count 108 28 bytes message Hello LoRa from .NET Core! 2
10:04:42-TX Done

This matched the Arduino serial monitor output.

Summary

The LoRaSetSpread sample illustrates how the SX127X.NetCore library modifies register(s) only if a value specified in the Initialise method parameter list is different from the default.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.