sandeepmistry / arduino-LoRa

An Arduino library for sending and receiving data using LoRa radios.
MIT License
1.65k stars 630 forks source link

Spurious reception / false packets #371

Closed BrendonHills closed 4 years ago

BrendonHills commented 4 years ago

Please can I have some advice? I am using Adafruit 32u4 Feather RFM95 LoRa boards and I have written code which uses two interrupts to wake from sleep, first on the activation of a RTC alarm (DS3231 Feather Board) and second on the activation of a change in a water sensor (for now simulated by a simple switch.) I have modularly tested to destruction every bit of code for the RTC, water sensor and sleep and all seems to work perfectly. The problem comes when I add the LoRa basic sender and receiver example code as functions called as a result of the ISR. I receive many erratic false packets giving sensor readings that have just NOT happened! I have narrowed it down to the LoRa receive module, and have done so by variously preventing the interrupts, and, at one point even disconnecting the transmitter, just leaving the receiver running, still receiving false packets. To be sure, I uploaded the basic examples of code from the library alone and without modification to the boards. Same issue, only this time instead of getting false activations (water high, water low, etc) I get spurious gibberish symbols and on receive only - see first image. I then suspected RFI, or perhpaps interference over the usb cable. So, I added ferrite cores to the (shielded) usb cable and wrapped the receiver in tin foil (apart from the antenna) to act as a Farday cage. Still the problem persists. I even ruled out faulty boards - if I upload the example basic RadioHead code to both boards it runs for days absolutely perfectly with no false packets. So I believe the issue MUST be in the LoRa receive code or library. Am I right, and if so, why? Please help if you can, I have spent over two weeks on this single issue and on Google but can't spot the problem any deeper. I would use the RadioHead library instead, but this one is so much simpler and neater for someone as relatively inexperienced as me - I want to make it work! Code is below and I attach a screenshot of spurious packets. My thanks in advance - all help greatly appreciated.

