.Net Meadow RFM95/96/97/98 LoRa library Part4

Transmit Basic

I had a couple of Armtronix IA005 SX1276 loRa nodes sitting on my desk from a recent post so I used one of them running a modified version of the Arduino LoRa library LoRaSetSyncWord example to receive messages from my Meadow device.

/*
  LoRa Duplex communication with Sync Word
 
  Sends a message every half second, and polls continually
  for new incoming messages. Sets the LoRa radio's Sync Word.
 
  Spreading factor is basically the radio's network ID. Radios with different
  Sync Words will not receive each other's transmissions. This is one way you
  can filter out radios you want to ignore, without making an addressing scheme.
 
  See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf
  for more on Sync Word.
 
  created 28 April 2017
  by Tom Igoe
*/
#include <stdlib.h>
#include <LoRa.h>
const int csPin = PA4;          // LoRa radio chip select
const int resetPin = PC13;       // LoRa radio reset
const int irqPin = PA11;         // change for your board; must be a hardware interrupt pin
 
byte msgCount = 0;            // count of outgoing messages
int interval = 2000;          // interval between sends
long lastSendTime = 0;        // time of last packet send
 
void setup() {
  Serial.begin(9600);                   // initialize serial
  while (!Serial);
 
  Serial.println("LoRa Duplex - Set sync word");
 
  // 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.setSyncWord(0x12);           // ranges from 0-0xFF, default 0x34, see API docs
 
  LoRa.dumpRegisters(Serial);
  Serial.println("LoRa init succeeded.");
}
 
void loop() {
  if (millis() - lastSendTime > interval) {
    String message = "HeLoRa World! ";   // send a message
    message += msgCount;
    sendMessage(message);
    Serial.println("Sending " + message);
    lastSendTime = millis();            // timestamp the message
    interval = random(1000) + 10000;    // 10-11 seconds
    msgCount++;
  }
 
  // parse for a packet, and call onReceive with the result:
  onReceive(LoRa.parsePacket());
}
 
void sendMessage(String outgoing) {
  LoRa.beginPacket();                   // start packet
  LoRa.print(outgoing);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}
 
void onReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return
 
  // read packet header bytes:
  String incoming = "";
 
  while (LoRa.available()) {
    incoming += (char)LoRa.read();
  }
 
  Serial.println("Message: " + incoming);
  Serial.println("RSSI: " + String(LoRa.packetRssi()));
  Serial.println("Snr: " + String(LoRa.packetSnr()));
  Serial.println();
}

