Hi together,
I try to built a LoraNode with an Arduino Pro mini 3,3V and a RFM95 Lora-Module. I checked different topic here but couldn’t find one solving my problem. The problem is:
I had one transmission to the TTN, so that I saw the Uplink data in the Live Data of the End Device. But after this no other transmission was made.
When I check the serial monitor/debugger of Arduino IDE an unkown event occurs and seems to abort the transmission but I can’t find out, what creates this event.
Here is the Code:
/*****************************************************************************************
- INCLUDE FILES
*/
#include “lmic.h”
#include <hal/hal.h>
#include <SPI.h>
#include <LowPower.h>
#include <Wire.h>
#include “adcvcc.h”/*****************************************************************************************
- DEFINES
*/
#define debugSerial Serial
#define SHOW_DEBUGINFO
#define debugPrintLn(…) { if (debugSerial) debugSerial.println(VA_ARGS); }
#define debugPrint(…) { if (debugSerial) debugSerial.print(VA_ARGS); }#define FASTINTERVAL 60 // 60 seconds (for testing)
#define NORMALINTERVAL 900 // (5)15 minutes (normal)/************************************************************************************
*Verbindung zum LoraChip RFM95w und TTN-Verbinungsdaten
************************************************************************************/
// Pin mapping CH2I (check out : Full Arduino Mini LoraWAN below 1uA Sleep Mode )
//Definieren der Anschlüsse zum RFM95-LoRaModul:
/*Nss – Arduino Pin 6
*RxTx – Unused
*RST – Arduino Pin 5
*DIO0 – Arduino Pin 2
*DIO1 – Arduino Pin 3
*DIO0 – Arduino Pin 4
*/
const lmic_pinmap lmic_pins = {
.nss = 6,
.rxtx = LMIC_UNUSED_PIN,
.rst = 5,
.dio = {2, 3, 4},
};// UPDATE WITH YOURE TTN KEYS AND ADDR
static const PROGMEM u1_t NWKSKEY[16] = {0xFB, 0xEA, 0xE5, 0x62, 0xD2, 0x20, 0xCA, 0x05, 0xAC, 0x41, 0x48, 0x2E, 0xB7, 0x47, 0xEF, 0xFB}; // LoRaWAN NwkSKey, network session key (msb)
static const u1_t PROGMEM APPSKEY[16] = {0x3D, 0xCA, 0x49, 0xB8, 0xC2, 0xFB, 0x23, 0xFC, 0x53, 0x42, 0x17, 0x4E, 0xA2, 0x38, 0xBF, 0xD8} ; // LoRaWAN AppSKey, application session key (msb)
static const u4_t DEVADDR = 0x260BB22F ; // LoRaWAN end-device address (DevAddr)// These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless
// DISABLE_JOIN is set in config.h, otherwise the linker will complain).
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }/*********************
- weitere Parameter
********************/
static osjob_t sendjob;// global enviromental parameters - Testdaten
static float temp = 10.0;
static float pressure = 0.0;
static float humidity = 25.0;int interval = FASTINTERVAL;
//Übertragungs-Überwachungsparameter
byte LMIC_transmitted = 0;
byte LMIC_event_Timeout = 0;/*******************************************************************************
- Funktions-Defnitionen
*****************************************************************************/
/ ======================================================================
Function: ADC_vect
Purpose : IRQ Handler for ADC
Input : -
Output : -
Comments: used for measuring 8 samples low power mode, ADC is then in
free running mode for 8 samples
====================================================================== */
ISR(ADC_vect)
{
// Increment ADC counter
_adc_irq_cnt++;
}void onEvent (ev_t ev) //Fehlerüberwachung mit Debug-Code für Seriellen Monitor
{
debugPrint(os_getTime());
debugPrint(": ");
debugPrintLn(ev);
switch(ev)
{
case EV_SCAN_TIMEOUT:
debugPrintLn(F(“EV_SCAN_TIMEOUT”));
break;
case EV_BEACON_FOUND:
debugPrintLn(F(“EV_BEACON_FOUND”));
break;
case EV_BEACON_MISSED:
debugPrintLn(F(“EV_BEACON_MISSED”));
break;
case EV_BEACON_TRACKED:
debugPrintLn(F(“EV_BEACON_TRACKED”));
break;
case EV_JOINING:
debugPrintLn(F(“EV_JOINING”));
break;
case EV_JOINED:
debugPrintLn(F(“EV_JOINED”));
break;
case EV_RFU1:
debugPrintLn(F(“EV_RFU1”));
break;
case EV_JOIN_FAILED:
debugPrintLn(F(“EV_JOIN_FAILED”));
break;
case EV_REJOIN_FAILED:
debugPrintLn(F(“EV_REJOIN_FAILED”));
break;
case EV_TXCOMPLETE:
debugPrintLn(F(“EV_TXCOMPLETE”));
if (LMIC.txrxFlags & TXRX_ACK)
debugPrintLn(F(“R ACK”)); // Received ack
if (LMIC.dataLen)
{
debugPrintLn(F(“R “));
debugPrintLn(LMIC.dataLen);
debugPrintLn(F(” bytes”)); // of payload
}
// Schedule next transmission
// os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
LMIC_transmitted = 1;
break;
case EV_LOST_TSYNC:
debugPrintLn(F(“EV_LOST_TSYNC”));
break;
case EV_RESET:
debugPrintLn(F(“EV_RESET”));
break;
case EV_RXCOMPLETE:
// data received in ping slot
debugPrintLn(F(“EV_RXCOMPLETE”));
break;
case EV_LINK_DEAD:
debugPrintLn(F(“EV_LINK_DEAD”));
break;
case EV_LINK_ALIVE:
debugPrintLn(F(“EV_LINK_ALIVE”));
break;
default:
debugPrintLn(F(“Unknown event”));
break;
}
}/*
Sendefunktion: Überprüft, ob gerade eine Übertragung stattfindet.
Wenn nicht werden die Parameter berechnet und im
seriellen Monitor ausgegeben. Anschließend werden die Parameter als Paket
in mydata angelegt und so das zu sendende Paket erstellt (Ausgabe "Packet ready).
Mit LMIC_setTxData2() wird das Paket als Sende Daten an den Chip übergeben und anschließend
“Packet Queued” ausgegeben.
/
void do_send(osjob_t j)
{
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND)
{
debugPrintLn(F(“OP_TXRXPEND”)); //P_TXRXPEND, not sending
}
else
{int batt = (int)(readVcc() / 100); // readVCC returns mVolt need just 100mVolt steps byte batvalue = (byte)batt; // no problem putting it into a int.
#ifdef SHOW_DEBUGINFO
debugPrint(F(“T=”));
debugPrintLn(temp);debugPrint(F("P=")); debugPrintLn(pressure); debugPrint(F("H=")); debugPrintLn(humidity); debugPrint(F("B=")); debugPrintLn(batt); debugPrint(F("BV=")); debugPrintLn(batvalue);
#endif
int t = (int)((temp + 40.0) * 10.0);
// t = t + 40; => t [-40…+85] => [0…125] => t = t * 10; => t [0…125] => [0…1250]
int p = (int)(pressure); // p [300…1100]
int h = (int)(humidity);unsigned char mydata[6]; mydata[0] = batvalue; mydata[1] = h & 0xFF; mydata[2] = t >> 8; mydata[3] = t & 0xFF; mydata[4] = p >> 8; mydata[5] = p & 0xFF; debugPrintLn(F("Packet ready\n")); LMIC_setTxData2(1, mydata, sizeof(mydata), 0); debugPrintLn(F("Packet queued\n")); //Packet queued
}
debugPrintLn(F(“do_send - Letzte Zeile\n”)); //Testmeldung für Abschluss von do_send
// Next TX is scheduled after TX_COMPLETE event.
}/********************************************************************
Setup
*******************************************************************/
void setup() {
Serial.begin(115200); //Baud-Rate, bei seriellem Monitor muss dasselbe eingestellt sein
debugPrintLn(F(“\n—Starting—”));// LMIC init
os_init();// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();// Set static session parameters. Instead of dynamically establishing a session
// by joining the network, precomputed session parameters are be provided.
#ifdef PROGMEM
// On AVR, these values are stored in flash and only copied to RAM
// once. Copy them to a temporary buffer here, LMIC_setSession will
// copy them into a buffer of its own again.
uint8_t size_appskey[sizeof(APPSKEY)];
uint8_t size_nwkskey[sizeof(NWKSKEY)];
memcpy_P(size_appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(size_nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x1, DEVADDR, size_nwkskey, size_appskey);
#else
// If not running an AVR with PROGMEM, just use the arrays directly
LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);
#endif/********************
- Frequenz festlegen
********************/
#if defined(CFG_eu868)
// Set up the channels used by the Things Network, which corresponds
// to the defaults of most gateways. Without this, only three base
// channels from the LoRaWAN specification are used, which certainly
// works, so it is good for debugging, but can overload those
// frequencies, so be sure to configure the full frequency range of
// your network here (unless your network autoconfigures them).
// Setting up channels should happen after LMIC_setSession, as that
// configures the minimal channel set.
// NA-US channels 0-71 are configured automatically
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band// For single channel gateways: Restrict to channel 0 when defined above
#ifdef CHANNEL0
LMIC_disableChannel(1);
LMIC_disableChannel(2);
LMIC_disableChannel(3);
LMIC_disableChannel(4);
LMIC_disableChannel(5);
LMIC_disableChannel(6);
LMIC_disableChannel(7);
LMIC_disableChannel(8);
#endif// TTN defines an additional channel at 869.525Mhz using SF9 for class B
// devices’ ping slots. LMIC does not have an easy way to define set this
// frequency and support for class B is spotty and untested, so this
// frequency is not configured here.
#elif defined(CFG_us915)
// NA-US channels 0-71 are configured automatically
// but only one group of 8 should (a subband) should be active
// TTN recommends the second sub band, 1 in a zero based count.
// gateway-conf/US-global_conf.json at master · TheThingsNetwork/gateway-conf · GitHub
LMIC_selectSubBand(1);
#endif// Disable link check validation
LMIC_setLinkCheckMode(0);// TTN uses SF9 for its RX2 window.
LMIC.dn2Dr = DR_SF9;// Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)
LMIC_setDrTxpow(DR_SF7,14);
debugPrintLn(F(“Setup complete”)); // Setup complete!"
delay(1000); // allow serial to send.
}void loop() {
// put your main code here, to run repeatedly:
// Start job
do_send(&sendjob);
debugPrintLn(F(“do_send() finished\n”));
// Wait for response of the queued message (check if message is send correctly)
os_runloop_once();
debugPrintLn(F(“os_runloop_once() finished\n”));// Continue until message is transmitted correctly
debugPrintLn(“\tWaiting for transmittion\n”);
while(LMIC_transmitted != 1) //Solange keine Übertragung abgeschlossen wurde (EC_TXCOMPLETE im Monitor), wird gewartet. Nach 60s Abbruch
{
os_runloop_once();
// Add timeout counter when nothing happens:
LMIC_event_Timeout++;
delay(1000);
if (LMIC_event_Timeout >= 60)
{
// Timeout when there’s no “EV_TXCOMPLETE” event after 60 seconds
debugPrintLn(F(“\tETimeout, msg not tx\n”));
break;
}
}//Übetragung wurde abgeschlossen, da while() verlassen, Parameter zurücksetzen LMIC_transmitted = 0; LMIC_event_Timeout = 0; //debugPrintLn(F("Going to sleep.")); delay(1000); // allow serial to send. for (int i = 0; i < interval; i++) { i +=7 ; // no normal 1 second run but 8 second loops m. // Enter power down state for 8 s with ADC and BOD module disabled LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); } debugPrintLn("--- LOOP END ---");
}
The Serial Monitor:
10:27:48.896 → —Starting—
10:27:48.896 → Setup complete
10:27:49.922 → T=10.00
10:27:49.922 → P=0.00
10:27:49.922 → H=25.00
10:27:49.922 → B=31
10:27:49.922 → BV=31
10:27:49.922 → Packet ready
10:27:49.922 →
10:27:49.969 → 67046: 17
10:27:49.969 → Unknown event
10:27:49.969 → Pac⸮
10:27:51.472 → —Starting—
Has anybody here an Idea how to solve this?
Thanks for the support!