`//Initialisation ==============================================

//for battery voltage ============

define VBATPIN A9

float measuredvbat; int healthCheck;

// For the RTC ===========

include "Wire.h"

include "RTClibExtended.h"

define RTCwakePin 1

volatile bool clockAlarm = false; RTC_DS3231 RTC;

// For Sleep mode ===========

include "LowPower.h"

// For the sensor =============

define sensorWakePin 0

int waterLevel; volatile bool sensorAlarm = false; volatile int valA; int waterLevelSent;

// For LoRa ============

include

include

define RFM95_CS 8

define RFM95_RST 4

define RFM95_INT 7

void setup() {

// For the RTC ==================================================== pinMode(RTCwakePin, INPUT_PULLUP); //Initialize communication with the clock Wire.begin(); RTC.begin(); // dECIDE IF TO LEAVE THE BELOW OR REMOVE - NEED TO SET RTC SEPERATELY IF REMOVED //RTC.adjust(DateTime(DATE, TIME)); //set RTC date and time to COMPILE time //Set SQW pin to OFF RTC.writeSqwPinMode(DS3231_OFF); initiateAlarm(); //call fn to clear and set alarms //Set alarm1 every day at 09:00 - minutes first then hour, 0 for secs no account of daylight saving time //RTC.setAlarm(ALM1_MATCH_HOURS, 0, 0, 09, 0); //Set alarm1 at 1 min past the hour past the minute REMOVE IN FINAL RTC.setAlarm(ALM1_MATCH_MINUTES, 0, 01, 0, 0);///REMOVE IN FINAL

// For the Water Sensor ==================================== pinMode(sensorWakePin, INPUT_PULLUP);

// For LoRa =============================== LoRa.setPins(RFM95_CS, RFM95_RST, RFM95_INT); //433E6 or 868E6 // Change sync word (0xF3)ranges from 0-0xFF //LoRa.setSyncWord(0xF3);

while (!LoRa.begin(868E6)) { ; } LoRa.setTxPower(20); LoRa.enableCrc(); //prevent bad packets //Set Spreading Factor to 12 for more robust, yet slowest signal //LoRa.setSpreadingFactor(12); //Set coding rate for best signal immunity - range 5 - 8 - default 5 8 doubles TX time!! //LoRa.setCodingRate4(8); //LoRa.setSignalBandwidth(); }

void RTCWakeUp() { clockAlarm = true; }

void sensorWakeUp() { valA = digitalRead(sensorWakePin); sensorAlarm = true; }

void loop() { USBDevice.attach();//remove in final

// rtc interrupt response if (clockAlarm) { clockAlarm = !clockAlarm; //reset flag initiateAlarm(); measuredvbat = analogRead(VBATPIN); measuredvbat = 2; // we divided by 2, so multiply back measuredvbat = 3.3; // Multiply by 3.3V, our reference voltage measuredvbat /= 1024; // convert to voltage if (measuredvbat >= 3.4) { healthCheck = 2; } else { healthCheck = 3; } LORATXHealth(); }

// sensor interrupt response if (sensorAlarm) { sensorAlarm = !sensorAlarm;// reset flag sensorDebounce(); //only send packet via Lora if there has been a change to water level since last packet sent if ((waterLevel) != (waterLevelSent)) { LORATXSensor(); } }

// once dealt with interrupts, can go back to sleep goToSleep(); }

void goToSleep() { noInterrupts(); attachInterrupt(digitalPinToInterrupt(sensorWakePin), sensorWakeUp, CHANGE); attachInterrupt(digitalPinToInterrupt(RTCwakePin), RTCWakeUp, FALLING); //LoRa sleep??? interrupts(); LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); //Disable external pin interrupts on wake up detachInterrupt(digitalPinToInterrupt(RTCwakePin)); detachInterrupt(digitalPinToInterrupt(sensorWakePin)); }

void initiateAlarm() { //clear any pending alarms and reset RTC.armAlarm(1, false); RTC.clearAlarm(1); RTC.alarmInterrupt(1, false); RTC.armAlarm(2, false); RTC.clearAlarm(2); RTC.alarmInterrupt(2, false); RTC.alarmInterrupt(1, true);//reset }

void sensorDebounce() { //not really debounce. Just checking if water level is the same 3 secs later and only take action if so. delay(3000); int valB = digitalRead(sensorWakePin); if ((valA) != (valB)) {//tried surrounding this with 'noInterrupts' to preserve the volatile 'valA' but no effect goToSleep(); } else { waterLevel = !valB; } }

void LORATXHealth() { noInterrupts(); LoRa.beginPacket(); LoRa.print(healthCheck);//state of battery, 3 = OK, 4 = re-charge LoRa.endPacket(); //LORASLEEP?? if so need to wake on interrupt //what about an acknowledgement or re-send? interrupts(); }

void LORATXSensor() { noInterrupts(); LoRa.beginPacket(); LoRa.print(waterLevel); LoRa.endPacket(); waterLevelSent = waterLevel; //LORASLEEP?? if so need to wake on interrupt //what about an acknowledgement or re-send? interrupts(); }` This first image shows the spurious packets when just running the example code. LoRa garbage

This second image shows the spurious packets form my code at the receiver - all the entries from 20:22:30.730 are entirely spurious and I am convinced did not come from the transmitting code.

Serial Receiver

BrendonHills commented 4 years ago

Apologies, I forgot to post the receiver code which receives the ASCII value of the integers sent by the transmitter. The integer 0 is sent for water LOW, 1 for water HIGH, 2 for good battery and 3 for recharge battery. If it becomes reliable, then I would add output via digital pins according to the switch case.