The Meadow application

	public class MeadowApp : App<F7Micro, MeadowApp>
	{
		private Rfm9XDevice rfm9XDevice;

		public MeadowApp()
		{
			ISpiBus spiBus = Device.CreateSpiBus(500);
			if (spiBus == null)
			{
				Console.WriteLine("spiBus == null");
			}

			rfm9XDevice = new Rfm9XDevice(Device, spiBus, Device.Pins.D09, Device.Pins.D11);

			// Put device into LoRa + Sleep mode
			rfm9XDevice.RegisterWriteByte(0x01, 0b10000000); // RegOpMode 

			// Set the frequency to 915MHz
			byte[] frequencyWriteBytes = { 0xE4, 0xC0, 0x00 }; // RegFrMsb, RegFrMid, RegFrLsb
			rfm9XDevice.RegisterWrite(0x06, frequencyWriteBytes);

			// More power PA Boost
			rfm9XDevice.RegisterWriteByte(0x09, 0b10000000); // RegPaConfig

			while (true)
			{
				rfm9XDevice.RegisterWriteByte(0x0E, 0x0); // RegFifoTxBaseAddress 

				// Set the Register Fifo address pointer
				rfm9XDevice.RegisterWriteByte(0x0D, 0x0); // RegFifoAddrPtr 

				string messageText = "Hello LoRa!";

				// load the message into the fifo
				byte[] messageBytes = UTF8Encoding.UTF8.GetBytes(messageText);
				foreach (byte b in messageBytes)
				{
					rfm9XDevice.RegisterWriteByte(0x0, b); // RegFifo
				}

				// Set the length of the message in the fifo
				rfm9XDevice.RegisterWriteByte(0x22, (byte)messageBytes.Length); // RegPayloadLength

				Console.WriteLine("Sending {0} bytes message {1}", messageBytes.Length, messageText);
				/// Set the mode to LoRa + Transmit
				rfm9XDevice.RegisterWriteByte(0x01, 0b10000011); // RegOpMode 

				// Wait until send done, no timeouts in PoC
				Console.WriteLine("Send-wait");
				byte IrqFlags = rfm9XDevice.RegisterReadByte(0x12); // RegIrqFlags
				while ((IrqFlags & 0b00001000) == 0)  // wait until TxDone cleared
				{
					Task.Delay(10).Wait();
					IrqFlags = rfm9XDevice.RegisterReadByte(0x12); // RegIrqFlags
					Console.Write(".");
				}
				Console.WriteLine("");
				rfm9XDevice.RegisterWriteByte(0x12, 0b00001000); // clear TxDone bit
				Console.WriteLine("Send-Done");

				Task.Delay(30000).Wait();
			}
		}

When I ran the meadow application after some messing around with the jumper wires.

'App.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'. 
'App.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\BrynLewis\source\repos\RFM9X.Meadow\TransmitBasic\bin\Debug\net472\App.exe'. Symbols loaded.
'App.exe' (CLR v4.0.30319: App.exe): Loaded 'C:\Users\BrynLewis\source\repos\RFM9X.Meadow\TransmitBasic\bin\Debug\net472\Meadow.dll'. 
The program '[37572] App.exe: Program Trace' has exited with code 0 (0x0).
The program '[37572] App.exe' has exited with code 0 (0x0).
.
.
DirectRegisterAccess = True
.
.
Sending 11 bytes message Hello LoRa!
Send-wait
Send-Done
Sending 11 bytes message Hello LoRa!
Send-wait
.
Send-Done

I could the see the messages arriving at the Armtronix device in the Arduino monitor (the other messages in the monitor are my solar powered weather station and soil moisture monitoring node).

12:47:55.198 -> Sending HeLoRa World! 10
12:48:05.745 -> Sending HeLoRa World! 12
12:48:06.663 -> Message: ⸮LoRaIoT1Maduino2at 85.8,ah 19,wsa 5,wsg 8,wd 123.38,r 0.00,
12:48:06.730 -> RSSI: -71
12:48:06.730 -> Snr: 10.00
12:48:06.730 ->
12:48:08.770 -> Message: Hello LoRa!
12:48:08.770 -> RSSI: -47
12:48:08.804 -> Snr: 9.00
12:48:08.804 ->
12:48:16.555 -> Sending HeLoRa World! 14
12:48:26.847 -> Sending HeLoRa World! 16
12:48:37.154 -> Sending HeLoRa World! 18
12:48:39.469 -> Message: Hello LoRa!
12:48:39.469 -> RSSI: -46
12:48:39.536 -> Snr: 9.00
12:48:39.536 ->
12:48:47.311 -> Sending HeLoRa World! 20
12:48:58.094 -> Sending HeLoRa World! 22
12:49:07.748 -> Message: ⸮LoRaIoT1Maduino2at 86.0,ah 19,wsa 5,wsg 15,wd 155.63,r 0.00,
12:49:07.817 -> RSSI: -71
12:49:07.817 -> Snr: 9.50
12:49:07.817 ->
12:49:08.464 -> Sending HeLoRa World! 24
12:49:10.097 -> Message: Hello LoRa!
12:49:10.097 -> RSSI: -46
12:49:10.130 -> Snr: 9.75
12:49:10.130 ->
12:49:19.373 -> Sending HeLoRa World! 26
12:49:30.125 -> Sending HeLoRa World! 28
12:49:40.262 -> Sending HeLoRa World! 30
12:49:40.671 -> Message: Hello LoRa!
12:49:40.671 -> RSSI: -46
12:49:40.705 -> Snr: 9.25
12:49:40.705 ->
12:49:50.725 -> Sending HeLoRa World! 32
12:50:01.081 -> Sending HeLoRa World! 34
12:50:08.800 -> Message: ⸮LoRaIoT1Maduino2at 85.6,ah 19,wsa 5,wsg 11,wd 159.00,r 0.00,
12:50:08.868 -> RSSI: -72
12:50:08.868 -> Snr: 10.00
12:50:08.868 ->
12:50:11.219 -> Message: Hello LoRa!
12:50:11.219 -> RSSI: -46
12:50:11.252 -> Snr: 9.25
12:50:11.252 ->
12:50:11.526 -> Sending HeLoRa World! 36
12:50:21.731 -> Sending HeLoRa World! 38
12:50:32.696 -> Sending HeLoRa World! 40
12:50:41.741 -> Message: Hello LoRa!
12:50:41.741 -> RSSI: -46
12:50:41.775 -> Snr: 9.25
12:50:41.775 ->
12:50:43.685 -> Sending HeLoRa World! 42
12:50:54.566 -> Sending HeLoRa World! 44
12:51:05.604 -> Sending HeLoRa World! 46
12:51:09.852 -> Message: ⸮LoRaIoT1Maduino2at 85.3,ah 19,wsa 2,wsg 8,wd 150.75,r 0.00,
12:51:09.954 -> RSSI: -71
12:51:09.954 -> Snr: 9.50
12:51:09.954 ->
12:51:12.400 -> Message: Hello LoRa!
12:51:12.400 -> RSSI: -46
12:51:12.433 -> Snr: 9.00
12:51:12.433 ->
12:51:16.511 -> Sending HeLoRa World! 48
12:51:27.530 -> Sending HeLoRa World! 50
12:51:37.796 -> Sending HeLoRa World! 52
12:51:42.968 -> Message: Hello LoRa!
12:51:42.968 -> RSSI: -45
12:51:43.003 -> Snr: 9.25
12:51:43.003 ->
12:51:48.389 -> Sending HeLoRa World! 54
12:51:59.052 -> Sending HeLoRa World! 56
12:52:09.251 -> Sending HeLoRa World! 58
12:52:10.912 -> Message: ⸮LoRaIoT1Maduino2at 85.1,ah 19,wsa 2,wsg 6,wd 84.00,r 0.00,
12:52:11.013 -> RSSI: -70
12:52:11.013 -> Snr: 9.75
12:52:11.013 ->
12:52:13.546 -> Message: Hello LoRa!
12:52:13.546 -> RSSI: -46
12:52:13.581 -> Snr: 9.75
12:52:13.581 ->

This PoC code is getting a bit nasty with magic numbers and no error checking. The next step is getting a basic packet receive working…

2 thoughts on “.Net Meadow RFM95/96/97/98 LoRa library Part4

  1. Pingback: .Net Meadow RFM95/96/97/98 LoRa library Part5 | devMobile's blog

  2. Pingback: .Net Meadow RFM95/96/97/98 LoRa library Part7 | devMobile's blog

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.