From 9a5f708ae8bba18f86863e52546da5aa24e8d104 Mon Sep 17 00:00:00 2001 From: Jan Grewe <jan@faked.org> Date: Sat, 25 Jul 2020 15:20:01 +0200 Subject: [PATCH] power status output LoRaWAN added --- .gitignore | 1 + src/main.cpp | 248 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 226 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index a20dc5c..55f017b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .travis.yml platformio.ini BikeBeam.code-workspace +src/config.h diff --git a/src/main.cpp b/src/main.cpp index 99f8578..9e5569f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,14 +1,83 @@ -#include <TinyGPS++.h> +#include <config.h> #include <axp20x.h> +#include <Arduino_LoRaWAN_ttn.h> +#include <lmic.h> +#include <hal/hal.h> +#include <SPI.h> +#include <TinyGPS++.h> + +class cLoRaWAN : public Arduino_LoRaWAN_ttn +{ +public: + cLoRaWAN(){}; + +protected: + // you'll need to provide implementations for each of the following. + virtual bool GetOtaaProvisioningInfo(Arduino_LoRaWAN::OtaaProvisioningInfo *) override; + virtual void NetSaveFCntUp(uint32_t uFCntUp) override; + virtual void NetSaveFCntDown(uint32_t uFCntDown) override; + virtual void NetSaveSessionInfo(const SessionInfo &Info, const uint8_t *pExtraInfo, size_t nExtraInfo) override; +}; + +bool cLoRaWAN::GetOtaaProvisioningInfo( + OtaaProvisioningInfo *pInfo) +{ + static const uint8_t DEVEUI[8] = TTN_DEVEUI; + static const uint8_t APPEUI[8] = TTN_APPEUI; + static const uint8_t APPKEY[16] = TTN_APPKEY; + + if (pInfo) + { + memcpy(pInfo->AppKey, APPKEY, sizeof(APPKEY)); + memcpy(pInfo->DevEUI, DEVEUI, sizeof(DEVEUI)); + memcpy(pInfo->AppEUI, APPEUI, sizeof(APPEUI)); + } + return true; +} + +void cLoRaWAN::NetSaveFCntDown(uint32_t uFCntDown) +{ + // save uFcntDown somwwhere +} + +void cLoRaWAN::NetSaveFCntUp(uint32_t uFCntUp) +{ + // save uFCntUp somewhere +} + +void cLoRaWAN::NetSaveSessionInfo( + const SessionInfo &Info, + const uint8_t *pExtraInfo, + size_t nExtraInfo) +{ + // save Info somewhere. +} + +const cLoRaWAN::lmic_pinmap pinMap = { + .nss = 18, + .rxtx = cLoRaWAN::lmic_pinmap::LMIC_UNUSED_PIN, + .rst = 23, + .dio = { 26, 33, 32 }, +}; + -TinyGPSPlus gps; -HardwareSerial GPS(1); AXP20X_Class axp; +HardwareSerial GPS(1); +TinyGPSPlus gps; +cLoRaWAN LoRaWAN{}; -void setupPower() { - if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) { +static uint8_t mydata[] = "Hello, world!"; +static osjob_t sendjob; +const unsigned TX_INTERVAL = 60; + +void setupPower() +{ + if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) + { Serial.println("AXP192 Begin PASS"); - } else { + } + else + { Serial.println("AXP192 Begin FAIL"); } axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); @@ -19,22 +88,29 @@ void setupPower() { axp.setChgLEDMode(AXP20X_LED_OFF); } -void setupGps() { - GPS.begin(9600, SERIAL_8N1, 34, 12); //17-TX 18-RX -} - -static void smartDelay(unsigned long ms) +void setupGps() { - unsigned long start = millis(); - do - { - while (GPS.available()) - gps.encode(GPS.read()); - } while (millis() - start < ms); + GPS.begin(9600, SERIAL_8N1, 34, 12); //17-TX 18-RX } -void printGpsStatus() { +void printStatus() +{ axp.setChgLEDMode(AXP20X_LED_LOW_LEVEL); + while (GPS.available()) + gps.encode(GPS.read()); + Serial.println("**********************"); + Serial.println("--- Power ---"); + Serial.printf("Battery Connected: %s\n", axp.isBatteryConnect() ? "true" : "false"); + if (axp.isBatteryConnect()) + { + Serial.printf("Battery Charging Enabled: %s\n", axp.isChargeingEnable() ? "true" : "false"); + Serial.printf("Battery Charging: %s\n", axp.isChargeing() ? "true" : "false"); + Serial.printf("Battery Voltage: %.2f V\n", axp.getBattVoltage() / 1000); + Serial.printf("Battery Percentage: %d %%\n", axp.getBattPercentage()); + Serial.printf("Battery Charge Current: %g mA\n", axp.getSettingChargeCurrent()); + } + Serial.printf("Chip Temp: %.1f C°\n", axp.getTemp() / 10); + Serial.println("--- GPS ---"); Serial.print("Latitude : "); Serial.println(gps.location.lat(), 5); Serial.print("Longitude : "); @@ -51,12 +127,133 @@ void printGpsStatus() { Serial.print(":"); Serial.println(gps.time.second()); Serial.print("Speed : "); - Serial.println(gps.speed.kmph()); + Serial.println(gps.speed.kmph()); Serial.println("**********************"); axp.setChgLEDMode(AXP20X_LED_OFF); - smartDelay(1000); - if (millis() > 5000 && gps.charsProcessed() < 10) - Serial.println(F("No GPS data received: check wiring")); +} + +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, mydata, sizeof(mydata) - 1, 0); + Serial.println(F("Packet queued")); + } + // Next TX is scheduled after TX_COMPLETE 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")); + // TTN uses SF9 for its RX2 window. + LMIC.dn2Dr = EU868_DR_SF9; + 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("artKey: "); + for (int i = 0; i < sizeof(artKey); ++i) + { + Serial.print(artKey[i], HEX); + } + Serial.println(""); + Serial.print("nwkKey: "); + for (int i = 0; i < sizeof(nwkKey); ++i) + { + Serial.print(nwkKey[i], HEX); + } + Serial.println(""); + + LMIC_setSeqnoUp(140); + } + 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; + case EV_SCAN_FOUND: + Serial.println(F("EV_SCAN_FOUND")); + break; + case EV_TXSTART: + Serial.println(F("EV_TXSTART")); + break; + case EV_TXCANCELED: + Serial.println(F("EV_TXCANCELLED")); + break; + case EV_JOIN_TXCOMPLETE: + Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept")); + break; + default: + Serial.println(F("Unknown event " + (unsigned)ev)); + break; + } } void setup() @@ -65,9 +262,14 @@ void setup() Wire.begin(21, 22); setupPower(); setupGps(); + LoRaWAN.begin(pinMap); + printStatus(); + do_send(&sendjob); } void loop() { - printGpsStatus(); + LoRaWAN.loop(); + //printStatus(); + //delay(1000); } -- GitLab