kopia lustrzana https://github.com/Max-Plastix/tbeam-helium-mapper
Added Deadzone Circule & fix lowbattery button
rodzic
458fb124e3
commit
2f37443562
|
@ -53,7 +53,7 @@ BreakConstructorInitializersBeforeComma: false
|
||||||
BreakConstructorInitializers: BeforeColon
|
BreakConstructorInitializers: BeforeColon
|
||||||
BreakAfterJavaFieldAnnotations: false
|
BreakAfterJavaFieldAnnotations: false
|
||||||
BreakStringLiterals: true
|
BreakStringLiterals: true
|
||||||
ColumnLimit: 160
|
ColumnLimit: 120
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
CompactNamespaces: false
|
CompactNamespaces: false
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
136
main/main.cpp
136
main/main.cpp
|
@ -5,24 +5,30 @@
|
||||||
This is a development fork by Max-Plastix hosted here:
|
This is a development fork by Max-Plastix hosted here:
|
||||||
https://github.com/Max-Plastix/tbeam-helium-mapper/
|
https://github.com/Max-Plastix/tbeam-helium-mapper/
|
||||||
|
|
||||||
This code comes from a number of developers and earlier efforts, visible in the lineage on Github and prior comments below.
|
This code comes from a number of developers and earlier efforts, visible in the
|
||||||
GPL makes this all possible -- continue to modify, extend, and share!
|
lineage on Github and prior comments below. GPL makes this all possible --
|
||||||
|
continue to modify, extend, and share!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This module and those attached with it have been modified for the Helium Network by Fizzy. The following has been changed from the original modifications for
|
This module and those attached with it have been modified for the Helium
|
||||||
Helium, by longfi-arduino:
|
Network by Fizzy. The following has been changed from the original
|
||||||
|
modifications for Helium, by longfi-arduino:
|
||||||
- Added Helium Startup Logo
|
- Added Helium Startup Logo
|
||||||
- Changed App Name and Version of device to reflect more of a device name and number scheme.
|
- Changed App Name and Version of device to reflect more of a device name and
|
||||||
- Enabled long press middle button to Discard Prefs by default for future troubleshooting on device.
|
number scheme.
|
||||||
- Changed Text output to reflect Helium, and not TTL (Code referances ttn, just to prevent brakes in this awesome code)
|
- Enabled long press middle button to Discard Prefs by default for future
|
||||||
|
troubleshooting on device.
|
||||||
|
- Changed Text output to reflect Helium, and not TTL (Code referances ttn,
|
||||||
|
just to prevent brakes in this awesome code)
|
||||||
- Changed credentials file to use OTAA by default.
|
- Changed credentials file to use OTAA by default.
|
||||||
- Changed GPS metric output text "Error", to "Accuracy/HDOP".
|
- Changed GPS metric output text "Error", to "Accuracy/HDOP".
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
Main module
|
Main module
|
||||||
|
|
||||||
# Modified by Kyle T. Gabriel to fix issue with incorrect GPS data for TTNMapper
|
# Modified by Kyle T. Gabriel to fix issue with incorrect GPS data for
|
||||||
|
TTNMapper
|
||||||
|
|
||||||
Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
|
Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
|
||||||
|
|
||||||
|
@ -41,10 +47,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <Preferences.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <axp20x.h>
|
#include <axp20x.h>
|
||||||
#include <lmic.h>
|
#include <lmic.h>
|
||||||
#include <Preferences.h>
|
|
||||||
|
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "gps.h"
|
#include "gps.h"
|
||||||
|
@ -62,6 +68,12 @@ float last_send_lat = 0;
|
||||||
float last_send_lon = 0;
|
float last_send_lon = 0;
|
||||||
float dist_moved = 0;
|
float dist_moved = 0;
|
||||||
|
|
||||||
|
// Deadzone (no uplink) location and radius
|
||||||
|
float deadzone_lat = DEADZONE_LAT;
|
||||||
|
float deadzone_lon = DEADZONE_LON;
|
||||||
|
float deadzone_radius_m = DEADZONE_RADIUS_M;
|
||||||
|
boolean in_deadzone = false;
|
||||||
|
|
||||||
/* Defaults that can be overwritten by downlink messages */
|
/* Defaults that can be overwritten by downlink messages */
|
||||||
/* 32-bit int seconds is 50 days maximum */
|
/* 32-bit int seconds is 50 days maximum */
|
||||||
unsigned int rest_wait_s; // prefs REST_WAIT
|
unsigned int rest_wait_s; // prefs REST_WAIT
|
||||||
|
@ -145,12 +157,12 @@ bool trySend() {
|
||||||
unsigned long int now_millis = millis();
|
unsigned long int now_millis = millis();
|
||||||
|
|
||||||
// Here we try to filter out bogus GPS readings.
|
// Here we try to filter out bogus GPS readings.
|
||||||
// It's not correct, and there should be a better indication from GPS that the fix is invalid
|
// It's not correct, and there should be a better indication from GPS that the
|
||||||
|
// fix is invalid
|
||||||
if (gps_hdop() <= 0 || gps_hdop() > 50 || now_lat == 0.0 // Not fair to the whole equator
|
if (gps_hdop() <= 0 || gps_hdop() > 50 || now_lat == 0.0 // Not fair to the whole equator
|
||||||
|| now_lat > 90.0 || now_lat < -90.0 || now_long == 0.0 // Not fair to King George
|
|| now_lat > 90.0 || now_lat < -90.0 || now_long == 0.0 // Not fair to King George
|
||||||
|| now_long < -180.0 || now_long > 180.0 || gps_altitude() == 0.0 // Not fair to the ocean
|
|| now_long < -180.0 || now_long > 180.0 || gps_altitude() == 0.0 // Not fair to the ocean
|
||||||
|| gps_sats() < 4
|
|| gps_sats() < 4)
|
||||||
)
|
|
||||||
return false; // Rejected as bogus GPS reading.
|
return false; // Rejected as bogus GPS reading.
|
||||||
|
|
||||||
// Don't attempt to send or update until we join Helium
|
// Don't attempt to send or update until we join Helium
|
||||||
|
@ -167,15 +179,17 @@ bool trySend() {
|
||||||
|
|
||||||
// distance from last transmitted location
|
// distance from last transmitted location
|
||||||
float dist_moved = gps_distanceBetween(last_send_lat, last_send_lon, now_lat, now_long);
|
float dist_moved = gps_distanceBetween(last_send_lat, last_send_lon, now_lat, now_long);
|
||||||
|
float deadzone_dist = gps_distanceBetween(deadzone_lat, deadzone_lon, now_lat, now_long);
|
||||||
|
in_deadzone = (deadzone_dist <= deadzone_radius_m);
|
||||||
|
|
||||||
#if 0
|
/*
|
||||||
snprintf(buffer, sizeof(buffer), "Lat: %10.6f\n", gps_latitude());
|
Serial.printf("[Time %lu / %us, Moved %dm in %lus %c]\n", (now_millis - last_send_millis) / 1000, tx_interval_s, (int32_t)dist_moved,
|
||||||
screen_print(buffer);
|
(now_millis - last_moved_millis) / 1000, in_deadzone ? 'D' : '-');
|
||||||
snprintf(buffer, sizeof(buffer), "Long: %10.6f\n", gps_longitude());
|
*/
|
||||||
screen_print(buffer);
|
|
||||||
snprintf(buffer, sizeof(buffer), "HDOP: %4.2fm\n", gps_hdop());
|
// Deadzone means we don't send unless asked
|
||||||
screen_print(buffer);
|
if (in_deadzone && !justSendNow)
|
||||||
#endif
|
return false;
|
||||||
|
|
||||||
char because = '?';
|
char because = '?';
|
||||||
if (justSendNow) {
|
if (justSendNow) {
|
||||||
|
@ -196,7 +210,8 @@ bool trySend() {
|
||||||
// SEND a Packet!
|
// SEND a Packet!
|
||||||
// digitalWrite(RED_LED, LOW);
|
// digitalWrite(RED_LED, LOW);
|
||||||
|
|
||||||
// The first distance-moved is crazy, since has no origin.. don't put it on screen.
|
// The first distance-moved is crazy, since has no origin.. don't put it on
|
||||||
|
// screen.
|
||||||
if (dist_moved > 1000000)
|
if (dist_moved > 1000000)
|
||||||
dist_moved = 0;
|
dist_moved = 0;
|
||||||
|
|
||||||
|
@ -262,8 +277,7 @@ void mapper_restore_prefs(void) {
|
||||||
tx_interval_s = stationary_tx_interval_s;
|
tx_interval_s = stationary_tx_interval_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapper_save_prefs (void)
|
void mapper_save_prefs(void) {
|
||||||
{
|
|
||||||
Preferences p;
|
Preferences p;
|
||||||
|
|
||||||
Serial.println("Saving prefs.");
|
Serial.println("Saving prefs.");
|
||||||
|
@ -277,8 +291,7 @@ void mapper_save_prefs (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapper_erase_prefs (void)
|
void mapper_erase_prefs(void) {
|
||||||
{
|
|
||||||
#if 0
|
#if 0
|
||||||
nvs_flash_erase(); // erase the NVS partition and...
|
nvs_flash_erase(); // erase the NVS partition and...
|
||||||
nvs_flash_init(); // initialize the NVS partition.
|
nvs_flash_init(); // initialize the NVS partition.
|
||||||
|
@ -381,7 +394,8 @@ void lora_msg_callback(uint8_t message) {
|
||||||
screen_print("+\v");
|
screen_print("+\v");
|
||||||
screen_update();
|
screen_update();
|
||||||
}
|
}
|
||||||
// We only want to say 'packetSent' for our packets (not packets needed for joining)
|
// We only want to say 'packetSent' for our packets (not packets needed for
|
||||||
|
// joining)
|
||||||
if (EV_TXCOMPLETE == message && packetQueued) {
|
if (EV_TXCOMPLETE == message && packetQueued) {
|
||||||
// screen_print("sent.\n");
|
// screen_print("sent.\n");
|
||||||
packetQueued = false;
|
packetQueued = false;
|
||||||
|
@ -416,8 +430,9 @@ void lora_msg_callback(uint8_t message) {
|
||||||
/*
|
/*
|
||||||
* Downlink format: FPort 1
|
* Downlink format: FPort 1
|
||||||
* 2 Bytes: Minimum Distance (1 to 65535) meters, or 0 no-change
|
* 2 Bytes: Minimum Distance (1 to 65535) meters, or 0 no-change
|
||||||
* 2 Bytes: Minimum Time (1 to 65535) seconds (18.2 hours) between pings, or 0 no-change, or 0xFFFF to use default
|
* 2 Bytes: Minimum Time (1 to 65535) seconds (18.2 hours) between pings, or
|
||||||
* 1 Byte: Battery voltage (2.0 to 4.5) for auto-shutoff, or 0 no-change
|
* 0 no-change, or 0xFFFF to use default 1 Byte: Battery voltage (2.0
|
||||||
|
* to 4.5) for auto-shutoff, or 0 no-change
|
||||||
*/
|
*/
|
||||||
if (port == 1 && len == 5) {
|
if (port == 1 && len == 5) {
|
||||||
float new_distance = (float)(data[0] << 8 | data[1]);
|
float new_distance = (float)(data[0] << 8 | data[1]);
|
||||||
|
@ -489,13 +504,12 @@ void scanI2Cdevice(void) {
|
||||||
Init the power manager chip
|
Init the power manager chip
|
||||||
|
|
||||||
axp192 power
|
axp192 power
|
||||||
DCDC1 0.7-3.5V @ 1200mA max -> OLED // If you turn this off you'll lose comms to the axp192 because the OLED and the axp192 share the same i2c bus
|
DCDC1 0.7-3.5V @ 1200mA max -> OLED // If you turn this off you'll lose comms
|
||||||
use ssd1306 sleep mode instead
|
to the axp192 because the OLED and the axp192 share the same i2c bus use
|
||||||
DCDC2 -> unused
|
ssd1306 sleep mode instead DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32
|
||||||
DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!)
|
(keep this on!) LDO1 30mA -> "VCC_RTC" charges GPS backup battery // charges
|
||||||
LDO1 30mA -> "VCC_RTC" charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can not be turned off
|
the tiny J13 battery by the GPS to power the GPS ram (for a couple of days),
|
||||||
LDO2 200mA -> "LORA_VCC"
|
can not be turned off LDO2 200mA -> "LORA_VCC" LDO3 200mA -> "GPS_VCC"
|
||||||
LDO3 200mA -> "GPS_VCC"
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void axp192Init() {
|
void axp192Init() {
|
||||||
|
@ -514,7 +528,8 @@ void axp192Init() {
|
||||||
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); // OLED power
|
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); // OLED power
|
||||||
axp.setDCDC1Voltage(3300); // for the OLED power
|
axp.setDCDC1Voltage(3300); // for the OLED power
|
||||||
axp.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); // Unconnected
|
axp.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); // Unconnected
|
||||||
axp.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); // "EXTEN" pin, normally unused
|
axp.setPowerOutPut(AXP192_EXTEN,
|
||||||
|
AXP202_OFF); // "EXTEN" pin, normally unused
|
||||||
|
|
||||||
// Flash the Blue LED until our first packet is transmitted
|
// Flash the Blue LED until our first packet is transmitted
|
||||||
axp.setChgLEDMode(AXP20X_LED_BLINK_4HZ);
|
axp.setChgLEDMode(AXP20X_LED_BLINK_4HZ);
|
||||||
|
@ -531,13 +546,16 @@ void axp192Init() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pinMode(PMU_IRQ, INPUT_PULLUP);
|
pinMode(PMU_IRQ, INPUT_PULLUP);
|
||||||
attachInterrupt(PMU_IRQ, [] { pmu_irq = true; }, FALLING);
|
attachInterrupt(
|
||||||
|
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
|
||||||
|
|
||||||
// Configure REG 36H: PEK press key parameter set. Index values for argument!
|
// Configure REG 36H: PEK press key parameter set. Index values for
|
||||||
|
// argument!
|
||||||
axp.setStartupTime(2); // "Power on time": 512mS
|
axp.setStartupTime(2); // "Power on time": 512mS
|
||||||
axp.setlongPressTime(2); // "Long time key press time": 2S
|
axp.setlongPressTime(2); // "Long time key press time": 2S
|
||||||
axp.setShutdownTime(2); // "Power off time" = 8S
|
axp.setShutdownTime(2); // "Power off time" = 8S
|
||||||
axp.setTimeOutShutdown(1); // "When key press time is longer than power off time, auto power off"
|
axp.setTimeOutShutdown(1); // "When key press time is longer than power off
|
||||||
|
// time, auto power off"
|
||||||
|
|
||||||
// Serial.printf("AC IN: %fv\n", axp.getAcinVoltage());
|
// Serial.printf("AC IN: %fv\n", axp.getAcinVoltage());
|
||||||
// Serial.printf("Vbus: %fv\n", axp.getVbusVoltage());
|
// Serial.printf("Vbus: %fv\n", axp.getVbusVoltage());
|
||||||
|
@ -567,8 +585,14 @@ void axp192Init() {
|
||||||
|
|
||||||
// Enable battery current measurements
|
// Enable battery current measurements
|
||||||
axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1);
|
axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1);
|
||||||
// axp.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ, 1);
|
// axp.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ |
|
||||||
|
// AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ, 1);
|
||||||
axp.enableIRQ(0xFFFFFFFFFF, 1); // Give me ALL the interrupts you have.
|
axp.enableIRQ(0xFFFFFFFFFF, 1); // Give me ALL the interrupts you have.
|
||||||
|
|
||||||
|
// @Kenny_PDY discovered that low-battery voltage inhibits detecting the menu button.
|
||||||
|
// I don't know why, but might be a persistent interrupt that blocks the button?
|
||||||
|
axp.enableIRQ(APX202_APS_LOW_VOL_LEVEL1_IRQ | AXP202_APS_LOW_VOL_LEVEL2_IRQ, 0);
|
||||||
|
|
||||||
axp.clearIRQ();
|
axp.clearIRQ();
|
||||||
} else {
|
} else {
|
||||||
Serial.println("AXP192 not found!");
|
Serial.println("AXP192 not found!");
|
||||||
|
@ -582,9 +606,11 @@ void wakeup() {
|
||||||
/*
|
/*
|
||||||
Not using yet because we are using wake on all buttons being low
|
Not using yet because we are using wake on all buttons being low
|
||||||
|
|
||||||
wakeButtons = esp_sleep_get_ext1_wakeup_status(); // If one of these buttons is set it was the reason we woke
|
wakeButtons = esp_sleep_get_ext1_wakeup_status(); // If one of these
|
||||||
if (wakeCause == ESP_SLEEP_WAKEUP_EXT1 && !wakeButtons) // we must have been using the 'all buttons rule for waking' to support busted boards, assume button
|
buttons is set it was the reason we woke if (wakeCause ==
|
||||||
one was pressed wakeButtons = ((uint64_t)1) << buttons.gpios[0];
|
ESP_SLEEP_WAKEUP_EXT1 && !wakeButtons) // we must have been using the 'all
|
||||||
|
buttons rule for waking' to support busted boards, assume button one was
|
||||||
|
pressed wakeButtons = ((uint64_t)1) << buttons.gpios[0];
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Serial.printf("BOOT #%d! cause:%d ext1:%08llx\n", bootCount, wakeCause, esp_sleep_get_ext1_wakeup_status());
|
Serial.printf("BOOT #%d! cause:%d ext1:%08llx\n", bootCount, wakeCause, esp_sleep_get_ext1_wakeup_status());
|
||||||
|
@ -602,8 +628,9 @@ void setup() {
|
||||||
|
|
||||||
axp192Init();
|
axp192Init();
|
||||||
|
|
||||||
// GPS sometimes gets wedged with no satellites in view and only a power-cycle saves it.
|
// GPS sometimes gets wedged with no satellites in view and only a power-cycle
|
||||||
// Here we turn off power and the delay in screen setup is enough time to bonk the GPS
|
// saves it. Here we turn off power and the delay in screen setup is enough
|
||||||
|
// time to bonk the GPS
|
||||||
axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // GPS power off
|
axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // GPS power off
|
||||||
|
|
||||||
// Buttons & LED
|
// Buttons & LED
|
||||||
|
@ -616,14 +643,16 @@ void setup() {
|
||||||
|
|
||||||
mapper_restore_prefs(); // Fetch saved settings
|
mapper_restore_prefs(); // Fetch saved settings
|
||||||
|
|
||||||
// Don't init display if we don't have one or we are waking headless due to a timer event
|
// Don't init display if we don't have one or we are waking headless due to a
|
||||||
|
// timer event
|
||||||
if (0 && wakeCause == ESP_SLEEP_WAKEUP_TIMER)
|
if (0 && wakeCause == ESP_SLEEP_WAKEUP_TIMER)
|
||||||
ssd1306_found = false; // forget we even have the hardware
|
ssd1306_found = false; // forget we even have the hardware
|
||||||
|
|
||||||
if (ssd1306_found)
|
if (ssd1306_found)
|
||||||
screen_setup();
|
screen_setup();
|
||||||
|
|
||||||
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS power on, so it has time to setttle.
|
// GPS power on, so it has time to setttle.
|
||||||
|
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
|
||||||
|
|
||||||
// Show logo on first boot after removing battery
|
// Show logo on first boot after removing battery
|
||||||
#ifndef ALWAYS_SHOW_LOGO
|
#ifndef ALWAYS_SHOW_LOGO
|
||||||
|
@ -654,7 +683,6 @@ void setup() {
|
||||||
|
|
||||||
// Might have to add a longer delay here
|
// Might have to add a longer delay here
|
||||||
gps_setup(); // Init GPS baudrate and messages
|
gps_setup(); // Init GPS baudrate and messages
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Power OFF -- does not return
|
// Power OFF -- does not return
|
||||||
|
@ -772,7 +800,6 @@ const char *find_irq_name(void) {
|
||||||
return irq_name;
|
return irq_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct menu_entry {
|
struct menu_entry {
|
||||||
const char *name;
|
const char *name;
|
||||||
void (*func)(void);
|
void (*func)(void);
|
||||||
|
@ -820,9 +847,14 @@ void menu_experiment(void){
|
||||||
|
|
||||||
Serial.printf("%f mA %f mW\n", axp.getBattChargeCurrent() - axp.getBattDischargeCurrent(), axp.getBattInpower());
|
Serial.printf("%f mA %f mW\n", axp.getBattChargeCurrent() - axp.getBattDischargeCurrent(), axp.getBattInpower());
|
||||||
|
|
||||||
axp.setPowerOutPut(AXP192_LDO3, power_toggle ? AXP202_ON : AXP202_OFF); // GPS main power
|
axp.setPowerOutPut(AXP192_LDO3,
|
||||||
|
power_toggle ? AXP202_ON : AXP202_OFF); // GPS main power
|
||||||
power_toggle = !power_toggle;
|
power_toggle = !power_toggle;
|
||||||
}
|
}
|
||||||
|
void menu_deadzone_here(void) {
|
||||||
|
deadzone_lat = gps_latitude();
|
||||||
|
deadzone_lon = gps_longitude();
|
||||||
|
}
|
||||||
|
|
||||||
dr_t sf_list[] = {DR_SF7, DR_SF8, DR_SF9, DR_SF10};
|
dr_t sf_list[] = {DR_SF7, DR_SF8, DR_SF9, DR_SF10};
|
||||||
#define SF_ENTRIES (sizeof(sf_list) / sizeof(sf_list[0]))
|
#define SF_ENTRIES (sizeof(sf_list) / sizeof(sf_list[0]))
|
||||||
|
@ -842,7 +874,7 @@ void menu_change_sf(void) {
|
||||||
struct menu_entry menu[] = {{"Send Now", menu_send_now}, {"Power Off", menu_power_off}, {"Distance +", menu_distance_plus},
|
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},
|
{"Distance -", menu_distance_minus}, {"Time +", menu_time_plus}, {"Time -", menu_time_minus},
|
||||||
{"Change SF", menu_change_sf}, {"Flush Prefs", menu_flush_prefs}, {"USB GPS", menu_gps_passthrough},
|
{"Change SF", menu_change_sf}, {"Flush Prefs", menu_flush_prefs}, {"USB GPS", menu_gps_passthrough},
|
||||||
{"Danger", menu_experiment}};
|
{"Deadzone Here", menu_deadzone_here}, {"Danger", menu_experiment}};
|
||||||
#define MENU_ENTRIES (sizeof(menu) / sizeof(menu[0]))
|
#define MENU_ENTRIES (sizeof(menu) / sizeof(menu[0]))
|
||||||
|
|
||||||
const char *menu_prev;
|
const char *menu_prev;
|
||||||
|
@ -878,7 +910,7 @@ void loop() {
|
||||||
if (in_menu && millis() - menu_idle_start > (5 * 1000))
|
if (in_menu && millis() - menu_idle_start > (5 * 1000))
|
||||||
in_menu = false;
|
in_menu = false;
|
||||||
|
|
||||||
screen_loop(tx_interval_s, min_dist_moved, sf_name, gps_sats(), in_menu, menu_prev, menu_cur, menu_next, is_highlighted);
|
screen_loop(tx_interval_s, min_dist_moved, sf_name, gps_sats(), in_menu, menu_prev, menu_cur, menu_next, is_highlighted, in_deadzone);
|
||||||
|
|
||||||
update_activity();
|
update_activity();
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,8 @@ void screen_setup() {
|
||||||
#include <axp20x.h>
|
#include <axp20x.h>
|
||||||
extern AXP20X_Class axp; // TODO: This is evil
|
extern AXP20X_Class axp; // TODO: This is evil
|
||||||
|
|
||||||
void screen_header(unsigned int tx_interval_s, float min_dist_moved, char *cached_sf_name, int sats) {
|
void screen_header(unsigned int tx_interval_s, float min_dist_moved, char *cached_sf_name, int sats,
|
||||||
|
boolean in_deadzone) {
|
||||||
if (!display)
|
if (!display)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -126,7 +127,8 @@ void screen_header(unsigned int tx_interval_s, float min_dist_moved, char *cache
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
display->drawString(0, 2, buffer);
|
display->drawString(0, 2, buffer);
|
||||||
|
|
||||||
snprintf(buffer, sizeof(buffer), "%.2fV %.0fmA", axp.getBattVoltage() / 1000, axp.getBattChargeCurrent() - axp.getBattDischargeCurrent());
|
snprintf(buffer, sizeof(buffer), "%.2fV %.0fmA", axp.getBattVoltage() / 1000,
|
||||||
|
axp.getBattChargeCurrent() - axp.getBattDischargeCurrent());
|
||||||
} else {
|
} else {
|
||||||
// Message count and time
|
// Message count and time
|
||||||
// snprintf(buffer, sizeof(buffer), "%4d", ttn_get_count() % 10000);
|
// snprintf(buffer, sizeof(buffer), "%4d", ttn_get_count() % 10000);
|
||||||
|
@ -145,10 +147,11 @@ void screen_header(unsigned int tx_interval_s, float min_dist_moved, char *cache
|
||||||
// Satellite count
|
// Satellite count
|
||||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||||
display->drawString(display->getWidth() - SATELLITE_IMAGE_WIDTH - 4, 2, itoa(sats, buffer, 10));
|
display->drawString(display->getWidth() - SATELLITE_IMAGE_WIDTH - 4, 2, itoa(sats, buffer, 10));
|
||||||
display->drawXbm(display->getWidth() - SATELLITE_IMAGE_WIDTH, 0, SATELLITE_IMAGE_WIDTH, SATELLITE_IMAGE_HEIGHT, SATELLITE_IMAGE);
|
display->drawXbm(display->getWidth() - SATELLITE_IMAGE_WIDTH, 0, SATELLITE_IMAGE_WIDTH, SATELLITE_IMAGE_HEIGHT,
|
||||||
|
SATELLITE_IMAGE);
|
||||||
|
|
||||||
// Second status row:
|
// Second status row:
|
||||||
snprintf(buffer, sizeof(buffer), "%us %.0fm", tx_interval_s, min_dist_moved);
|
snprintf(buffer, sizeof(buffer), "%us %.0fm %c", tx_interval_s, min_dist_moved, in_deadzone ? 'D' : ' ');
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
display->drawString(0, 12, buffer);
|
display->drawString(0, 12, buffer);
|
||||||
|
|
||||||
|
@ -159,13 +162,14 @@ void screen_header(unsigned int tx_interval_s, float min_dist_moved, char *cache
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MARGIN 15
|
#define MARGIN 15
|
||||||
void screen_loop(unsigned int tx_interval_s, float min_dist_moved, char *cached_sf_name, int sats, boolean in_menu, const char *menu_prev,
|
void screen_loop(unsigned int tx_interval_s, float min_dist_moved, char *cached_sf_name, int sats, boolean in_menu,
|
||||||
const char *menu_cur, const char *menu_next, boolean highlighted) {
|
const char *menu_prev, const char *menu_cur, const char *menu_next, boolean highlighted,
|
||||||
|
boolean in_deadzone) {
|
||||||
if (!display)
|
if (!display)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
display->clear();
|
display->clear();
|
||||||
screen_header(tx_interval_s, min_dist_moved, cached_sf_name, sats);
|
screen_header(tx_interval_s, min_dist_moved, cached_sf_name, sats, in_deadzone);
|
||||||
|
|
||||||
if (in_menu) {
|
if (in_menu) {
|
||||||
char buffer[40];
|
char buffer[40];
|
||||||
|
|
|
@ -8,7 +8,7 @@ void screen_print(const char *text, uint8_t x, uint8_t y, uint8_t alignment);
|
||||||
|
|
||||||
void screen_update(void);
|
void screen_update(void);
|
||||||
void screen_loop(unsigned int tx_interval_ms, float min_dist_moved, char *cached_sf_name, int sats, boolean in_menu, const char *menu_prev,
|
void screen_loop(unsigned int tx_interval_ms, float min_dist_moved, char *cached_sf_name, int sats, boolean in_menu, const char *menu_prev,
|
||||||
const char *menu_cur, const char *menu_next, boolean highlighted);
|
const char *menu_cur, const char *menu_next, boolean highlighted, boolean in_deadzone);
|
||||||
void screen_off(void);
|
void screen_off(void);
|
||||||
void screen_on(void);
|
void screen_on(void);
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue