Rfm9xLoRaDevice NetMF SNR and RSSI

The signal to noise Ratio (SNR) and Received Signal Strength Indication(RSSI) for inbound messages required reading values from three registers
•RegPktSnrValue
•RegPktRssiValue
•RegRssiValue

I had to modify the OnDataRecievedHandler method signature so the values could be returned

 public delegate void OnDataRecievedHandler(float packetSnr, int packetRssi, int rssi, byte[] data);

I was inspired by the RSSI adjustment approach used in the Arduino-LoRa library

// Get the RSSI HF vs. LF port adjustment section 5.5.5 RSSI and SNR in LoRa Mode
float packetSnr = this.Rfm9XLoraModem.ReadByte((byte)Registers.RegPktSnrValue) * 0.25f;

int rssi = this.Rfm9XLoraModem.ReadByte((byte)Registers.RegRssiValue);
if (Frequency > RFMidBandThreshold)
{
  rssi = RssiAdjustmentHF + rssi;
}
else
{
  rssi = RssiAdjustmentLF + rssi;
}

int packetRssi = this.Rfm9XLoraModem.ReadByte((byte)Registers.RegPktRssiValue);
if (Frequency > RFMidBandThreshold)
{
  packetRssi = RssiAdjustmentHF + packetRssi;
}
else
{
  packetRssi = RssiAdjustmentLF + packetRssi;
}

OnDataReceived?.Invoke( packetSnr, packetRssi, rssi, messageBytes);

The values displayed in the Rfm9xLoRaDeviceClient application looked reasonable, but will need further checking

00:06:14-Rfm9X PacketSnr 9.8 Packet RSSI -47dBm RSSI -111dBm = 28 byte message "Hello W10 IoT Core LoRa! 182"
Sending 20 bytes message Hello NetMF LoRa! 38
Transmit-Done
00:06:24-Rfm9X PacketSnr 9.8 Packet RSSI -48dBm RSSI -111dBm = 28 byte message "Hello W10 IoT Core LoRa! 181"
Sending 20 bytes message Hello NetMF LoRa! 39
Transmit-Done
00:06:34-Rfm9X PacketSnr 9.8 Packet RSSI -47dBm RSSI -112dBm = 28 byte message "Hello W10 IoT Core LoRa! 180"
Sending 20 bytes message Hello NetMF LoRa! 40
Transmit-Done
00:06:44-Rfm9X PacketSnr 10.0 Packet RSSI -48dBm RSSI -111dBm = 28 byte message "Hello W10 IoT Core LoRa! 179"

 

Rfm9xLoRaDevice SNR and RSSI revisited

The magic numbers for the high frequency(HF) vs. low frequency(LF) adjustment bugged me

int rssi = this.RegisterManager.ReadByte((byte)Registers.RegRssiValue);
if (Frequency < 868E6)
	rssi = -164 + rssi; // LF output port
else
	rssi = -157 + rssi; // HF output port

int packetRssi = this.RegisterManager.ReadByte((byte)Registers.RegPktRssiValue);
if (Frequency < 868E6)
	packetRssi = -164 + rssi; // LF output port
else
	packetRssi = -157 + rssi; // HF output port

After some searching I ended up at the Semetch LoRaMac node github repository. In that code they had a number of constants which looked like a better approach.

if( SX1276.Settings.Channel > RF_MID_BAND_THRESH )
{
   rssi = RSSI_OFFSET_HF + SX1276Read( REG_LR_RSSIVALUE );
}
else
{
   rssi = RSSI_OFFSET_LF + SX1276Read( REG_LR_RSSIVALUE );
}

I also fixed a couple of bugs I noticed with the maths and the code now looks like this

int rssi = this.RegisterManager.ReadByte((byte)Registers.RegRssiValue);
if (Frequency > RFMidBandThreshold)
   rssi = RssiAdjustmentHF + rssi;
else
   rssi = RssiAdjustmentLF + rssi;

int packetRssi = this.RegisterManager.ReadByte((byte)Registers.RegPktRssiValue);
if (Frequency > RFMidBandThreshold)
   packetRssi = RssiAdjustmentHF + packetRssi;
else
   packetRssi = RssiAdjustmentLF + packetRssi;

This has also got me thing about how RegLna – LnaBoostLf/LnaBoostHf should be handled as well.

Rfm9xLoRaDevice SNR and RSSI

The signal to noise Ratio (SNR) and Received Signal Strength Indication(RSSI) for inbound messages required reading values from three registers

  • RegPktSnrValue
  • RegPktRssiValue
  • RegRssiValue

I had to modify the EventArgs returned to the customer

public class OnDataReceivedEventArgs : EventArgs
{
	public float PacketSnr { get; set; }
	public int PacketRssi { get; set; }
	public int Rssi { get; set; }
	public byte[] Data { get; set; }
}

I was inspired by the RSSI adjustment approach used in the Arduino-LoRa library

// Get the RSSI HF vs. LF port adjustment section 5.5.5 RSSI and SNR in LoRa Mode
float packetSnr = this.RegisterManager.ReadByte((byte)Registers.RegPktSnrValue) * 0.25f;

int rssi = this.RegisterManager.ReadByte((byte)Registers.RegRssiValue);
if (Frequency < 868E6)
	rssi = -164 - rssi; // LF output port
else
	rssi = -157 + rssi; // HF output port

int packetRssi = this.RegisterManager.ReadByte((byte)Registers.RegPktRssiValue);
if (Frequency < 868E6)
	packetRssi = -164 - rssi; // LF output port
else
	packetRssi = -157 - rssi; // HF output port

OnDataReceivedEventArgs receiveArgs = new OnDataReceivedEventArgs
{
	PacketSnr = packetSnr,
	Rssi = rssi,
	PacketRssi = packetRssi,
	Data = messageBytes
};

The values displayed in the Rfm9xLoRaDeviceClient application looked reasonable, but will need further checking