`#include

include

define RFM95_CS 8

define RFM95_RST 4

define RFM95_INT 7

void setup() { LoRa.setPins(RFM95_CS, RFM95_RST, RFM95_INT); Serial.begin(9600); while (!Serial);

Serial.println("LoRa Receiver");

if (!LoRa.begin(868E6)) { Serial.println("Starting LoRa failed!"); while (1); } LoRa.setTxPower(20); LoRa.enableCrc(); //prevent bad packets }

void loop() { // try to parse packet int packetSize = LoRa.parsePacket(); if (packetSize) { // received a packet Serial.print("Received packet ");

// read packet
while (LoRa.available()) {
  int message = ((char)LoRa.read());
  switch (message) {
    case 48:
      Serial.println("Water LOW");
      break;
    case 49:
      Serial.println("Water HIGH");
      break;
    case 50:
      Serial.println("Health OK");
      break;
    case 51:
      Serial.println("Recharge battery");
      break;
  }
}

// print RSSI of packet
//Serial.print("' with RSSI ");
//Serial.println(LoRa.packetRssi());

} }`

IoTThinks commented 4 years ago

You can try to use callback receive instead of parsePacket. Check the examples.

beowulff commented 4 years ago

What makes you think that you are the only person within a 2 mile radius transmitting data?

BrendonHills commented 4 years ago

I tried upping the baud rate of the serial comms last night as I came across a post late last night. I increased the baud rate between the receiver and the computer from 9600 to 115200 just in case it may help - no difference.

You can try to use callback receive instead of parsePacket. Check the examples. I will check callback thanks.

What makes you think that you are the only person within a 2 mile radius transmitting data? As to other LoRa - I live VERY rurally, 1 mile from the nearest settlement with just three neighbours a few hundred metres away, nothing shown on the Things Network, and no 'interference' on the same frequency using the RadioHead library.

IoTThinks commented 4 years ago

Very likely from other LoRa sources. You can change to a slightly different frequency like 870 Mhz and see?

Or you can drop those packets with RSSI < -100.

BrendonHills commented 4 years ago

Very likely from other LoRa sources. You can change to a slightly different frequency like 870 Mhz and see? Just tried this suggestion and moved to 870 Mhz. Same issue arose within half an hour false packets. Also tried a further frequency - same issue. I am convinced it is not other LoRa. It must be either: a) something in my receiver code b)something in the library (highly unlikely!) c)something to do with the serial connection of the receiver to my computer. What to try next anyone please? Still working on the callback issue but looking after the kids today! Or you can drop those packets with RSSI < -100. This is not desirable for my application.

IoTThinks commented 4 years ago

Try again without sleeping in node.

BrendonHills commented 4 years ago

Yes tried that. As I said in the beginning, the same issue is present with and without sleep mode at the transmitter, with and without the interrupts and with and without anything connected to the transmitter at all. I have stripped it all back to basics and rebuilt, testing at every stage. It even occurs when just the receiver alone is connected, no transmitter at all. Th transmitter appears to work perfectly, although I can’t monitor it iFinally, there is no sleep mode in the receiver. If I run the basic sender and receiver examples from the library, it still happens. And, if I run the Radiohead examples from their library, on the same frequency and the same boards and USB serial connections, it doesn’t happen! It’s really stumping me.

Daimon.


