TTN-Mapper-GPS/ttn-gps-mapper-abp.ino

255 lines
8.6 KiB
C++

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <lmic.h>
#include <hal/hal.h>
uint8_t coords[9];
static const int RXPin = 0, TXPin = 1; // TXPin not used / dummy
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
uint32_t timer = millis();
// LoraWAN Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
// https://github.com/matthijskooijman/arduino-lmic
// -------- LoRa PinMapping FeatherWing Octopus
const lmic_pinmap lmic_pins = {
.nss = 2, // Connected to pin D
.rxtx = LMIC_UNUSED_PIN, // For placeholder only, Do not connected on RFM92/RFM95
.rst = LMIC_UNUSED_PIN, // Needed on RFM92/RFM95? (probably not) D0/GPIO16
.dio = {
15, 15, LMIC_UNUSED_PIN }
};
// mapper3 ABP
void os_getArtEui (u1_t* buf) {
}
void os_getDevEui (u1_t* buf) {
}
void os_getDevKey (u1_t* buf) {
}
//mapper-bb-006 please insert the keys in MSB Format
// DEVADDR example: 260A1B2C
static const u4_t DEVADDR = 0x260XXXXX;
static const u1_t PROGMEM APPSKEY[16]={ XXX };
static const u1_t PROGMEM NWKSKEY[16]={ XXX };
volatile int LoRaWAN_Tx_Ready = 0; // Merker für ACK
int LoRaWAN_Rx_Payload = 0 ;
// -------- LoRa Event
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"));
LoRaWAN_Rx_Payload = 0;
for (int i = 0;i<LMIC.dataLen;i++) {
Serial.println(LMIC.frame[i+ LMIC.dataBeg],HEX);
LoRaWAN_Rx_Payload = 256*LoRaWAN_Rx_Payload+LMIC.frame[i+ LMIC.dataBeg];
}
}
LoRaWAN_Tx_Ready = 1;
// 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 setup(){ // Einmalige Initialisierung
Serial.begin(115200);
ss.begin(GPSBaud);
// -- Initialisiere LoraWAN
os_init(); // LMIC LoraWAN
LMIC_reset(); // Reset the MAC state
LMIC.txpow = 27; // Maximum TX power
LMIC.datarate=DR_SF12; // Long Range
LMIC.rps = updr2rps(LMIC.datarate);
// Set static session parameters. Instead of dynamically establishing a session
// by joining the network, precomputed session parameters are be provided.
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
// 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
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
LMIC_setLinkCheckMode(0); // Disable link check validation
LMIC.dn2Dr = DR_SF9; // TTN uses SF9 for its RX2 window.
LMIC_setDrTxpow(DR_SF7,14); // Set data rate and transmit power for uplink
}
void loop() { // Kontinuierliche Wiederholung
while (ss.available() > 0)
if (gps.encode(ss.read()))
{
/*
// if millis() or timer wraps around, we'll just reset it
if (timer > millis()) timer = millis();
// approximately every 10 seconds or so, print out the current stats
if (millis() - timer > 30000) {
timer = millis(); // reset the timer
*/
if (gps.location.isValid()) {
Serial.print(gps.altitude.meters(), 6);
Serial.print(F(","));
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
Serial.print(F(","));
Serial.println(gps.location.isValid(), 6);
//Block------------------------------ sende Daten an TTN
//int port = 10;
//static uint8_t mydata[2];
//int wert=round(boschBME280.readTempC()*10);
//wert=round(boschBME680.readGas()/1000.*10);
//mydata[0] = wert >> 8;
//mydata[1] = wert & 0xFF;
// Check if there is not a current TX/RX job running
//if (LMIC.opmode & OP_TXRXPEND) {
if (LMIC.opmode & (1 << 7)) {
Serial.println(F("OP_TXRXPEND, not sending"));
}
else {
// Prepare upstream data transmission at the next possible time.
LoRaWAN_Tx_Ready = 0; // Merker für ACK
//LMIC_setTxData2(port, mydata, sizeof(mydata), 0); // Sende
int32_t lati = gps.location.lat() * 10000;
int32_t lon = gps.location.lng() * 10000;
int32_t altitudeGPS = gps.altitude.meters(); // int16_t
int8_t hdopGPS = gps.hdop.value();
Serial.println(lati);
Serial.println(lon);
Serial.println(altitudeGPS);
Serial.println(hdopGPS);
// Pad 2 int32_t to 6 8uint_t, big endian (24 bit each, having 11 meter precision)
coords[0] = lati;
coords[1] = lati >> 8;
coords[2] = lati >> 16;
coords[3] = lon;
coords[4] = lon >> 8;
coords[5] = lon >> 16;
coords[6] = altitudeGPS;
coords[7] = altitudeGPS >> 8;
coords[8] = hdopGPS;
LMIC_setTxData2(1, (uint8_t*) coords, sizeof(coords), 0);
Serial.println(F("Packet queued"));
while(LoRaWAN_Tx_Ready==0) {
yield();
os_runloop_once();
}; // Warte bis gesendet
//}
// Blockende
Serial.print(F("Waiting "));
for (int i = 0;i<10;i++) {
Serial.print(F("."));
delay(1000); // please set a proper duty cycle
}
Serial.println(" done.");
}
} else {
Serial.println("no GPS fix");
}
}
}