kopia lustrzana https://github.com/Max-Plastix/tbeam-helium-mapper
Reset FCount at 50,000 uplinks.
rodzic
b64e90e9fb
commit
32f51fd068
|
@ -3,3 +3,4 @@
|
|||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
.vscode/extensions.json
|
||||
|
|
|
@ -3,5 +3,8 @@
|
|||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -192,6 +192,10 @@ void build_mapper_packet() {
|
|||
txBuffer[10] = sats & 0xFF;
|
||||
}
|
||||
|
||||
// Helium requires a FCount reset sometime before hitting 0xFFFF
|
||||
// 50,000 makes it obvious it was intentional
|
||||
#define MAX_FCOUNT 50000
|
||||
|
||||
boolean send_uplink(uint8_t *txBuffer, uint8_t length, uint8_t fport, boolean confirmed) {
|
||||
if (confirmed) {
|
||||
Serial.println("ACK requested");
|
||||
|
@ -206,6 +210,21 @@ boolean send_uplink(uint8_t *txBuffer, uint8_t length, uint8_t fport, boolean co
|
|||
Serial.println("Surprise send failure!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Helium requires a re-join / reset of count to avoid 16bit count rollover
|
||||
// Hopefully a device reboot every 50k uplinks is no problem.
|
||||
if (ttn_get_count() > MAX_FCOUNT) {
|
||||
Serial.println("FCount Rollover!");
|
||||
|
||||
// I don't understand why this doesn't show at all
|
||||
screen_print("\n\nRollover Reset!\n");
|
||||
screen_update();
|
||||
delay(1000); // Give some time to read the screen
|
||||
|
||||
ttn_erase_prefs();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1178,7 +1197,7 @@ void menu_change_sf(void) {
|
|||
struct menu_entry menu[] = {
|
||||
{"Send Now", menu_send_now}, {"Power Off", menu_power_off}, {"Distance +", menu_distance_plus},
|
||||
{"Distance -", menu_distance_minus}, {"Time +", menu_time_plus}, {"Time -", menu_time_minus},
|
||||
{"Change SF", menu_change_sf}, {"Helium ReJoin", menu_flush_prefs}, {"USB GPS", menu_gps_passthrough},
|
||||
{"Change SF", menu_change_sf}, {"Full Reset", menu_flush_prefs}, {"USB GPS", menu_gps_passthrough},
|
||||
{"Deadzone Here", menu_deadzone_here}, {"No Deadzone", menu_no_deadzone}, {"Stay On", menu_stay_on},
|
||||
{"GPS Reset", menu_gps_reset}, {"Experiment", menu_experiment}};
|
||||
#define MENU_ENTRIES (sizeof(menu) / sizeof(menu[0]))
|
||||
|
|
18
main/ttn.cpp
18
main/ttn.cpp
|
@ -105,7 +105,8 @@ void forceTxSingleChannelDr() {
|
|||
ttn_sf(ttn_tx_sf);
|
||||
}
|
||||
|
||||
// DevEUI generator using devices's MAC address - from https://github.com/cyberman54/ESP32-Paxcounter/blob/master/src/lorawan.cpp
|
||||
// DevEUI generator using devices's MAC address - from
|
||||
// https://github.com/cyberman54/ESP32-Paxcounter/blob/master/src/lorawan.cpp
|
||||
void gen_lora_deveui(uint8_t* pdeveui) {
|
||||
uint8_t *p = pdeveui, dmac[6];
|
||||
int i = 0;
|
||||
|
@ -275,7 +276,7 @@ bool ttn_setup() {
|
|||
return (1 == os_init_ex((const void*)&lmic_pins));
|
||||
}
|
||||
|
||||
void ttn_join() {
|
||||
void ttn_join(void) {
|
||||
// Reset the MAC state. Session and pending data transfers will be discarded.
|
||||
LMIC_reset();
|
||||
|
||||
|
@ -382,14 +383,16 @@ void ttn_join() {
|
|||
uint32_t netId = p.getUInt("netId", UINT32_MAX);
|
||||
uint32_t devAddr = p.getUInt("devAddr", UINT32_MAX);
|
||||
uint8_t nwkKey[16], artKey[16];
|
||||
bool keysgood = p.getBytes("nwkKey", nwkKey, sizeof(nwkKey)) == sizeof(nwkKey) && p.getBytes("artKey", artKey, sizeof(artKey)) == sizeof(artKey);
|
||||
bool keysgood = devAddr != UINT32_MAX && netId != UINT32_MAX &&
|
||||
p.getBytes("nwkKey", nwkKey, sizeof(nwkKey)) == sizeof(nwkKey) &&
|
||||
p.getBytes("artKey", artKey, sizeof(artKey)) == sizeof(artKey);
|
||||
p.end(); // close our prefs
|
||||
|
||||
if (!keysgood) {
|
||||
// We have not yet joined a network, start a full join attempt
|
||||
// Make LMiC initialize the default channels, choose a channel, and
|
||||
// schedule the OTAA join
|
||||
Serial.println("No session saved, joining from scratch");
|
||||
Serial.println("Joining from scratch");
|
||||
screen_print("Joining...\n");
|
||||
LMIC_startJoining();
|
||||
} else {
|
||||
|
@ -454,9 +457,10 @@ void ttn_write_prefs() {
|
|||
static void ttn_set_cnt() {
|
||||
LMIC_setSeqnoUp(count);
|
||||
|
||||
// We occasionally mirror our count to flash, to ensure that if we lose power we will at least start with a count that is almost correct
|
||||
// (otherwise the TNN network will discard packets until count once again reaches the value they've seen). We limit these writes to a max rate
|
||||
// of one write every 5 minutes. Which should let the FLASH last for 300 years (given the ESP32 NVS algoritm)
|
||||
// We occasionally mirror our count to flash, to ensure that if we lose power we will at least start with a count that
|
||||
// is almost correct (otherwise the TNN network will discard packets until count once again reaches the value they've
|
||||
// seen). We limit these writes to a max rate of one write every 5 minutes. Which should let the FLASH last for 300
|
||||
// years (given the ESP32 NVS algoritm)
|
||||
static uint32_t lastWriteMsec = UINT32_MAX; // Ensure we write at least once
|
||||
uint32_t now = millis();
|
||||
if (now < lastWriteMsec || (now - lastWriteMsec) > 5 * 60 * 1000L) { // write if we roll over (50 days) or 5 mins
|
||||
|
|
Ładowanie…
Reference in New Issue