Hello mates,
i am trying to integrate the OTAA-TTN Example into our code for our node (Arduino UNO + Dragino LoRaShield+GPS). When i’m using the example with only changing the DEVUI & APPKEY, it sends a join-request to the gateway.
When i integrate parts of the example in my code, it do what it should do, but it don’t send a request or anything else.
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <EEPROM.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
int EEPROMcount1 = 5;
int EEPROMcount5 = 20;
int measureAry[50];
int measureAryF[15];
float oldLat;
float oldLon;
TinyGPS gps;
SoftwareSerial ss(3, 4); // Arduino TX, RX for GPS
static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_date(TinyGPS &gps);
// No longer required for LoRaServer but still needed in LMIC.
// Keep it all zero.
// This should be in little endian format.
static const u1_t PROGMEM APPEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
void os_getArtEui(u1_t* buf) { memcpy_P(buf, APPEUI, 8); }
// First registrate your device on the Homepage and copy the DEVEUI to the { }.
// Don't forget the commas!
// The entered values is default and only for example.
static const u1_t PROGMEM DEVEUI[8] = { 0x11, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x88 };
void os_getDevEui(u1_t* buf) { memcpy_P(buf, DEVEUI, 8); }
// This key should be in big endian format .
// Registrate your device on the Homepage and copy the DEVKEY to the { }.
// Don't forget the comamas!
// The key shown here is the semtech default key.
static const u1_t PROGMEM APPKEY[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C };
void os_getDevKey(u1_t* buf) { memcpy_P(buf, APPKEY, 16); }
static uint8_t sendData[12];
static osjob_t sendjob;
const lmic_pinmap lmic_pins = {
.nss = 10,
.rxtx = LMIC_UNUSED_PIN,
.rst = 9,
.dio = { 2, 6, 7 },
};
// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 60;
// watchdog interrupt *****************************************************
ISR(WDT_vect)
{
wdt_disable(); // disable watchdog
}
//BEGIN OF METHODES *****************************************************
void setup()
{
Serial.begin(9600);
ss.begin(9600);
Serial.println("Start CoLoMe ****************************************");
Serial.println("LoRa Frequency Min: " + String(EU868_FREQ_MIN) + ", LoRa Frequency Max: " + String(EU868_FREQ_MAX));
Serial.println("*****************************************************");
clearEEPROM();
os_init();
// reset MAC state
LMIC_reset();
// start joining
//LMIC_startJoining();
//LMIC_reset();
//smartdelay(10000);
}
void loop()
{
//Execute run-time jobs from the timer and from the run queues.
os_runloop_once();
//
// //loop the functions below with the rigth timing
// float flat, flon;
// unsigned long age, date, time, chars = 0;
//
//
// for (int i = 1; i <= 60; i++)
// {
// if (i % 60 == 0)
// {
// Serial.println("60 min");
// Serial.println();
// ss.end();
// myWatchdogEnable(0b000111); // 2 seconds
// ss.begin(9600);
//
// }
// else if (i % 15 == 0)
// {
// quarteHourFnc();
// smartdelay(100);
// ss.end();
// myWatchdogEnable(0b000111); // 2 seconds
// ss.begin(9600);
// }
// else if (i % 5 == 0)
// {
// fiveMinuteFnc();
// Serial.println(String(EEPROM.read(EEPROMcount5)) + " 5 minute min");
// Serial.println(String(EEPROM.read(EEPROMcount5 + 1)) + " 5 minute max");
// Serial.println(String(EEPROM.read(EEPROMcount5 + 2)) + " 5 minute avg");
// Serial.println();
// smartdelay(100);
// ss.end();
// myWatchdogEnable(0b000111); // 2 seconds
// EEPROMcount5 += 3;
// if (EEPROMcount5 == 29) {
// EEPROMcount5 = 20;
// ss.begin(9600);
// }
// }
// else
// {
// everyMinuteFnc();
// Serial.println("");
// Serial.println(String(EEPROM.read(EEPROMcount1)) + " 1 minute min");
// Serial.println(String(EEPROM.read(EEPROMcount1 + 1)) + " 1 minute max");
// Serial.println(String(EEPROM.read(EEPROMcount1 + 2)) + " 1 minute avg");
// Serial.println();
// smartdelay(100);
// ss.end();
//
// EEPROMcount1 += 3;
// if (EEPROMcount1 == 20) {
// EEPROMcount1 = 5;
// ss.begin(9600);
// }
// }
//
// //myWatchdogEnable(0b100001); // 8 seconds
// myWatchdogEnable(0b000111); // 2 seconds
// }
}
//GET MIN/MAX/AVG *************************************************
int getMin(int* array, int size) {
int min = array[0];
for (int i = 0; i<size; i++) {
if (array[i] < min) {
min = array[i];
}
}
return min / 4;
}
int getMax(int* array, int size) {
int max = array[0];
for (int i = 0; i<size; i++) {
if (array[i] > max) {
max = array[i];
}
}
return max / 4;
}
int getAvg(int* array, int size) {
int avg;
for (int i = 0; i<size; i++) {
avg += array[i];
}
return (avg / 4) / size;
}
//CLEAR EEPROM *****************************************************
void clearEEPROM()
{
for (int i = 0; i < EEPROM.length(); i++) {
if (EEPROM.read(i) != 0) //skip already "empty" addresses
{
EEPROM.write(i, 0); //write 0 to address i
}
}
Serial.println("EEPROM erased");
}
//GPS Function *****************************************************
void getGPS()
{
TinyGPS gps;
SoftwareSerial ss(3, 4); // Arduino TX, RX ,
float flat, flon;
unsigned long age, date, time, chars = 0;
gps.f_get_position(&flat, &flon, &age); //retrieves latitude and longitude
print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 3);
print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 3);
print_date(gps);
Serial.println();
smartdelay(1000);
}
//WATCHDOGENABLE *****************************************************
void myWatchdogEnable(const byte interval)
{
MCUSR = 0; // reset various flags
WDTCSR |= 0b00011000; // set WDCE (enables configuration mode for 4 clock cycles), WDE(enables system reset on time-out)
WDTCSR = 0b01000000 | interval; // set WDIE (enales interrupts for last action before reset), and appropriate delay
wdt_reset(); // resets watchdogtimer
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode(); // now goes to Sleep and waits for the interrupt
}
//SMARTDELAY *****************************************************
void smartdelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
{
gps.encode(ss.read());
}
} while (millis() - start < ms);
}
//PRINTFLOAT********************************************************
static void print_float(float val, float invalid, int len, int prec)
{
if (val == invalid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i = flen; i<len; ++i)
Serial.print(' ');
}
}
//LoRaWAN *****************************************************
void onEvent (ev_t ev) {
Serial.print(os_getTime());
Serial.print(": ");
switch(ev) {
case EV_SCAN_TIMEOUT:
Serial.println(F("EV_SCAN_TIMEOUT"));
break;
case EV_BEACON_FOUND:
Serial.println(F("EV_BEACON_FOUND"));
break;
case EV_BEACON_MISSED:
Serial.println(F("EV_BEACON_MISSED"));
break;
case EV_BEACON_TRACKED:
Serial.println(F("EV_BEACON_TRACKED"));
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 {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, sendData, sizeof(sendData)-1, 0);
Serial.println(F("Packet queued"));
}
// Next TX is scheduled after TX_COMPLETE event.
}
//EVERY MINUTE ***************************************************
void everyMinuteFnc()
{
// To-Do: measure for 10 seconds, save min., max. & avg. value to EEPROM (4 times)
for (int i = 0; i < 50; i++)
{
measureAry[i] = analogRead(0);
smartdelay(25);
}
for (int j = 0; j < 50; j++)
{
Serial.print(String(measureAry[j]) + " ");
}
Serial.println("50 values measured");
EEPROM.write(EEPROMcount1, getMin(measureAry, 50));
EEPROM.write(EEPROMcount1 + 1, getMax(measureAry, 50));
EEPROM.write(EEPROMcount1 + 2, getAvg(measureAry, 50));
EEPROM.write(30, EEPROMcount1);
Serial.println("3 values writen to EEPROM");
}
//FIVe MINUTE*************************************************************
void fiveMinuteFnc()
{
//To-Do: call everyMinuteFnc, read EEPROM, save min., max. & avg. value of the last 5 measures to EEPROM, drop unused values (2 times)
everyMinuteFnc();
for (int j = 0; j <= 15; j++) {
measureAryF[j] = EEPROM.read(j + 5);
}
EEPROM.write(EEPROMcount5, getMin(measureAryF, 15));
EEPROM.write(EEPROMcount5 + 1, getMax(measureAryF, 15));
EEPROM.write(EEPROMcount5 + 2, getAvg(measureAryF, 15));
}
//QUARTER FUNCTION
void quarteHourFnc()
{
float flat, flon;
unsigned long age, date, time, chars = 0;
//To-Do: call fiveMinuteFnc, build sendpackage (SeSt-ID, timereference, position, 9 measured values,
// send package via LoRa for 0.3125 seconds, clear EEPROM from measured values (3 times)
fiveMinuteFnc();
int savedValues[9];
for (int i = 0; i <= sizeof(savedValues) / sizeof(int); i++)
{
savedValues[i] = EEPROM.read(20 + i);
}
for (int j = 0; j < sizeof(savedValues) / sizeof(int); j++)
{
sendData[j] = savedValues[j];
}
gps.f_get_position(&flat, &flon, &age); //retrieves latitude and longitude
int gpsOffsetLat = (flat - oldLat) * 100;
int gpsOffsetLon = (flon - oldLon) * 100;
oldLat = flat;
oldLon = flon;
print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 3);
print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 3);
Serial.println();
Serial.println(gpsOffsetLat);
Serial.println(gpsOffsetLon);
Serial.println();
smartdelay(100);
// Start job (sending automatically starts OTAA too)
do_send(&sendjob);
Serial.println();
}
void everyHourFnc()
{
//To-Do: call quarterHourFnc, get GPS contact to get new time & check position, if new pos clear EEPROM and write new pos
}
What do i have to change?
Greetings Lotzo