Skip to content
Snippets Groups Projects
Select Git revision
  • dfb0c783429815c3955d79085192c12bd0580e66
  • master default protected
2 results

main.cpp

Blame
  • main.cpp 8.36 KiB
    #include <config.h>
    #include <axp20x.h>
    #include <Arduino_LoRaWAN_ttn.h>
    #include <lmic.h>
    #include <hal/hal.h>
    #include <SPI.h>
    #include <TinyGPS++.h>
    #include <CayenneLPP.h>
    #include <OneButton.h>
    
    class cLoRaWAN : public Arduino_LoRaWAN_ttn
    {
    public:
        cLoRaWAN(){};
    
    protected:
        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)
    {
    }
    
    void cLoRaWAN::NetSaveFCntUp(uint32_t uFCntUp)
    {
    }
    
    void cLoRaWAN::NetSaveSessionInfo(
        const SessionInfo &Info,
        const uint8_t *pExtraInfo,
        size_t nExtraInfo)
    {
    }
    
    const cLoRaWAN::lmic_pinmap pinMap = {
        .nss = 18,
        .rxtx = cLoRaWAN::lmic_pinmap::LMIC_UNUSED_PIN,
        .rst = 23,
        .dio = {26, 33, cLoRaWAN::lmic_pinmap::LMIC_UNUSED_PIN},
    };
    
    AXP20X_Class axp;
    HardwareSerial GPS(1);
    TinyGPSPlus gps;
    cLoRaWAN LoRaWAN{};
    CayenneLPP lpp(55);
    DynamicJsonDocument jsonBuffer(1024);
    OneButton btn = OneButton(BUTTON_PIN, true, true);
    unsigned long statusTimer;
    
    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"));
            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"));
            }
            break;
        case EV_LOST_TSYNC:
            Serial.println(F("EV_LOST_TSYNC"));
            break;
        case EV_RESET:
            Serial.println(F("EV_RESET"));
            break;
        case EV_RXCOMPLETE:
            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 setupPower()
    {
        if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS))
        {
            Serial.println("AXP192 Begin PASS");
        }
        else
        {
            Serial.println("AXP192 Begin FAIL");
        }
        axp.setPowerOutPut(AXP192_DCDC1, AXP202_OFF); // OLED  : off
        axp.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); // N/C   : off
        axp.setPowerOutPut(AXP192_DCDC3, AXP202_ON);  // ESP32 : on
        axp.setPowerOutPut(AXP192_LDO2, AXP202_ON);   // LORA  : on
        axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);   // GPS   : on
        axp.setDCDC3Voltage(3300);                    // ESP32 : 3.3V
        axp.setLDO2Voltage(3300);                     // LORA  : 3.3V
        axp.setLDO3Voltage(3300);                     // GPS   : 3.3V
        axp.setChgLEDMode(AXP20X_LED_OFF);
    }
    
    void setupGps()
    {
        GPS.begin(9600, SERIAL_8N1, 34, 12); // IO34: RX, IO12: TX
    }
    
    void printStatus()
    {
        axp.setChgLEDMode(AXP20X_LED_LOW_LEVEL);
        while (GPS.available())
        {
            gps.encode(GPS.read());
        }
        Serial.println("##############################");
        Serial.println("--- Power ---");
        Serial.printf("DCDC1/OLED Status   : %s\n", axp.isDCDC1Enable() ? "enabled" : "disabled");
        Serial.printf("DCDC1/OLED Voltage  : %g V\n", (float)axp.getDCDC1Voltage() / 1000);
        Serial.printf("DCDC2/N/C Status    : %s\n", axp.isDCDC2Enable() ? "enabled" : "disabled");
        Serial.printf("DCDC2/N/C Voltage   : %g V\n", (float)axp.getDCDC2Voltage() / 1000);
        Serial.printf("DCDC3/ESP32 Status  : %s\n", axp.isDCDC3Enable() ? "enabled" : "disabled");
        Serial.printf("DCDC3/ESP32 Voltage : %g V\n", (float)axp.getDCDC3Voltage() / 1000);
        Serial.printf("LDO2/LoRa Status    : %s\n", axp.isLDO2Enable() ? "enabled" : "disabled");
        Serial.printf("LDO2/LoRa Voltage   : %g V\n", (float)axp.getLDO2Voltage() / 1000);
        Serial.printf("LDO3/GPS Status     : %s\n", axp.isLDO3Enable() ? "enabled" : "disabled");
        Serial.printf("LDO3/GPS Voltage    : %g V\n", (float)axp.getLDO3Voltage() / 1000);
        Serial.println("--- Battery ---");
        Serial.printf("Battery Connected: %s\n", axp.isBatteryConnect() ? "true" : "false");
        if (axp.isBatteryConnect())
        {
            Serial.printf("Battery Percentage : %d %%\n", axp.getBattPercentage());
            Serial.printf("Battery Voltage    : %g V\n", axp.getBattVoltage() / 1000);
            Serial.printf("Battery Current    : %g mA\n", axp.getBattDischargeCurrent());
            Serial.println("--- Charging ---");
            Serial.printf("Charging Enabled   : %s\n", axp.isChargeingEnable() ? "true" : "false");
            Serial.printf("Battery Charging   : %s\n", axp.isChargeing() ? "true" : "false");
            Serial.printf("Set Charge Current : %g mA\n", axp.getSettingChargeCurrent());
        }
        Serial.println("--- Chip ---");
        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  : ");
        Serial.println(gps.location.lng(), 4);
        Serial.print("Satellites : ");
        Serial.println(gps.satellites.value());
        Serial.print("Altitude   : ");
        Serial.print(gps.altitude.meters());
        Serial.println("M");
        Serial.print("Time       : ");
        Serial.print(gps.time.hour());
        Serial.print(":");
        Serial.print(gps.time.minute());
        Serial.print(":");
        Serial.println(gps.time.second());
        Serial.print("Speed      : ");
        Serial.println(gps.speed.kmph());
        Serial.println("##############################");
        axp.setChgLEDMode(AXP20X_LED_OFF);
    }
    
    void do_send()
    {
        // Check if there is not a current TX/RX job running
        if (LMIC.opmode & OP_TXRXPEND)
        {
            Serial.println(F("OP_TXRXPEND, not sending"));
        }
        else
        {
            while (GPS.available())
            {
                gps.encode(GPS.read());
            }
            lpp.reset();
            lpp.addGPS(1, gps.location.lat(), gps.location.lng(), gps.altitude.meters());
            lpp.addAnalogInput(2, axp.getBattVoltage()/1000);
            LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0);
            Serial.println(F("Packet queued"));
            Serial.println();
            JsonObject json = jsonBuffer.to<JsonObject>();
            lpp.decodeTTN(lpp.getBuffer(), lpp.getSize(), json);
            serializeJsonPretty(json, Serial);
            Serial.println();
        }
    }
    
    static void handleClick()
    {
        printStatus();
        do_send();
    }
    
    void setup()
    {
        Serial.begin(115200);
        Wire.begin(21, 22);
        setupPower();
        setupGps();
        LoRaWAN.begin(pinMap);
        btn.attachClick(handleClick);
        printStatus();
        statusTimer = millis();
    }
    
    void loop()
    {
        LoRaWAN.loop();
        btn.tick();
        if (millis() - statusTimer >= 1000 * 30) {
            printStatus();
            do_send();
            statusTimer = millis();
       }
    }