Update LoRaWAN examples
This commit is contained in:
parent
9db7b606a7
commit
95553f48e7
6 changed files with 1442 additions and 74 deletions
850
examples/LoRaWAN/LoRaWAN_ABP/LoRaBoards.cpp
Normal file
850
examples/LoRaWAN/LoRaWAN_ABP/LoRaBoards.cpp
Normal file
|
|
@ -0,0 +1,850 @@
|
|||
/**
|
||||
* @file boards.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd
|
||||
* @date 2024-04-24
|
||||
* @last-update 2024-08-07
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LoRaBoards.h"
|
||||
|
||||
#if defined(HAS_SDCARD)
|
||||
SPIClass SDCardSPI(HSPI);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
HardwareSerial SerialGPS(GPS_RX_PIN, GPS_TX_PIN);
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
#include "hal/gpio_hal.h"
|
||||
#endif
|
||||
#include "driver/gpio.h"
|
||||
#endif //ARDUINO_ARCH_ESP32
|
||||
|
||||
|
||||
DISPLAY_MODEL *u8g2 = NULL;
|
||||
static DevInfo_t devInfo;
|
||||
|
||||
#ifdef HAS_GPS
|
||||
static bool find_gps = false;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef HAS_PMU
|
||||
XPowersLibInterface *PMU = NULL;
|
||||
bool pmuInterrupt;
|
||||
|
||||
static void setPmuFlag()
|
||||
{
|
||||
pmuInterrupt = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool beginPower()
|
||||
{
|
||||
#ifdef HAS_PMU
|
||||
if (!PMU) {
|
||||
PMU = new XPowersAXP2101(PMU_WIRE_PORT);
|
||||
if (!PMU->init()) {
|
||||
Serial.println("Warning: Failed to find AXP2101 power management");
|
||||
delete PMU;
|
||||
PMU = NULL;
|
||||
} else {
|
||||
Serial.println("AXP2101 PMU init succeeded, using AXP2101 PMU");
|
||||
}
|
||||
}
|
||||
|
||||
if (!PMU) {
|
||||
PMU = new XPowersAXP192(PMU_WIRE_PORT);
|
||||
if (!PMU->init()) {
|
||||
Serial.println("Warning: Failed to find AXP192 power management");
|
||||
delete PMU;
|
||||
PMU = NULL;
|
||||
} else {
|
||||
Serial.println("AXP192 PMU init succeeded, using AXP192 PMU");
|
||||
}
|
||||
}
|
||||
|
||||
if (!PMU) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PMU->setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
|
||||
|
||||
pinMode(PMU_IRQ, INPUT_PULLUP);
|
||||
attachInterrupt(PMU_IRQ, setPmuFlag, FALLING);
|
||||
|
||||
if (PMU->getChipModel() == XPOWERS_AXP192) {
|
||||
|
||||
PMU->setProtectedChannel(XPOWERS_DCDC3);
|
||||
|
||||
// lora
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
|
||||
// gps
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
|
||||
// oled
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
|
||||
|
||||
PMU->enablePowerOutput(XPOWERS_LDO2);
|
||||
PMU->enablePowerOutput(XPOWERS_LDO3);
|
||||
|
||||
//protected oled power source
|
||||
PMU->setProtectedChannel(XPOWERS_DCDC1);
|
||||
//protected esp32 power source
|
||||
PMU->setProtectedChannel(XPOWERS_DCDC3);
|
||||
// enable oled power
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC1);
|
||||
|
||||
//disable not use channel
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC2);
|
||||
|
||||
PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ);
|
||||
|
||||
PMU->enableIRQ(XPOWERS_AXP192_VBUS_REMOVE_IRQ |
|
||||
XPOWERS_AXP192_VBUS_INSERT_IRQ |
|
||||
XPOWERS_AXP192_BAT_CHG_DONE_IRQ |
|
||||
XPOWERS_AXP192_BAT_CHG_START_IRQ |
|
||||
XPOWERS_AXP192_BAT_REMOVE_IRQ |
|
||||
XPOWERS_AXP192_BAT_INSERT_IRQ |
|
||||
XPOWERS_AXP192_PKEY_SHORT_IRQ
|
||||
);
|
||||
|
||||
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
//Unuse power channel
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC2);
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC3);
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC4);
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC5);
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO1);
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO4);
|
||||
PMU->disablePowerOutput(XPOWERS_BLDO1);
|
||||
PMU->disablePowerOutput(XPOWERS_BLDO2);
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO1);
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO2);
|
||||
|
||||
// GNSS RTC PowerVDD 3300mV
|
||||
PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_VBACKUP);
|
||||
|
||||
//ESP32 VDD 3300mV
|
||||
// ! No need to set, automatically open , Don't close it
|
||||
// PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
|
||||
// PMU->setProtectedChannel(XPOWERS_DCDC1);
|
||||
PMU->setProtectedChannel(XPOWERS_DCDC1);
|
||||
|
||||
// LoRa VDD 3300mV
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||
|
||||
//GNSS VDD 3300mV
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO3);
|
||||
|
||||
#endif /*CONFIG_IDF_TARGET_ESP32*/
|
||||
|
||||
|
||||
#if defined(T_BEAM_S3_SUPREME)
|
||||
|
||||
//t-beam m.2 inface
|
||||
//gps
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO4);
|
||||
|
||||
// lora
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO3);
|
||||
|
||||
// In order to avoid bus occupation, during initialization, the SD card and QMC sensor are powered off and restarted
|
||||
if (ESP_SLEEP_WAKEUP_UNDEFINED == esp_sleep_get_wakeup_cause()) {
|
||||
Serial.println("Power off and restart ALDO BLDO..");
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO1);
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO2);
|
||||
PMU->disablePowerOutput(XPOWERS_BLDO1);
|
||||
delay(250);
|
||||
}
|
||||
|
||||
// Sensor
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO1);
|
||||
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||
|
||||
//Sdcard
|
||||
|
||||
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_BLDO1);
|
||||
|
||||
PMU->setPowerChannelVoltage(XPOWERS_BLDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_BLDO2);
|
||||
|
||||
//face m.2
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC3);
|
||||
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC4, XPOWERS_AXP2101_DCDC4_VOL2_MAX);
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC4);
|
||||
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC5);
|
||||
|
||||
|
||||
//not use channel
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC2);
|
||||
// PMU->disablePowerOutput(XPOWERS_DCDC4);
|
||||
// PMU->disablePowerOutput(XPOWERS_DCDC5);
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO1);
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO2);
|
||||
PMU->disablePowerOutput(XPOWERS_VBACKUP);
|
||||
|
||||
|
||||
#elif defined(T_BEAM_S3_BPF)
|
||||
|
||||
//gps
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO4);
|
||||
|
||||
//Sdcard
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||
|
||||
// Extern Power source
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC3);
|
||||
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC5);
|
||||
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO1);
|
||||
|
||||
//not use channel
|
||||
PMU->disablePowerOutput(XPOWERS_BLDO1);
|
||||
PMU->disablePowerOutput(XPOWERS_BLDO2);
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC4);
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC2);
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC4);
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC5);
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO1);
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO2);
|
||||
PMU->disablePowerOutput(XPOWERS_VBACKUP);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Set constant current charge current limit
|
||||
PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
|
||||
|
||||
// Set charge cut-off voltage
|
||||
PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
|
||||
|
||||
// Disable all interrupts
|
||||
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
PMU->clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
PMU->enableIRQ(
|
||||
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ //CHARGE
|
||||
// XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ | XPOWERS_AXP2101_PKEY_POSITIVE_IRQ | //POWER KEY
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
PMU->enableSystemVoltageMeasure();
|
||||
PMU->enableVbusVoltageMeasure();
|
||||
PMU->enableBattVoltageMeasure();
|
||||
|
||||
Serial.printf("=========================================\n");
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
|
||||
Serial.printf("DC1 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
|
||||
Serial.printf("DC2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
|
||||
Serial.printf("DC3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
|
||||
Serial.printf("DC4 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC5)) {
|
||||
Serial.printf("DC5 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC5) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC5));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
|
||||
Serial.printf("LDO2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
|
||||
Serial.printf("LDO3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
|
||||
Serial.printf("ALDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
|
||||
Serial.printf("ALDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
|
||||
Serial.printf("ALDO3: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
|
||||
Serial.printf("ALDO4: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
|
||||
Serial.printf("BLDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
|
||||
Serial.printf("BLDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
|
||||
}
|
||||
Serial.printf("=========================================\n");
|
||||
|
||||
|
||||
// Set the time of pressing the button to turn off
|
||||
PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
||||
uint8_t opt = PMU->getPowerKeyPressOffTime();
|
||||
Serial.print("PowerKeyPressOffTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWEROFF_4S: Serial.println("4 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_6S: Serial.println("6 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_8S: Serial.println("8 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_10S: Serial.println("10 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void disablePeripherals()
|
||||
{
|
||||
|
||||
#ifdef HAS_PMU
|
||||
if (!PMU)return;
|
||||
#if defined(T_BEAM_S3_BPF)
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO4); //gps
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO2); //Sdcard
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC3); // Extern Power source
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC5);
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
void loopPMU()
|
||||
{
|
||||
#ifdef HAS_PMU
|
||||
if (!PMU) {
|
||||
return;
|
||||
}
|
||||
if (!pmuInterrupt) {
|
||||
return;
|
||||
}
|
||||
|
||||
pmuInterrupt = false;
|
||||
// Get PMU Interrupt Status Register
|
||||
uint32_t status = PMU->getIrqStatus();
|
||||
Serial.print("STATUS => HEX:");
|
||||
Serial.print(status, HEX);
|
||||
Serial.print(" BIN:");
|
||||
Serial.println(status, BIN);
|
||||
|
||||
if (PMU->isVbusInsertIrq()) {
|
||||
Serial.println("isVbusInsert");
|
||||
}
|
||||
if (PMU->isVbusRemoveIrq()) {
|
||||
Serial.println("isVbusRemove");
|
||||
}
|
||||
if (PMU->isBatInsertIrq()) {
|
||||
Serial.println("isBatInsert");
|
||||
}
|
||||
if (PMU->isBatRemoveIrq()) {
|
||||
Serial.println("isBatRemove");
|
||||
}
|
||||
if (PMU->isPekeyShortPressIrq()) {
|
||||
Serial.println("isPekeyShortPress");
|
||||
}
|
||||
if (PMU->isPekeyLongPressIrq()) {
|
||||
Serial.println("isPekeyLongPress");
|
||||
}
|
||||
if (PMU->isBatChagerDoneIrq()) {
|
||||
Serial.println("isBatChagerDone");
|
||||
}
|
||||
if (PMU->isBatChagerStartIrq()) {
|
||||
Serial.println("isBatChagerStart");
|
||||
}
|
||||
// Clear PMU Interrupt Status Register
|
||||
PMU->clearIrqStatus();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool beginDisplay()
|
||||
{
|
||||
Wire.beginTransmission(DISPLAY_ADDR);
|
||||
if (Wire.endTransmission() == 0) {
|
||||
Serial.printf("Find Display model at 0x%X address\n", DISPLAY_ADDR);
|
||||
u8g2 = new DISPLAY_MODEL(U8G2_R0, U8X8_PIN_NONE);
|
||||
u8g2->begin();
|
||||
u8g2->clearBuffer();
|
||||
u8g2->setFont(u8g2_font_inb19_mr);
|
||||
u8g2->drawStr(0, 30, "LilyGo");
|
||||
u8g2->drawHLine(2, 35, 47);
|
||||
u8g2->drawHLine(3, 36, 47);
|
||||
u8g2->drawVLine(45, 32, 12);
|
||||
u8g2->drawVLine(46, 33, 12);
|
||||
u8g2->setFont(u8g2_font_inb19_mf);
|
||||
u8g2->drawStr(58, 60, "LoRa");
|
||||
u8g2->sendBuffer();
|
||||
u8g2->setFont(u8g2_font_fur11_tf);
|
||||
delay(3000);
|
||||
return true;
|
||||
}
|
||||
|
||||
Serial.printf("Warning: Failed to find Display at 0x%0X address\n", DISPLAY_ADDR);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool beginSDCard()
|
||||
{
|
||||
#ifdef SDCARD_CS
|
||||
if (SD.begin(SDCARD_CS, SDCardSPI)) {
|
||||
uint32_t cardSize = SD.cardSize() / (1024 * 1024);
|
||||
Serial.print("Sd Card init succeeded, The current available capacity is ");
|
||||
Serial.print(cardSize / 1024.0);
|
||||
Serial.println(" GB");
|
||||
return true;
|
||||
} else {
|
||||
Serial.println("Warning: Failed to init Sd Card");
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void beginWiFi()
|
||||
{
|
||||
if (!WiFi.softAP(BOARD_VARIANT_NAME)) {
|
||||
log_e("Soft AP creation failed.");
|
||||
}
|
||||
IPAddress myIP = WiFi.softAPIP();
|
||||
Serial.print("AP IP address: ");
|
||||
Serial.println(myIP);
|
||||
}
|
||||
|
||||
|
||||
void printWakeupReason()
|
||||
{
|
||||
#ifdef ESP32
|
||||
Serial.print("Reset reason:");
|
||||
esp_sleep_wakeup_cause_t wakeup_reason;
|
||||
wakeup_reason = esp_sleep_get_wakeup_cause();
|
||||
switch (wakeup_reason) {
|
||||
case ESP_SLEEP_WAKEUP_UNDEFINED:
|
||||
Serial.println(" In case of deep sleep, reset was not caused by exit from deep sleep");
|
||||
break;
|
||||
case ESP_SLEEP_WAKEUP_ALL :
|
||||
break;
|
||||
case ESP_SLEEP_WAKEUP_EXT0 :
|
||||
Serial.println("Wakeup caused by external signal using RTC_IO");
|
||||
break;
|
||||
case ESP_SLEEP_WAKEUP_EXT1 :
|
||||
Serial.println("Wakeup caused by external signal using RTC_CNTL");
|
||||
break;
|
||||
case ESP_SLEEP_WAKEUP_TIMER :
|
||||
Serial.println("Wakeup caused by timer");
|
||||
break;
|
||||
case ESP_SLEEP_WAKEUP_TOUCHPAD :
|
||||
Serial.println("Wakeup caused by touchpad");
|
||||
break;
|
||||
case ESP_SLEEP_WAKEUP_ULP :
|
||||
Serial.println("Wakeup caused by ULP program");
|
||||
break;
|
||||
default :
|
||||
Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void getChipInfo()
|
||||
{
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
|
||||
Serial.println("-----------------------------------");
|
||||
|
||||
printWakeupReason();
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
|
||||
if (psramFound()) {
|
||||
uint32_t psram = ESP.getPsramSize();
|
||||
devInfo.psramSize = psram / 1024.0 / 1024.0;
|
||||
Serial.printf("PSRAM is enable! PSRAM: %.2fMB\n", devInfo.psramSize);
|
||||
} else {
|
||||
Serial.println("PSRAM is disable!");
|
||||
devInfo.psramSize = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Serial.print("Flash:");
|
||||
devInfo.flashSize = ESP.getFlashChipSize() / 1024.0 / 1024.0;
|
||||
devInfo.flashSpeed = ESP.getFlashChipSpeed() / 1000 / 1000;
|
||||
devInfo.chipModel = ESP.getChipModel();
|
||||
devInfo.chipModelRev = ESP.getChipRevision();
|
||||
devInfo.chipFreq = ESP.getCpuFreqMHz();
|
||||
|
||||
Serial.print(devInfo.flashSize);
|
||||
Serial.println(" MB");
|
||||
Serial.print("Flash speed:");
|
||||
Serial.print(devInfo.flashSpeed);
|
||||
Serial.println(" M");
|
||||
Serial.print("Model:");
|
||||
|
||||
Serial.println(devInfo.chipModel);
|
||||
Serial.print("Chip Revision:");
|
||||
Serial.println(devInfo.chipModelRev);
|
||||
Serial.print("Freq:");
|
||||
Serial.print(devInfo.chipFreq);
|
||||
Serial.println(" MHZ");
|
||||
Serial.print("SDK Ver:");
|
||||
Serial.println(ESP.getSdkVersion());
|
||||
Serial.print("DATE:");
|
||||
Serial.println(__DATE__);
|
||||
Serial.print("TIME:");
|
||||
Serial.println(__TIME__);
|
||||
|
||||
Serial.print("EFUSE MAC: ");
|
||||
Serial.print( ESP.getEfuseMac(), HEX);
|
||||
Serial.println();
|
||||
|
||||
Serial.println("-----------------------------------");
|
||||
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
uint32_t uid[3];
|
||||
|
||||
uid[0] = HAL_GetUIDw0();
|
||||
uid[1] = HAL_GetUIDw1();
|
||||
uid[2] = HAL_GetUIDw2();
|
||||
Serial.print("STM UID: 0X");
|
||||
Serial.print( uid[0], HEX);
|
||||
Serial.print( uid[1], HEX);
|
||||
Serial.print( uid[2], HEX);
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setupBoards(bool disable_u8g2 )
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
// while (!Serial);
|
||||
|
||||
Serial.println("setupBoards");
|
||||
|
||||
getChipInfo();
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN);
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
SPI.setMISO(RADIO_MISO_PIN);
|
||||
SPI.setMOSI(RADIO_MOSI_PIN);
|
||||
SPI.setSCLK(RADIO_SCLK_PIN);
|
||||
SPI.begin();
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
SDCardSPI.begin(SDCARD_SCLK, SDCARD_MISO, SDCARD_MOSI);
|
||||
#endif
|
||||
|
||||
#ifdef I2C_SDA
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
scanDevices(&Wire);
|
||||
#endif
|
||||
|
||||
#ifdef I2C1_SDA
|
||||
Wire1.begin(I2C1_SDA, I2C1_SCL);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_GPS
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
SerialGPS.begin(GPS_BAUD_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
SerialGPS.setRx(GPS_RX_PIN);
|
||||
SerialGPS.setTx(GPS_TX_PIN);
|
||||
SerialGPS.begin(GPS_BAUD_RATE);
|
||||
#endif // ARDUINO_ARCH_
|
||||
#endif // HAS_GPS
|
||||
|
||||
#if OLED_RST
|
||||
pinMode(OLED_RST, OUTPUT);
|
||||
digitalWrite(OLED_RST, HIGH); delay(20);
|
||||
digitalWrite(OLED_RST, LOW); delay(20);
|
||||
digitalWrite(OLED_RST, HIGH); delay(20);
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_LED
|
||||
/*
|
||||
* T-Beam LED defaults to low level as turn on,
|
||||
* so it needs to be forced to pull up
|
||||
* * * * */
|
||||
#if LED_ON == LOW
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
gpio_hold_dis((gpio_num_t)BOARD_LED);
|
||||
#endif //ARDUINO_ARCH_ESP32
|
||||
#endif
|
||||
|
||||
pinMode(BOARD_LED, OUTPUT);
|
||||
digitalWrite(BOARD_LED, LED_ON);
|
||||
#endif
|
||||
|
||||
#ifdef GPS_EN_PIN
|
||||
pinMode(GPS_EN_PIN, OUTPUT);
|
||||
digitalWrite(GPS_EN_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
#ifdef GPS_RST_PIN
|
||||
pinMode(GPS_RST_PIN, OUTPUT);
|
||||
digitalWrite(GPS_RST_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
SerialGPS.println("@GSR"); delay(300);
|
||||
SerialGPS.println("@GSR"); delay(300);
|
||||
SerialGPS.println("@GSR"); delay(300);
|
||||
SerialGPS.println("@GSR"); delay(300);
|
||||
SerialGPS.println("@GSR"); delay(300);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef RADIO_LDO_EN
|
||||
pinMode(RADIO_LDO_EN, OUTPUT);
|
||||
digitalWrite(RADIO_LDO_EN, HIGH);
|
||||
#endif
|
||||
|
||||
beginPower();
|
||||
|
||||
beginSDCard();
|
||||
|
||||
if (!disable_u8g2) {
|
||||
beginDisplay();
|
||||
}
|
||||
|
||||
// beginWiFi();
|
||||
|
||||
#ifdef HAS_GPS
|
||||
#ifdef T_BEAM_S3_BPF
|
||||
find_gps = beginGPS();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Serial.println("init done . ");
|
||||
}
|
||||
|
||||
|
||||
void printResult(bool radio_online)
|
||||
{
|
||||
Serial.print("Radio : ");
|
||||
Serial.println((radio_online) ? "+" : "-");
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
|
||||
Serial.print("PSRAM : ");
|
||||
Serial.println((psramFound()) ? "+" : "-");
|
||||
|
||||
Serial.print("Display : ");
|
||||
Serial.println(( u8g2) ? "+" : "-");
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
Serial.print("Sd Card : ");
|
||||
Serial.println((SD.cardSize() != 0) ? "+" : "-");
|
||||
#endif
|
||||
|
||||
#ifdef HAS_PMU
|
||||
Serial.print("Power : ");
|
||||
Serial.println(( PMU ) ? "+" : "-");
|
||||
#endif
|
||||
|
||||
#ifdef HAS_GPS
|
||||
#ifdef T_BEAM_S3_BPF
|
||||
Serial.print("GPS : ");
|
||||
Serial.println(( find_gps ) ? "+" : "-");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (u8g2) {
|
||||
|
||||
u8g2->clearBuffer();
|
||||
u8g2->setFont(u8g2_font_NokiaLargeBold_tf );
|
||||
uint16_t str_w = u8g2->getStrWidth(BOARD_VARIANT_NAME);
|
||||
u8g2->drawStr((u8g2->getWidth() - str_w) / 2, 16, BOARD_VARIANT_NAME);
|
||||
u8g2->drawHLine(5, 21, u8g2->getWidth() - 5);
|
||||
|
||||
u8g2->drawStr( 0, 38, "Disp:"); u8g2->drawStr( 45, 38, ( u8g2) ? "+" : "-");
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
u8g2->drawStr( 0, 54, "SD :"); u8g2->drawStr( 45, 54, (SD.cardSize() != 0) ? "+" : "-");
|
||||
#endif
|
||||
|
||||
u8g2->drawStr( 62, 38, "Radio:"); u8g2->drawStr( 120, 38, ( radio_online ) ? "+" : "-");
|
||||
|
||||
#ifdef HAS_PMU
|
||||
u8g2->drawStr( 62, 54, "Power:"); u8g2->drawStr( 120, 54, ( PMU ) ? "+" : "-");
|
||||
#endif
|
||||
|
||||
u8g2->sendBuffer();
|
||||
|
||||
delay(2000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint8_t ledState = LOW;
|
||||
static const uint32_t debounceDelay = 50;
|
||||
static uint32_t lastDebounceTime = 0;
|
||||
|
||||
void flashLed()
|
||||
{
|
||||
#ifdef BOARD_LED
|
||||
if ((millis() - lastDebounceTime) > debounceDelay) {
|
||||
ledState = !ledState;
|
||||
if (ledState) {
|
||||
digitalWrite(BOARD_LED, LED_ON);
|
||||
} else {
|
||||
digitalWrite(BOARD_LED, !LED_ON);
|
||||
}
|
||||
lastDebounceTime = millis();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void scanDevices(TwoWire *w)
|
||||
{
|
||||
uint8_t err, addr;
|
||||
int nDevices = 0;
|
||||
uint32_t start = 0;
|
||||
|
||||
Serial.println("I2C Devices scanning");
|
||||
for (addr = 1; addr < 127; addr++) {
|
||||
start = millis();
|
||||
w->beginTransmission(addr); delay(2);
|
||||
err = w->endTransmission();
|
||||
if (err == 0) {
|
||||
nDevices++;
|
||||
switch (addr) {
|
||||
case 0x77:
|
||||
case 0x76:
|
||||
Serial.println("\tFind BMX280 Sensor!");
|
||||
break;
|
||||
case 0x34:
|
||||
Serial.println("\tFind AXP192/AXP2101 PMU!");
|
||||
break;
|
||||
case 0x3C:
|
||||
Serial.println("\tFind SSD1306/SH1106 dispaly!");
|
||||
break;
|
||||
case 0x51:
|
||||
Serial.println("\tFind PCF8563 RTC!");
|
||||
break;
|
||||
case 0x1C:
|
||||
Serial.println("\tFind QMC6310 MAG Sensor!");
|
||||
break;
|
||||
default:
|
||||
Serial.print("\tI2C device found at address 0x");
|
||||
if (addr < 16) {
|
||||
Serial.print("0");
|
||||
}
|
||||
Serial.print(addr, HEX);
|
||||
Serial.println(" !");
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (err == 4) {
|
||||
Serial.print("Unknow error at address 0x");
|
||||
if (addr < 16) {
|
||||
Serial.print("0");
|
||||
}
|
||||
Serial.println(addr, HEX);
|
||||
}
|
||||
}
|
||||
if (nDevices == 0)
|
||||
Serial.println("No I2C devices found\n");
|
||||
|
||||
Serial.println("Scan devices done.");
|
||||
Serial.println("\n");
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAS_GPS
|
||||
bool beginGPS()
|
||||
{
|
||||
SerialGPS.begin(GPS_BAUD_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
||||
bool result = false;
|
||||
uint32_t startTimeout ;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
SerialGPS.write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(5);
|
||||
// Get version information
|
||||
startTimeout = millis() + 3000;
|
||||
Serial.print("Try to init L76K . Wait stop .");
|
||||
while (SerialGPS.available()) {
|
||||
Serial.print(".");
|
||||
SerialGPS.readString();
|
||||
if (millis() > startTimeout) {
|
||||
Serial.println("Wait L76K stop NMEA timeout!");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Serial.println();
|
||||
SerialGPS.flush();
|
||||
delay(200);
|
||||
|
||||
SerialGPS.write("$PCAS06,0*1B\r\n");
|
||||
startTimeout = millis() + 500;
|
||||
String ver = "";
|
||||
while (!SerialGPS.available()) {
|
||||
if (millis() > startTimeout) {
|
||||
Serial.println("Get L76K timeout!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
SerialGPS.setTimeout(10);
|
||||
ver = SerialGPS.readStringUntil('\n');
|
||||
if (ver.startsWith("$GPTXT,01,01,02")) {
|
||||
Serial.println("L76K GNSS init succeeded, using L76K GNSS Module\n");
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
delay(500);
|
||||
}
|
||||
// Initialize the L76K Chip, use GPS + GLONASS
|
||||
SerialGPS.write("$PCAS04,5*1C\r\n");
|
||||
delay(250);
|
||||
// only ask for RMC and GGA
|
||||
SerialGPS.write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(250);
|
||||
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
||||
SerialGPS.write("$PCAS11,3*1E\r\n");
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
102
examples/LoRaWAN/LoRaWAN_ABP/LoRaBoards.h
Normal file
102
examples/LoRaWAN/LoRaWAN_ABP/LoRaBoards.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* @file boards.h
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd
|
||||
* @date 2024-04-25
|
||||
* @last-update 2024-08-07
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "utilities.h"
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
#include <SD.h>
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
#include <FS.h>
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
#include <U8g2lib.h>
|
||||
#include <XPowersLib.h>
|
||||
|
||||
#ifndef DISPLAY_MODEL
|
||||
#define DISPLAY_MODEL U8G2_SSD1306_128X64_NONAME_F_HW_I2C
|
||||
#endif
|
||||
|
||||
#ifndef OLED_WIRE_PORT
|
||||
#define OLED_WIRE_PORT Wire
|
||||
#endif
|
||||
|
||||
#ifndef PMU_WIRE_PORT
|
||||
#define PMU_WIRE_PORT Wire
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_ADDR
|
||||
#define DISPLAY_ADDR 0x3C
|
||||
#endif
|
||||
|
||||
#ifndef LORA_FREQ_CONFIG
|
||||
#define LORA_FREQ_CONFIG 915.0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
String chipModel;
|
||||
float psramSize;
|
||||
uint8_t chipModelRev;
|
||||
uint8_t chipFreq;
|
||||
uint8_t flashSize;
|
||||
uint8_t flashSpeed;
|
||||
} DevInfo_t;
|
||||
|
||||
|
||||
void setupBoards(bool disable_u8g2 = false);
|
||||
|
||||
bool beginSDCard();
|
||||
|
||||
bool beginDisplay();
|
||||
|
||||
void disablePeripherals();
|
||||
|
||||
bool beginPower();
|
||||
|
||||
void printResult(bool radio_online);
|
||||
|
||||
void flashLed();
|
||||
|
||||
void scanDevices(TwoWire *w);
|
||||
|
||||
bool beginGPS();
|
||||
|
||||
void loopPMU();
|
||||
|
||||
#ifdef HAS_PMU
|
||||
extern XPowersLibInterface *PMU;
|
||||
extern bool pmuInterrupt;
|
||||
#endif
|
||||
extern DISPLAY_MODEL *u8g2;
|
||||
|
||||
#define U8G2_HOR_ALIGN_CENTER(t) ((u8g2->getDisplayWidth() - (u8g2->getUTF8Width(t))) / 2)
|
||||
#define U8G2_HOR_ALIGN_RIGHT(t) ( u8g2->getDisplayWidth() - u8g2->getUTF8Width(t))
|
||||
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
|
||||
#if defined(HAS_SDCARD)
|
||||
extern SPIClass SDCardSPI;
|
||||
#endif
|
||||
|
||||
#define SerialGPS Serial1
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
extern HardwareSerial SerialGPS;
|
||||
#endif
|
||||
96
examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino
Normal file
96
examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
RadioLib LoRaWAN ABP Example
|
||||
|
||||
ABP = Activation by Personalisation, an alternative
|
||||
to OTAA (Over the Air Activation). OTAA is preferable.
|
||||
|
||||
This example will send uplink packets to a LoRaWAN network.
|
||||
Before you start, you will have to register your device at
|
||||
https://www.thethingsnetwork.org/
|
||||
After your device is registered, you can run this example.
|
||||
The device will join the network and start uploading data.
|
||||
|
||||
LoRaWAN v1.0.4/v1.1 requires the use of persistent storage.
|
||||
As this example does not use persistent storage, running this
|
||||
examples REQUIRES you to check "Resets frame counters"
|
||||
on your LoRaWAN dashboard. Refer to the notes or the
|
||||
network's documentation on how to do this.
|
||||
To comply with LoRaWAN's persistent storage, refer to
|
||||
https://github.com/radiolib-org/radiolib-persistence
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
|
||||
For LoRaWAN details, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/LoRaWAN
|
||||
|
||||
*/
|
||||
|
||||
#include "configABP.h"
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
while (!Serial);
|
||||
|
||||
setupBoards();
|
||||
|
||||
#ifdef RADIO_TCXO_ENABLE
|
||||
pinMode(RADIO_TCXO_ENABLE, OUTPUT);
|
||||
digitalWrite(RADIO_TCXO_ENABLE, HIGH);
|
||||
#endif
|
||||
|
||||
delay(5000); // Give time to switch to the serial monitor
|
||||
Serial.println(F("\nSetup ... "));
|
||||
|
||||
Serial.println(F("Initialise the radio"));
|
||||
int state = radio.begin();
|
||||
debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
|
||||
|
||||
Serial.println(F("Initialise LoRaWAN Network credentials"));
|
||||
node.beginABP(devAddr, fNwkSIntKey, sNwkSIntKey, nwkSEncKey, appSKey);
|
||||
|
||||
node.activateABP();
|
||||
debug(state != RADIOLIB_ERR_NONE, F("Activate ABP failed"), state, true);
|
||||
|
||||
Serial.println(F("Ready!\n"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.println(F("Sending uplink"));
|
||||
|
||||
// This is the place to gather the sensor inputs
|
||||
// Instead of reading any real sensor, we just generate some random numbers as example
|
||||
uint8_t value1 = radio.random(100);
|
||||
uint16_t value2 = radio.random(2000);
|
||||
|
||||
// Build payload byte array
|
||||
uint8_t uplinkPayload[3];
|
||||
uplinkPayload[0] = value1;
|
||||
uplinkPayload[1] = highByte(value2); // See notes for high/lowByte functions
|
||||
uplinkPayload[2] = lowByte(value2);
|
||||
|
||||
// Perform an uplink
|
||||
int state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
|
||||
debug(state < RADIOLIB_ERR_NONE, F("Error in sendReceive"), state, false);
|
||||
|
||||
// Check if a downlink was received
|
||||
// (state 0 = no downlink, state 1/2 = downlink in window Rx1/Rx2)
|
||||
if (state > 0) {
|
||||
Serial.println(F("Received a downlink"));
|
||||
} else {
|
||||
Serial.println(F("No downlink received"));
|
||||
}
|
||||
|
||||
Serial.print(F("Next uplink in "));
|
||||
Serial.print(uplinkIntervalSeconds);
|
||||
Serial.println(F(" seconds\n"));
|
||||
|
||||
// Wait until next uplink - observing legal & TTN FUP constraints
|
||||
delay(uplinkIntervalSeconds * 1000UL); // delay needs milli-seconds
|
||||
}
|
||||
155
examples/LoRaWAN/LoRaWAN_ABP/configABP.h
Normal file
155
examples/LoRaWAN/LoRaWAN_ABP/configABP.h
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
|
||||
#define _RADIOLIB_EX_LORAWAN_CONFIG_H
|
||||
|
||||
#include <RadioLib.h>
|
||||
#include "LoRaBoards.h"
|
||||
|
||||
#if defined(USING_SX1276)
|
||||
SX1276 radio = new Module(RADIO_CS_PIN, RADIO_DIO0_PIN, RADIO_RST_PIN, RADIO_DIO1_PIN);
|
||||
#elif defined(USING_SX1262)
|
||||
SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
|
||||
#elif defined(USING_SX1278)
|
||||
SX1278 radio = new Module(RADIO_CS_PIN, RADIO_DIO0_PIN, RADIO_RST_PIN, RADIO_DIO1_PIN);
|
||||
#elif defined(USING_LR1121)
|
||||
LR1121 radio = new Module(RADIO_CS_PIN, RADIO_DIO9_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
|
||||
#endif
|
||||
|
||||
|
||||
// how often to send an uplink - consider legal & FUP constraints - see notes
|
||||
const uint32_t uplinkIntervalSeconds = 1UL * 60UL; // minutes x seconds
|
||||
|
||||
// device address - either a development address or one assigned
|
||||
// to the LoRaWAN Service Provider - TTN will generate one for you
|
||||
#ifndef RADIOLIB_LORAWAN_DEV_ADDR // Replace with your DevAddr
|
||||
#define RADIOLIB_LORAWAN_DEV_ADDR 0x260DA9E1
|
||||
#endif
|
||||
|
||||
#ifndef RADIOLIB_LORAWAN_FNWKSINT_KEY // Replace with your FNwkSInt Key
|
||||
#define RADIOLIB_LORAWAN_FNWKSINT_KEY 0xD2, 0xB1, 0x21, 0xCC, 0xDE, 0xBE, 0xE5, 0x29, 0xEC, 0x00, 0xD2, 0xE4, 0xBB, 0x25, 0x9D, 0xFF
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_SNWKSINT_KEY // Replace with your SNwkSInt Key
|
||||
#define RADIOLIB_LORAWAN_SNWKSINT_KEY 0x17, 0x4A, 0xAD, 0x42, 0x32, 0x5B, 0x54, 0xAC, 0xA5, 0xB9, 0xE6, 0x45, 0x60, 0x3E, 0x6E, 0x64
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_NWKSENC_KEY // Replace with your NwkSEnc Key
|
||||
#define RADIOLIB_LORAWAN_NWKSENC_KEY 0xA6, 0xFB, 0xE9, 0xDC, 0xB7, 0x16, 0x34, 0x6C, 0xC1, 0x6F, 0xB8, 0x3C, 0x94, 0x0C, 0xA1, 0x63
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_APPS_KEY // Replace with your AppS Key
|
||||
#define RADIOLIB_LORAWAN_APPS_KEY 0xCB, 0xE2, 0x15, 0x39, 0xFB, 0xD4, 0x9A, 0x6E, 0xF5, 0x82, 0xE1, 0x97, 0xEC, 0x2B, 0x0E, 0x3C
|
||||
#endif
|
||||
|
||||
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
||||
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
||||
|
||||
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
|
||||
const LoRaWANBand_t Region = CN500;
|
||||
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
|
||||
|
||||
// ============================================================================
|
||||
// Below is to support the sketch - only make changes if the notes say so ...
|
||||
|
||||
// copy over the keys in to the something that will not compile if incorrectly formatted
|
||||
uint32_t devAddr = RADIOLIB_LORAWAN_DEV_ADDR;
|
||||
uint8_t fNwkSIntKey[] = { RADIOLIB_LORAWAN_FNWKSINT_KEY };
|
||||
uint8_t sNwkSIntKey[] = { RADIOLIB_LORAWAN_SNWKSINT_KEY };
|
||||
uint8_t nwkSEncKey[] = { RADIOLIB_LORAWAN_NWKSENC_KEY };
|
||||
uint8_t appSKey[] = { RADIOLIB_LORAWAN_APPS_KEY };
|
||||
|
||||
// create the LoRaWAN node
|
||||
LoRaWANNode node(&radio, &Region, subBand);
|
||||
|
||||
// result code to text - these are error codes that can be raised when using LoRaWAN
|
||||
// however, RadioLib has many more - see https://jgromes.github.io/RadioLib/group__status__codes.html for a complete list
|
||||
String stateDecode(const int16_t result) {
|
||||
switch (result) {
|
||||
case RADIOLIB_ERR_NONE:
|
||||
return "ERR_NONE";
|
||||
case RADIOLIB_ERR_CHIP_NOT_FOUND:
|
||||
return "ERR_CHIP_NOT_FOUND";
|
||||
case RADIOLIB_ERR_PACKET_TOO_LONG:
|
||||
return "ERR_PACKET_TOO_LONG";
|
||||
case RADIOLIB_ERR_RX_TIMEOUT:
|
||||
return "ERR_RX_TIMEOUT";
|
||||
case RADIOLIB_ERR_CRC_MISMATCH:
|
||||
return "ERR_CRC_MISMATCH";
|
||||
case RADIOLIB_ERR_INVALID_BANDWIDTH:
|
||||
return "ERR_INVALID_BANDWIDTH";
|
||||
case RADIOLIB_ERR_INVALID_SPREADING_FACTOR:
|
||||
return "ERR_INVALID_SPREADING_FACTOR";
|
||||
case RADIOLIB_ERR_INVALID_CODING_RATE:
|
||||
return "ERR_INVALID_CODING_RATE";
|
||||
case RADIOLIB_ERR_INVALID_FREQUENCY:
|
||||
return "ERR_INVALID_FREQUENCY";
|
||||
case RADIOLIB_ERR_INVALID_OUTPUT_POWER:
|
||||
return "ERR_INVALID_OUTPUT_POWER";
|
||||
case RADIOLIB_ERR_NETWORK_NOT_JOINED:
|
||||
return "RADIOLIB_ERR_NETWORK_NOT_JOINED";
|
||||
case RADIOLIB_ERR_DOWNLINK_MALFORMED:
|
||||
return "RADIOLIB_ERR_DOWNLINK_MALFORMED";
|
||||
case RADIOLIB_ERR_INVALID_REVISION:
|
||||
return "RADIOLIB_ERR_INVALID_REVISION";
|
||||
case RADIOLIB_ERR_INVALID_PORT:
|
||||
return "RADIOLIB_ERR_INVALID_PORT";
|
||||
case RADIOLIB_ERR_NO_RX_WINDOW:
|
||||
return "RADIOLIB_ERR_NO_RX_WINDOW";
|
||||
case RADIOLIB_ERR_INVALID_CID:
|
||||
return "RADIOLIB_ERR_INVALID_CID";
|
||||
case RADIOLIB_ERR_UPLINK_UNAVAILABLE:
|
||||
return "RADIOLIB_ERR_UPLINK_UNAVAILABLE";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_FULL:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_FULL";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND";
|
||||
case RADIOLIB_ERR_JOIN_NONCE_INVALID:
|
||||
return "RADIOLIB_ERR_JOIN_NONCE_INVALID";
|
||||
case RADIOLIB_ERR_N_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_N_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_A_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_A_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_DWELL_TIME_EXCEEDED:
|
||||
return "RADIOLIB_ERR_DWELL_TIME_EXCEEDED";
|
||||
case RADIOLIB_ERR_CHECKSUM_MISMATCH:
|
||||
return "RADIOLIB_ERR_CHECKSUM_MISMATCH";
|
||||
case RADIOLIB_ERR_NO_JOIN_ACCEPT:
|
||||
return "RADIOLIB_ERR_NO_JOIN_ACCEPT";
|
||||
case RADIOLIB_LORAWAN_SESSION_RESTORED:
|
||||
return "RADIOLIB_LORAWAN_SESSION_RESTORED";
|
||||
case RADIOLIB_LORAWAN_NEW_SESSION:
|
||||
return "RADIOLIB_LORAWAN_NEW_SESSION";
|
||||
case RADIOLIB_ERR_NONCES_DISCARDED:
|
||||
return "RADIOLIB_ERR_NONCES_DISCARDED";
|
||||
case RADIOLIB_ERR_SESSION_DISCARDED:
|
||||
return "RADIOLIB_ERR_SESSION_DISCARDED";
|
||||
}
|
||||
return "See https://jgromes.github.io/RadioLib/group__status__codes.html";
|
||||
}
|
||||
|
||||
// helper function to display any issues
|
||||
void debug(bool failed, const __FlashStringHelper *message, int state, bool halt)
|
||||
{
|
||||
if (failed) {
|
||||
Serial.print(message);
|
||||
Serial.print(" - ");
|
||||
Serial.print(stateDecode(state));
|
||||
Serial.print(" (");
|
||||
Serial.print(state);
|
||||
Serial.println(")");
|
||||
while (halt) {
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to display a byte array
|
||||
void arrayDump(uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
for (uint16_t c = 0; c < len; c++) {
|
||||
char b = buffer[c];
|
||||
if (b < 0x10) {
|
||||
Serial.print('0');
|
||||
}
|
||||
Serial.print(b, HEX);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -648,7 +648,7 @@ void setupBoards(bool disable_u8g2 )
|
|||
beginDisplay();
|
||||
}
|
||||
|
||||
beginWiFi();
|
||||
// beginWiFi();
|
||||
|
||||
#ifdef HAS_GPS
|
||||
#ifdef T_BEAM_S3_BPF
|
||||
|
|
|
|||
|
|
@ -25,16 +25,6 @@
|
|||
#include <RadioLib.h>
|
||||
#include "LoRaBoards.h"
|
||||
|
||||
// !!!!! APP EUI
|
||||
#define RADIOLIB_LORAWAN_JOIN_EUI 0xAABB112233445566
|
||||
// !!!!! DEV EUI
|
||||
#define RADIOLIB_LORAWAN_DEV_EUI 0x70B3D57ED0066FDA
|
||||
// !!!!! APP EUI
|
||||
#define RADIOLIB_LORAWAN_APP_KEY 0xAA, 0xBB, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66
|
||||
// !!! APP KEY
|
||||
#define RADIOLIB_LORAWAN_NWK_KEY 0xF2, 0x84, 0x31, 0x0F, 0x82, 0x65, 0x99, 0x4F, 0x70, 0xCB, 0x88, 0x74, 0xFA, 0xD6, 0x71, 0xA2
|
||||
|
||||
|
||||
#if defined(USING_SX1276)
|
||||
SX1276 radio = new Module(RADIO_CS_PIN, RADIO_DIO0_PIN, RADIO_RST_PIN, RADIO_DIO1_PIN);
|
||||
#elif defined(USING_SX1262)
|
||||
|
|
@ -45,6 +35,21 @@ SX1278 radio = new Module(RADIO_CS_PIN, RADIO_DIO0_PIN, RADIO_RST_PIN, RADIO_DIO
|
|||
LR1121 radio = new Module(RADIO_CS_PIN, RADIO_DIO9_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
|
||||
#endif
|
||||
|
||||
// joinEUI - previous versions of LoRaWAN called this AppEUI
|
||||
// for development purposes you can use all zeros - see wiki for details
|
||||
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
|
||||
|
||||
|
||||
// the Device EUI & two keys can be generated on the TTN console
|
||||
#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
|
||||
#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
|
||||
#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
|
||||
#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
|
||||
// how often to send an uplink - consider legal & FUP constraints - see notes
|
||||
const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
|
||||
|
|
@ -69,15 +74,87 @@ uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
|
|||
// create the LoRaWAN node
|
||||
LoRaWANNode node(&radio, &Region, subBand);
|
||||
|
||||
// helper function to display any issues
|
||||
void debug(bool isFail, const __FlashStringHelper *message, int state, bool Freeze)
|
||||
|
||||
// result code to text - these are error codes that can be raised when using LoRaWAN
|
||||
// however, RadioLib has many more - see https://jgromes.github.io/RadioLib/group__status__codes.html for a complete list
|
||||
String stateDecode(const int16_t result)
|
||||
{
|
||||
if (isFail) {
|
||||
switch (result) {
|
||||
case RADIOLIB_ERR_NONE:
|
||||
return "ERR_NONE";
|
||||
case RADIOLIB_ERR_CHIP_NOT_FOUND:
|
||||
return "ERR_CHIP_NOT_FOUND";
|
||||
case RADIOLIB_ERR_PACKET_TOO_LONG:
|
||||
return "ERR_PACKET_TOO_LONG";
|
||||
case RADIOLIB_ERR_RX_TIMEOUT:
|
||||
return "ERR_RX_TIMEOUT";
|
||||
case RADIOLIB_ERR_CRC_MISMATCH:
|
||||
return "ERR_CRC_MISMATCH";
|
||||
case RADIOLIB_ERR_INVALID_BANDWIDTH:
|
||||
return "ERR_INVALID_BANDWIDTH";
|
||||
case RADIOLIB_ERR_INVALID_SPREADING_FACTOR:
|
||||
return "ERR_INVALID_SPREADING_FACTOR";
|
||||
case RADIOLIB_ERR_INVALID_CODING_RATE:
|
||||
return "ERR_INVALID_CODING_RATE";
|
||||
case RADIOLIB_ERR_INVALID_FREQUENCY:
|
||||
return "ERR_INVALID_FREQUENCY";
|
||||
case RADIOLIB_ERR_INVALID_OUTPUT_POWER:
|
||||
return "ERR_INVALID_OUTPUT_POWER";
|
||||
case RADIOLIB_ERR_NETWORK_NOT_JOINED:
|
||||
return "RADIOLIB_ERR_NETWORK_NOT_JOINED";
|
||||
case RADIOLIB_ERR_DOWNLINK_MALFORMED:
|
||||
return "RADIOLIB_ERR_DOWNLINK_MALFORMED";
|
||||
case RADIOLIB_ERR_INVALID_REVISION:
|
||||
return "RADIOLIB_ERR_INVALID_REVISION";
|
||||
case RADIOLIB_ERR_INVALID_PORT:
|
||||
return "RADIOLIB_ERR_INVALID_PORT";
|
||||
case RADIOLIB_ERR_NO_RX_WINDOW:
|
||||
return "RADIOLIB_ERR_NO_RX_WINDOW";
|
||||
case RADIOLIB_ERR_INVALID_CID:
|
||||
return "RADIOLIB_ERR_INVALID_CID";
|
||||
case RADIOLIB_ERR_UPLINK_UNAVAILABLE:
|
||||
return "RADIOLIB_ERR_UPLINK_UNAVAILABLE";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_FULL:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_FULL";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND";
|
||||
case RADIOLIB_ERR_JOIN_NONCE_INVALID:
|
||||
return "RADIOLIB_ERR_JOIN_NONCE_INVALID";
|
||||
case RADIOLIB_ERR_N_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_N_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_A_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_A_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_DWELL_TIME_EXCEEDED:
|
||||
return "RADIOLIB_ERR_DWELL_TIME_EXCEEDED";
|
||||
case RADIOLIB_ERR_CHECKSUM_MISMATCH:
|
||||
return "RADIOLIB_ERR_CHECKSUM_MISMATCH";
|
||||
case RADIOLIB_ERR_NO_JOIN_ACCEPT:
|
||||
return "RADIOLIB_ERR_NO_JOIN_ACCEPT";
|
||||
case RADIOLIB_LORAWAN_SESSION_RESTORED:
|
||||
return "RADIOLIB_LORAWAN_SESSION_RESTORED";
|
||||
case RADIOLIB_LORAWAN_NEW_SESSION:
|
||||
return "RADIOLIB_LORAWAN_NEW_SESSION";
|
||||
case RADIOLIB_ERR_NONCES_DISCARDED:
|
||||
return "RADIOLIB_ERR_NONCES_DISCARDED";
|
||||
case RADIOLIB_ERR_SESSION_DISCARDED:
|
||||
return "RADIOLIB_ERR_SESSION_DISCARDED";
|
||||
}
|
||||
return "See https://jgromes.github.io/RadioLib/group__status__codes.html";
|
||||
}
|
||||
|
||||
// helper function to display any issues
|
||||
void debug(bool failed, const __FlashStringHelper *message, int state, bool halt)
|
||||
{
|
||||
if (failed) {
|
||||
Serial.print(message);
|
||||
Serial.print("(");
|
||||
Serial.print(" - ");
|
||||
Serial.print(stateDecode(state));
|
||||
Serial.print(" (");
|
||||
Serial.print(state);
|
||||
Serial.println(")");
|
||||
while (Freeze);
|
||||
while (halt) {
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,8 +171,6 @@ void arrayDump(uint8_t *buffer, uint16_t len)
|
|||
Serial.println();
|
||||
}
|
||||
|
||||
static uint32_t txCounter = 0;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
|
@ -116,10 +191,10 @@ void setup()
|
|||
|
||||
Serial.println(F("Initialise the radio"));
|
||||
|
||||
int state = radio.begin();
|
||||
int16_t state = 0; // return value for calls to RadioLib
|
||||
Serial.println(F("Initialise the radio"));
|
||||
state = radio.begin();
|
||||
debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
|
||||
printResult(state == RADIOLIB_ERR_NONE);
|
||||
delay(2000);
|
||||
|
||||
#ifdef USING_DIO2_AS_RF_SWITCH
|
||||
#ifdef USING_SX1262
|
||||
|
|
@ -174,38 +249,60 @@ void setup()
|
|||
radio.setTCXO(3.0);
|
||||
#endif
|
||||
|
||||
int retry = 0;
|
||||
while (1) {
|
||||
if (u8g2) {
|
||||
u8g2->clearBuffer();
|
||||
u8g2->setFont(u8g2_font_NokiaLargeBold_tf );
|
||||
uint16_t str_w = u8g2->getStrWidth(BOARD_VARIANT_NAME);
|
||||
u8g2->drawStr((u8g2->getWidth() - str_w) / 2, 16, BOARD_VARIANT_NAME);
|
||||
u8g2->drawHLine(5, 21, u8g2->getWidth() - 5);
|
||||
// Override the default join rate
|
||||
uint8_t joinDR = 4;
|
||||
|
||||
u8g2->setCursor(0, 38);
|
||||
u8g2->print("Join LoRaWAN :");
|
||||
u8g2->println(String(retry++));
|
||||
u8g2->sendBuffer();
|
||||
}
|
||||
Serial.println(F("Join ('login') to the LoRaWAN Network"));
|
||||
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
||||
state = node.activateOTAA();
|
||||
debug(state < RADIOLIB_ERR_NONE, F("Join failed"), state, false);
|
||||
if (state == RADIOLIB_ERR_NONE || state == RADIOLIB_LORAWAN_NEW_SESSION) {
|
||||
break;
|
||||
}
|
||||
delay(10000);
|
||||
Serial.print("Retry ");
|
||||
// Setup the OTAA session information
|
||||
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
||||
|
||||
Serial.println(F("Join ('login') the LoRaWAN Network"));
|
||||
state = node.activateOTAA(joinDR);
|
||||
debug(state != RADIOLIB_LORAWAN_NEW_SESSION, F("Join failed"), state, true);
|
||||
|
||||
// Print the DevAddr
|
||||
Serial.print("[LoRaWAN] DevAddr: ");
|
||||
Serial.println((unsigned long)node.getDevAddr(), HEX);
|
||||
|
||||
// Enable the ADR algorithm (on by default which is preferable)
|
||||
node.setADR(true);
|
||||
|
||||
// Set a datarate to start off with
|
||||
node.setDatarate(5);
|
||||
|
||||
// Manages uplink intervals to the TTN Fair Use Policy
|
||||
node.setDutyCycle(true, 1250);
|
||||
|
||||
// Enable the dwell time limits - 400ms is the limit for the US
|
||||
node.setDwellTime(true, 400);
|
||||
|
||||
Serial.println(F("Ready!\n"));
|
||||
|
||||
if (u8g2) {
|
||||
u8g2->clearBuffer();
|
||||
u8g2->setFont(u8g2_font_NokiaLargeBold_tf );
|
||||
uint16_t str_w = u8g2->getStrWidth(BOARD_VARIANT_NAME);
|
||||
u8g2->drawStr((u8g2->getWidth() - str_w) / 2, 16, BOARD_VARIANT_NAME);
|
||||
u8g2->drawHLine(5, 21, u8g2->getWidth() - 5);
|
||||
|
||||
u8g2->setCursor(0, 38);
|
||||
u8g2->print("Join LoRaWAN Ready!");
|
||||
u8g2->sendBuffer();
|
||||
}
|
||||
|
||||
Serial.println(F("Joined!\n"));
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.println(F("Sending uplink"));
|
||||
int16_t state = RADIOLIB_ERR_NONE;
|
||||
|
||||
// set battery fill level - the LoRaWAN network server
|
||||
// may periodically request this information
|
||||
// 0 = external power source
|
||||
// 1 = lowest (empty battery)
|
||||
// 254 = highest (full battery)
|
||||
// 255 = unable to measure
|
||||
uint8_t battLevel = 146;
|
||||
node.setDeviceStatus(battLevel);
|
||||
|
||||
// This is the place to gather the sensor inputs
|
||||
// Instead of reading any real sensor, we just generate some random numbers as example
|
||||
|
|
@ -218,37 +315,105 @@ void loop()
|
|||
uplinkPayload[1] = highByte(value2); // See notes for high/lowByte functions
|
||||
uplinkPayload[2] = lowByte(value2);
|
||||
|
||||
// Perform an uplink
|
||||
int state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
|
||||
debug((state != RADIOLIB_LORAWAN_NO_DOWNLINK) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false);
|
||||
uint8_t downlinkPayload[10]; // Make sure this fits your plans!
|
||||
size_t downlinkSize; // To hold the actual payload size received
|
||||
|
||||
if (u8g2) {
|
||||
u8g2->clearBuffer();
|
||||
u8g2->setFont(u8g2_font_NokiaLargeBold_tf );
|
||||
uint16_t str_w = u8g2->getStrWidth(BOARD_VARIANT_NAME);
|
||||
u8g2->drawStr((u8g2->getWidth() - str_w) / 2, 16, BOARD_VARIANT_NAME);
|
||||
u8g2->drawHLine(5, 21, u8g2->getWidth() - 5);
|
||||
u8g2->setCursor(0, 38);
|
||||
u8g2->print(node.isActivated() ? "Joined." : "NoJoin");
|
||||
u8g2->print("\tTx:"); u8g2->println(++txCounter);
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
u8g2->setCursor(0, 54);
|
||||
u8g2->println("MAC:"); u8g2->println(ESP.getEfuseMac(), HEX);
|
||||
#endif
|
||||
u8g2->sendBuffer();
|
||||
// you can also retrieve additional information about an uplink or
|
||||
// downlink by passing a reference to LoRaWANEvent_t structure
|
||||
LoRaWANEvent_t uplinkDetails;
|
||||
LoRaWANEvent_t downlinkDetails;
|
||||
|
||||
uint8_t fPort = 10;
|
||||
|
||||
// Retrieve the last uplink frame counter
|
||||
uint32_t fCntUp = node.getFCntUp();
|
||||
|
||||
// Send a confirmed uplink on the second uplink
|
||||
// and also request the LinkCheck and DeviceTime MAC commands
|
||||
Serial.println(F("Sending uplink"));
|
||||
if (fCntUp == 1) {
|
||||
Serial.println(F("and requesting LinkCheck and DeviceTime"));
|
||||
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_LINK_CHECK);
|
||||
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_DEVICE_TIME);
|
||||
state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload), fPort, downlinkPayload, &downlinkSize, true, &uplinkDetails, &downlinkDetails);
|
||||
} else {
|
||||
state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload), fPort, downlinkPayload, &downlinkSize, false, &uplinkDetails, &downlinkDetails);
|
||||
}
|
||||
debug(state < RADIOLIB_ERR_NONE, F("Error in sendReceive"), state, false);
|
||||
|
||||
// Check if a downlink was received
|
||||
// (state 0 = no downlink, state 1/2 = downlink in window Rx1/Rx2)
|
||||
if (state > 0) {
|
||||
Serial.println(F("Received a downlink"));
|
||||
// Did we get a downlink with data for us
|
||||
if (downlinkSize > 0) {
|
||||
Serial.println(F("Downlink data: "));
|
||||
arrayDump(downlinkPayload, downlinkSize);
|
||||
} else {
|
||||
Serial.println(F("<MAC commands only>"));
|
||||
}
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
Serial.print(F("[LoRaWAN] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print SNR (Signal-to-Noise Ratio)
|
||||
Serial.print(F("[LoRaWAN] SNR:\t\t"));
|
||||
Serial.print(radio.getSNR());
|
||||
Serial.println(F(" dB"));
|
||||
|
||||
// print extra information about the event
|
||||
Serial.println(F("[LoRaWAN] Event information:"));
|
||||
Serial.print(F("[LoRaWAN] Confirmed:\t"));
|
||||
Serial.println(downlinkDetails.confirmed);
|
||||
Serial.print(F("[LoRaWAN] Confirming:\t"));
|
||||
Serial.println(downlinkDetails.confirming);
|
||||
Serial.print(F("[LoRaWAN] Datarate:\t"));
|
||||
Serial.println(downlinkDetails.datarate);
|
||||
Serial.print(F("[LoRaWAN] Frequency:\t"));
|
||||
Serial.print(downlinkDetails.freq, 3);
|
||||
Serial.println(F(" MHz"));
|
||||
Serial.print(F("[LoRaWAN] Frame count:\t"));
|
||||
Serial.println(downlinkDetails.fCnt);
|
||||
Serial.print(F("[LoRaWAN] Port:\t\t"));
|
||||
Serial.println(downlinkDetails.fPort);
|
||||
Serial.print(F("[LoRaWAN] Time-on-air: \t"));
|
||||
Serial.print(node.getLastToA());
|
||||
Serial.println(F(" ms"));
|
||||
Serial.print(F("[LoRaWAN] Rx window: \t"));
|
||||
Serial.println(state);
|
||||
|
||||
uint8_t margin = 0;
|
||||
uint8_t gwCnt = 0;
|
||||
if (node.getMacLinkCheckAns(&margin, &gwCnt) == RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("[LoRaWAN] LinkCheck margin:\t"));
|
||||
Serial.println(margin);
|
||||
Serial.print(F("[LoRaWAN] LinkCheck count:\t"));
|
||||
Serial.println(gwCnt);
|
||||
}
|
||||
|
||||
uint32_t networkTime = 0;
|
||||
uint8_t fracSecond = 0;
|
||||
if (node.getMacDeviceTimeAns(&networkTime, &fracSecond, true) == RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("[LoRaWAN] DeviceTime Unix:\t"));
|
||||
Serial.println(networkTime);
|
||||
Serial.print(F("[LoRaWAN] DeviceTime second:\t1/"));
|
||||
Serial.println(fracSecond);
|
||||
}
|
||||
|
||||
} else {
|
||||
Serial.println(F("[LoRaWAN] No downlink received"));
|
||||
}
|
||||
|
||||
// wait before sending another packet
|
||||
uint32_t minimumDelay = uplinkIntervalSeconds * 1000UL;
|
||||
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per FUP & law!)
|
||||
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
|
||||
|
||||
Serial.print(F("Uplink complete, next in "));
|
||||
Serial.print(uplinkIntervalSeconds);
|
||||
Serial.println(F(" seconds"));
|
||||
Serial.print(F("[LoRaWAN] Next uplink in "));
|
||||
Serial.print(delayMs / 1000);
|
||||
Serial.println(F(" seconds\n"));
|
||||
|
||||
#ifdef BOARD_LED
|
||||
digitalWrite(BOARD_LED, LED_ON);
|
||||
delay(200);
|
||||
digitalWrite(BOARD_LED, !LED_ON);
|
||||
#endif
|
||||
|
||||
// Wait until next uplink - observing legal & TTN FUP constraints
|
||||
delay(uplinkIntervalSeconds * 1000UL); // delay needs milli-seconds
|
||||
delay(delayMs);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue