/*------------------------------------------------------------------ * GPS LORA SENDER * DUPE 9/2020 * Receive GPS and send data via LORA/LORAWAN to file/display * HW: TTGO LORA ESP32, GPS MODUL VKEL > LoRaWAN CRO * TX PIN 16 | RX PIN 17 * CO: https://github.com/matthijskooijman/arduino-lmic * CO: https://github.com/mikalhart/TinyGPSPlus --------------------------------------------------------------------*/ #include #include #include TinyGPSPlus gps; #define PMTK_SET_NMEA_UPDATE_05HZ "$PMTK220,2000*1C" #define PMTK_SET_NMEA_UPDATE_1HZ "$PMTK220,1000*1F" #define PMTK_SET_NMEA_OUTPUT_RMCGGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28" #define RX1 16 #define TX1 17 HardwareSerial gpsSerial_1(1); unsigned long last_update = 0; uint8_t txBuffer[9]; uint32_t latitudeBinary, longitudeBinary; uint16_t altitudeGps; uint8_t hdopGps; #ifdef COMPILE_REGRESSION_TEST # warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!" # define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN) #endif # define FILLMEIN 0 // LORA OTAA parameters // This should also be in little endian format static const u1_t PROGMEM APPEUI[8]={ }; void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} static const u1_t PROGMEM DEVEUI[8]={ }; void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} // This key should be in big endian format static const u1_t PROGMEM APPKEY[16] = { }; void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} static osjob_t sendjob; const unsigned TX_INTERVAL = 300; // Pin mapping TTGO const lmic_pinmap lmic_pins = { .nss = 18, .rxtx = LMIC_UNUSED_PIN, .rst = 14, .dio = {26, 33, 32}, }; unsigned char payload[15]; int counter = 0; int vbatPort = 34; void printHex2(unsigned v) { v &= 0xff; if (v < 16){ Serial.print('0'); Serial.print(v, HEX); } } 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")); { u4_t netid = 0; devaddr_t devaddr = 0; u1_t nwkKey[16]; u1_t artKey[16]; LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); Serial.print("netid: "); Serial.println(netid, DEC); Serial.print("devaddr: "); Serial.println(devaddr, HEX); Serial.print("AppSKey: "); for (size_t i=0; i= 1000) { buildPacket(); Serial.print("Sending packet: "); Serial.println(counter); // prepare upstream data transmission at the next possible time LMIC_setTxData2(1, txBuffer, sizeof(txBuffer)-1, 0); Serial.println("Data odeslana."); last_update = millis delay(3000); } debugSerial.println("None packet TX"); } void buildPacket() { latitudeBinary = ((gps.location.lat() + 90) / 180.0) * 16777215; longitudeBinary = ((gps.location.lng() + 180) / 360.0) * 16777215; txBuffer[0] = ( latitudeBinary >> 16 ) & 0xFF; txBuffer[1] = ( latitudeBinary >> 8 ) & 0xFF; txBuffer[2] = latitudeBinary & 0xFF; txBuffer[3] = ( longitudeBinary >> 16 ) & 0xFF; txBuffer[4] = ( longitudeBinary >> 8 ) & 0xFF; txBuffer[5] = longitudeBinary & 0xFF; altitudeGps = gps.altitude.meters(); txBuffer[6] = ( altitudeGps >> 8 ) & 0xFF; txBuffer[7] = altitudeGps & 0xFF; hdopGps = gps.hdop.value()/10; txBuffer[8] = hdopGps & 0xFF; } void displayGpsInfo() { debugSerial.print(F("Location: ")); if (gps.location.isValid()) { debugSerial.print(gps.location.lat(), 6); debugSerial.print(F(",")); debugSerial.print(gps.location.lng(), 6); } else { debugSerial.print(F("GPS LOCATION INVALID")); } debugSerial.print(F(" Date/Time: ")); if (gps.date.isValid()) { debugSerial.print(gps.date.month()); debugSerial.print(F("/")); debugSerial.print(gps.date.day()); debugSerial.print(F("/")); debugSerial.print(gps.date.year()); } else { debugSerial.print(F("GPS TIME INVALID")); } debugSerial.print(F(" ")); if (gps.time.isValid()) { if (gps.time.hour() < 10) debugSerial.print(F("0")); debugSerial.print(gps.time.hour()); debugSerial.print(F(":")); if (gps.time.minute() < 10) debugSerial.print(F("0")); debugSerial.print(gps.time.minute()); debugSerial.print(F(":")); if (gps.time.second() < 10) debugSerial.print(F("0")); debugSerial.print(gps.time.second()); debugSerial.print(F(".")); if (gps.time.centisecond() < 10) debugSerial.print(F("0")); debugSerial.print(gps.time.centisecond()); } else { debugSerial.print(F("GPS INVALID")); } debugSerial.println(); } void setup() { delay(5000); gpsSerial_1.begin(9600, SERIAL_8N1, RX1, TX1); gpsSerial.println(F(PMTK_SET_NMEA_UPDATE_1HZ)); // 1 Hz update rate while (! Serial); Serial.begin(9600); Serial.println(F("Starting")); // LMIC init os_init(); // Reset the MAC state. Session and pending data transfers will be discarded. LMIC_reset(); // Start job (sending automatically starts OTAA too) do_send(&sendjob); } void loop() { os_runloop_once(); }