From: IoTThinks.com notifications@github.com Sent: Tuesday, June 2, 2020 11:14:34 AM To: sandeepmistry/arduino-LoRa arduino-LoRa@noreply.github.com Cc: BrendonHills daimontilley@hotmail.com; Author author@noreply.github.com Subject: Re: [sandeepmistry/arduino-LoRa] Spurious reception / false packets (#371)

Try again without sleeping in node.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/sandeepmistry/arduino-LoRa/issues/371#issuecomment-637440090, or unsubscribehttps://github.com/notifications/unsubscribe-auth/APZV26FFZLP5I3HLA7LOKVTRUTGIVANCNFSM4NQGHWDQ.

beowulff commented 4 years ago

That’s because you are dismissing the obvious answer - you are receiving other device’s transmissions. LoRa can transmit over 400 miles in optimal conditions.

BrendonHills commented 4 years ago

Thanks Beowulff and I am very grateful for your comments and suggestions. I do understand your point, and I sincerely hope I am not giving the impression of dismissing it out of hand, that is not my intention, it’s just that it seems unlikely given the experimentation I have tried. Surely if it was interference from another LoRa source then it should also appear in the Radiohead receiver, unless there is a big frequency discrepancy, and it does not, even when running side by side, at the same time, on identical boards? Interestingly, I have now swapped the receiver code from the basic LoRaReceiver to Receiver Callback, as suggested by iotthinks.com and so far, seven hours in, there seem to be MANY less spurious packets, but still some.

I think the Faraday cage and screening steps I have taken should minimise any possibility of RFI, although that is still also a possibility I guess.

So, I think my next step is to take further action in case it is indeed interference. I assume that if I set the SyncWord facility, I should only receive transmissions with that syncword contained, thereby greatly reducing the risk of interference? Are there any other steps you can suggest to address this in software at all?

Thanks again for the comments – I am determined to try everything!

Daimon.

From: beowulff notifications@github.com Sent: Tuesday, June 2, 2020 1:56:53 PM To: sandeepmistry/arduino-LoRa arduino-LoRa@noreply.github.com Cc: BrendonHills daimontilley@hotmail.com; Author author@noreply.github.com Subject: Re: [sandeepmistry/arduino-LoRa] Spurious reception / false packets (#371)

That’s because you are dismissing the obvious answer - you are receiving other device’s transmissions. LoRa can transmit over 400 miles in optimal conditions.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/sandeepmistry/arduino-LoRa/issues/371#issuecomment-637524265, or unsubscribehttps://github.com/notifications/unsubscribe-auth/APZV26FNNZUUT4F5HFHQXMLRUTZJLANCNFSM4NQGHWDQ.

BrendonHills commented 4 years ago

I see also that amending SF might help with any interference from other LoRa transmissions. I will try this and sync word and report back tomorrow. Question, can you set a decimal in the frequency - e.g. 869.3e6??

IoTThinks commented 4 years ago

The default sync word may be different between two library.

This library has default sync word 0x12. Can try to change to RadioHead value? Or other values?

Yes 868.12e6 works. Or 868120e3 is ok.

BrendonHills commented 4 years ago

Thanks very much. I am grateful to you both IoTThinks.com and BeoWulff. I made changes to frequency, sync word, SF and CR last night and left it on overnight – so far so good – no spurious packets after ten hours! I will leave it on for the rest of the day to be sure.

Thanks for the subtleties IoTThinks.com and thanks to BeoWulff for pushing me to not dismiss interference as the cause - I am humbled, I have learnt and I have hopefully resolved the problem!

By the end of the day I hope that I can be confident that the issue is resolved, so this thread can be closed.

Best wishes all.

Sent from Mailhttps://go.microsoft.com/fwlink/?LinkId=550986 for Windows 10

From: IoTThinks.commailto:notifications@github.com Sent: 03 June 2020 02:22 To: sandeepmistry/arduino-LoRamailto:arduino-LoRa@noreply.github.com Cc: BrendonHillsmailto:daimontilley@hotmail.com; Authormailto:author@noreply.github.com Subject: Re: [sandeepmistry/arduino-LoRa] Spurious reception / false packets (#371)

The default sync word may be different between two library.

This library has default sync word 0x12. Can try to change to RadioHead value? Or other values?

Yes 868.12e6 works. Or 868120e3 is ok.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/sandeepmistry/arduino-LoRa/issues/371#issuecomment-637898314, or unsubscribehttps://github.com/notifications/unsubscribe-auth/APZV26AYUIK3HVZ3TV65FPDRUWQTVANCNFSM4NQGHWDQ.

BrendonHills commented 4 years ago

Thanks again to you both for yourt comments. I am now 48 hours in and no spurious packets - so it was interference after all. I will close the issue and am grateful for the help.