Hi,
I have developed a networked system using a Feather M0 microcontroller (RF915) communicating over LoraWAN with some locally deployed LoraWAN gateways (uses RAK gateway module with raspberry pi 3+). I can transmit and receive the data successfully.
I ran some experiments to observe RSSI, SNR values on the gateway for different locations of the micrcontroller’s sensor. While there are significant changes in RSSI values as the distance changes, I do not see the spreading factor change? Theoretically, the spreading factor should change for large distances between the gateway and the sensor. Was wondering why this is not working in our case.
I am using the LMIC library and modified the example sketch of ‘ttn-otaa-feather-us915-dht22’ of the LoRaWAN LMIC library accordingly, with the following changes related to ADR and spreading factor.
LMIC_setLinkCheckMode(0); //disable the ADR
LMIC_setDrTxpow(DR_SF7,14); //SF is set to 7
Here is my code snippet:
/*******************************************************************************
* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
*
* Permission is hereby granted, free of charge, to anyone
* obtaining a copy of this document and accompanying files,
* to do whatever they want with them without any restriction,
* including, but not limited to, copying, modification and redistribution.
* NO WARRANTY OF ANY KIND IS PROVIDED.
*
* This example sends a valid LoRaWAN packet with payload "Hello,
* world!", using frequency and encryption settings matching those of
* the The Things Network.
*
* This uses OTAA (Over-the-air activation), where where a DevEUI and
* application key is configured, which are used in an over-the-air
* activation procedure where a DevAddr and session keys are
* assigned/generated for use with all further communication.
*
* Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in
* g1, 0.1% in g2), but not the TTN fair usage policy (which is probably
* violated by this sketch when left running for longer)!
* To use this sketch, first register your application and device with
* the things network, to set or generate an AppEUI, DevEUI and AppKey.
* Multiple devices can use the same AppEUI, but each device has its own
* DevEUI and AppKey.
*
* Do not forget to define the radio type correctly in config.h.
*
*******************************************************************************/
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
// #include <Adafruit_Sensor.h>
// #include <DHT.h>
// #include <DHT_U.h>
#include <CayenneLPP.h>
// #define DHTPIN 12
// #define DHTTYPE DHT22 // DHT 22 (AM2302)
// DHT_Unified dht(DHTPIN, DHTTYPE);
// Init CayenneLPP Payload
CayenneLPP lpp(51);
// This EUI must be in little-endian format, so least-significant-byte
// first. When copying an EUI from ttnctl output, this means to reverse
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
// 0x70.
break;
case EV_JOINING:
Serial.println(F("EV_JOINING"));
break;
case EV_JOINED:
Serial.println(F("EV_JOINED"));
// Disable link check validation (automatically enabled
// during join, but not supported by TTN at this time).
LMIC_setLinkCheckMode(0);
break;
case EV_RFU1:
Serial.println(F("EV_RFU1"));
break;
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if (LMIC.dataLen) {
Serial.println(F("Received "));
Serial.println(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
default:
Serial.println(F("Unknown event"));
break;
}
}
void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
}
// else {
// // Clear Payload
// lpp.reset();
// // Get temperature event and print its value.
// //sensors_event_t event;
// dht.temperature().getEvent(&event);
// if (isnan(event.temperature)) {
// Serial.println(F("Error reading temperature!"));
// }
// else {
// Serial.print(F("Temperature: "));
// Serial.print(event.temperature);
// Serial.println(F("°C"));
// lpp.addTemperature(1, event.temperature);
// }
// // Get humidity event and print its value.
// dht.humidity().getEvent(&event);
// if (isnan(event.relative_humidity)) {
// Serial.println(F("Error reading humidity!"));
// }
// else {
// Serial.print(F("Humidity: "));
// Serial.print(event.relative_humidity);
// Serial.println(F("%"));
// lpp.addRelativeHumidity(2, event.relative_humidity);
// }
// // Prepare upstream data transmission at the next possible time.
// LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0);
// Serial.println(F("Packet queued"));
// }
// // Next TX is scheduled after TX_COMPLETE event.
else {
// Prepare upstream data transmission at the next possible time.
//mydata2=mydata2+1;
//newData= mydata1+String(mydata2);
//String mdata=String(mydata);
counter=counter+1;
mydata1[0]=counter;
LMIC_setTxData2(1,mydata1, sizeof(mydata1)-1,0);
//LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
Serial.println(F("Packet queued"));
}
}
void setup() {
Serial.begin(9600);
Serial.println(F("Starting"));
#ifdef VCC_ENABLE
// For Pinoccio Scout boards
pinMode(VCC_ENABLE, OUTPUT);
digitalWrite(VCC_ENABLE, HIGH);
delay(1000);
#endif
// Initialize DHT22.
// dht.begin();
// Serial.println(F("DHTxx Unified Sensor Example"));
// Print temperature sensor details.
// sensor_t sensor;
// dht.temperature().getSensor(&sensor);
// Serial.println(F("------------------------------------"));
// Serial.println(F("Temperature Sensor"));
// Serial.print (F("Sensor Type: ")); Serial.println(sensor.name);
// Serial.print (F("Driver Ver: ")); Serial.println(sensor.version);
// Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id);
// Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
// Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
// Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
// Serial.println(F("------------------------------------"));
// // Print humidity sensor details.
// dht.humidity().getSensor(&sensor);
// Serial.println(F("Humidity Sensor"));
// Serial.print (F("Sensor Type: ")); Serial.println(sensor.name);
// Serial.print (F("Driver Ver: ")); Serial.println(sensor.version);
// Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id);
// Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F("%"));
// Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F("%"));
// Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F("%"));
// Serial.println(F("------------------------------------"));
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
// allow much more clock error than the X/1000 default. See:
// [https://github.com/mcci-catena/arduino- ... -462171974](https://github.com/mcci-catena/arduino-lorawan/issues/74#issuecomment-462171974)
// [https://github.com/mcci-catena/arduino- ... 7cf85aL633](https://github.com/mcci-catena/arduino-lmic/commit/42da75b56#diff-16d75524a9920f5d043fe731a27cf85aL633)
// the X/1000 means an error rate of 0.1%; the above issue discusses using
// values up to 10%. so, values from 10 (10% error, the most lax) to 1000
// (0.1% error, the most strict) can be used.
LMIC_setClockError(1 * MAX_CLOCK_ERROR / 40);
// Sub-band 2 - Helium Network
LMIC_selectSubBand(1); // zero indexed
LMIC_setLinkCheckMode(0);
LMIC_setDrTxpow(DR_SF7, 14);
// Start job (sending automatically starts OTAA too)
do_send(&sendjob);
}
void loop() {
os_runloop_once();
}
Any advice or suggestions regarding this would be of great help.
Thanks,
Ragini