Compare commits

..

10 Commits

Author SHA1 Message Date
Ben Meadors
10265aabd5 Fix buggy phone positions (#2876)
* Guard-clause channel util. to reduce nesting

* Try-fix PhoneAPI position not updating

* Trunk

* Missed it

* Really disable GPS when asked to

---------

Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2023-10-09 18:33:04 -05:00
Jonathan Bennett
8780d93941 Remove missed GPS definition (#2878) 2023-10-09 13:30:51 -05:00
Sacha Weatherstone
54f0c045e4 Update README.md 2023-10-09 22:30:02 +10:00
github-actions[bot]
3ddad671a5 [create-pull-request] automated change (#2875)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-10-08 08:12:42 -05:00
pat-trunk-io
dc6f0b8e0b mention trunk is beta on windows (#2871)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-06 15:31:04 -05:00
pat-trunk-io
33f28c3d56 Add trunk githooks to the repo (#2870) 2023-10-06 15:02:27 -05:00
github-actions[bot]
ef1d8c8eee [create-pull-request] automated change (#2869) 2023-10-05 17:51:23 -05:00
Ben Meadors
950d5f0946 Power saving sensor (#2865)
* Trunk

* Again

* This thing just keeps updating itself

* Ignore tools

* Sleepy sensor

* Batrunkadunk
2023-10-05 12:42:03 -05:00
Thomas Göttgens
fc06754e1f Possibly fix #2704 "Heltec Wireless Tracker screen doesn't display anything" (#2749)
* fix #2704


Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2023-10-04 22:24:25 -05:00
github-actions[bot]
fbf74fc0b2 [create-pull-request] automated change (#2863)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-10-04 10:23:55 -05:00
20 changed files with 279 additions and 87 deletions

View File

@@ -7,7 +7,7 @@
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc... is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
- Please do not check in files that don't have real changes - Please do not check in files that don't have real changes
- Please do not reformat lines that you didn't have to change the code on - Please do not reformat lines that you didn't have to change the code on
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (WSL2 is required on windows), - We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (In beta for windows, WSL2 for the linux version),
because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines. because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description. - If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
- If your other co-developers have comments on your PR please tweak as needed. - If your other co-developers have comments on your PR please tweak as needed.

2
.trunk/.gitignore vendored
View File

@@ -2,7 +2,7 @@
*logs *logs
*actions *actions
*notifications *notifications
*tools
plugins plugins
user_trunk.yaml user_trunk.yaml
user.yaml user.yaml
tools

View File

@@ -1,53 +1,53 @@
version: 0.1 version: 0.1
cli: cli:
version: 1.13.0 version: 1.16.2
plugins: plugins:
sources: sources:
- id: trunk - id: trunk
ref: v1.1.1 ref: v1.2.5
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- bandit@1.7.5 - bandit@1.7.5
- checkov@2.4.1 - checkov@2.5.0
- terrascan@1.18.3 - terrascan@1.18.3
- trivy@0.44.1 - trivy@0.45.1
- trufflehog@3.48.0 - trufflehog@3.59.0
- taplo@0.8.1 - taplo@0.8.1
- ruff@0.0.284 - ruff@0.0.292
- yamllint@1.32.0 - yamllint@1.32.0
- isort@5.12.0 - isort@5.12.0
- markdownlint@0.35.0 - markdownlint@0.37.0
- oxipng@8.0.0 - oxipng@8.0.0
- svgo@3.0.2 - svgo@3.0.2
- actionlint@1.6.25 - actionlint@1.6.26
- flake8@6.1.0 - flake8@6.1.0
- hadolint@2.12.0 - hadolint@2.12.0
- shfmt@3.6.0 - shfmt@3.6.0
- shellcheck@0.9.0 - shellcheck@0.9.0
- black@23.7.0 - black@23.9.1
- git-diff-check - git-diff-check
- gitleaks@8.17.0 - gitleaks@8.18.0
- clang-format@16.0.3 - clang-format@16.0.3
- prettier@3.0.2 - prettier@3.0.3
disabled: disabled:
- taplo@0.8.1 - taplo@0.8.1
- shellcheck@0.9.0 - shellcheck@0.9.0
- shfmt@3.6.0 - shfmt@3.6.0
- oxipng@8.0.0 - oxipng@8.0.0
- actionlint@1.6.22 - actionlint@1.6.22
- markdownlint@0.35.0 - markdownlint@0.37.0
- hadolint@2.12.0 - hadolint@2.12.0
- svgo@3.0.2 - svgo@3.0.2
runtimes: runtimes:
enabled: enabled:
- python@3.10.8 - python@3.10.8
- go@1.19.5 - go@1.21.0
- node@18.12.1 - node@18.12.1
actions: actions:
disabled: disabled:
- trunk-announce - trunk-announce
- trunk-check-pre-push
- trunk-fmt-pre-commit
enabled: enabled:
- trunk-fmt-pre-commit
- trunk-check-pre-push
- trunk-upgrade-available - trunk-upgrade-available

View File

@@ -10,8 +10,8 @@
This repository contains the device firmware for the Meshtastic project. This repository contains the device firmware for the Meshtastic project.
**[Building Instructions](https://meshtastic.org/docs/development/firmware/build)** - **[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)** - **[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
## Stats ## Stats

View File

@@ -175,9 +175,21 @@ class AnalogBatteryLevel : public HasBatteryLevel
uint32_t raw = 0; uint32_t raw = 0;
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#ifndef BAT_MEASURE_ADC_UNIT // ADC1 #ifndef BAT_MEASURE_ADC_UNIT // ADC1
#ifdef ADC_CTRL
if (heltec_version == 5) {
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, HIGH);
delay(10);
}
#endif
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) { for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
raw += adc1_get_raw(adc_channel); raw += adc1_get_raw(adc_channel);
} }
#ifdef ADC_CTRL
if (heltec_version == 5) {
digitalWrite(ADC_CTRL, LOW);
}
#endif
#else // ADC2 #else // ADC2
int32_t adc_buf = 0; int32_t adc_buf = 0;
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) { for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {

View File

@@ -611,7 +611,7 @@ int32_t GPS::runOnce()
return 2000; // Setup failed, re-run in two seconds return 2000; // Setup failed, re-run in two seconds
// We have now loaded our saved preferences from flash // We have now loaded our saved preferences from flash
if (config.position.gps_enabled == false && config.position.fixed_position == false) { if (config.position.gps_enabled == false) {
return disable(); return disable();
} }
// ONCE we will factory reset the GPS for bug #327 // ONCE we will factory reset the GPS for bug #327
@@ -703,8 +703,8 @@ int32_t GPS::runOnce()
// If state has changed do a publish // If state has changed do a publish
publishUpdate(); publishUpdate();
if (config.position.gps_enabled == false) // This should trigger if GPS is disabled but fixed_position is true if (config.position.fixed_position == true && hasValidLocation)
return disable(); return disable(); // This should trigger when we have a fixed position, and get that first position
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms // 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake. // if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.

View File

@@ -1,4 +1,5 @@
#include "configuration.h" #include "configuration.h"
#include "main.h"
#ifndef TFT_BACKLIGHT_ON #ifndef TFT_BACKLIGHT_ON
#define TFT_BACKLIGHT_ON HIGH #define TFT_BACKLIGHT_ON HIGH
@@ -81,8 +82,16 @@ class LGFX : public lgfx::LGFX_Device
{ {
auto cfg = _light_instance.config(); // Gets a structure for backlight settings. auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
#ifdef ST7735_BL_V03
if (heltec_version == 3) {
cfg.pin_bl = ST7735_BL_V03;
} else {
cfg.pin_bl = ST7735_BL_V05;
}
#else
cfg.pin_bl = ST7735_BL; // Pin number to which the backlight is connected cfg.pin_bl = ST7735_BL; // Pin number to which the backlight is connected
cfg.invert = true; // true to invert the brightness of the backlight #endif
cfg.invert = true; // true to invert the brightness of the backlight
// cfg.freq = 44100; // PWM frequency of backlight // cfg.freq = 44100; // PWM frequency of backlight
// cfg.pwm_channel = 1; // PWM channel number to use // cfg.pwm_channel = 1; // PWM channel number to use
@@ -364,9 +373,23 @@ void TFTDisplay::sendCommand(uint8_t com)
// handle display on/off directly // handle display on/off directly
switch (com) { switch (com) {
case DISPLAYON: { case DISPLAYON: {
#if defined(ST7735_BACKLIGHT_EN_V03) && defined(TFT_BACKLIGHT_ON)
if (heltec_version == 3) {
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
} else {
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
}
#endif
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON) #if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON); digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
#endif #endif
#ifdef VTFT_CTRL_V03
if (heltec_version == 3) {
digitalWrite(VTFT_CTRL_V03, LOW);
} else {
digitalWrite(VTFT_CTRL_V05, LOW);
}
#endif
#ifdef VTFT_CTRL #ifdef VTFT_CTRL
digitalWrite(VTFT_CTRL, LOW); digitalWrite(VTFT_CTRL, LOW);
#endif #endif
@@ -376,9 +399,23 @@ void TFTDisplay::sendCommand(uint8_t com)
break; break;
} }
case DISPLAYOFF: { case DISPLAYOFF: {
#if defined(ST7735_BACKLIGHT_EN_V03) && defined(TFT_BACKLIGHT_ON)
if (heltec_version == 3) {
digitalWrite(ST7735_BACKLIGHT_EN_V03, !TFT_BACKLIGHT_ON);
} else {
digitalWrite(ST7735_BACKLIGHT_EN_V05, !TFT_BACKLIGHT_ON);
}
#endif
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON) #if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON); digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON);
#endif #endif
#ifdef VTFT_CTRL_V03
if (heltec_version == 3) {
digitalWrite(VTFT_CTRL_V03, HIGH);
} else {
digitalWrite(VTFT_CTRL_V05, HIGH);
}
#endif
#ifdef VTFT_CTRL #ifdef VTFT_CTRL
digitalWrite(VTFT_CTRL, HIGH); digitalWrite(VTFT_CTRL, HIGH);
#endif #endif
@@ -436,6 +473,16 @@ bool TFTDisplay::connect()
pinMode(TFT_BL, OUTPUT); pinMode(TFT_BL, OUTPUT);
#endif #endif
#ifdef ST7735_BACKLIGHT_EN_V03
if (heltec_version == 3) {
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
pinMode(ST7735_BACKLIGHT_EN_V03, OUTPUT);
} else {
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
pinMode(ST7735_BACKLIGHT_EN_V05, OUTPUT);
}
#endif
tft.init(); tft.init();
#if defined(M5STACK) #if defined(M5STACK)
tft.setRotation(0); tft.setRotation(0);

View File

@@ -146,6 +146,25 @@ const char *getDeviceName()
return name; return name;
} }
#ifdef VEXT_ENABLE_V03
#include <soc/rtc.h>
static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char *name)
{
const uint32_t cal_count = 1000;
uint32_t cali_val;
for (int i = 0; i < 5; ++i) {
cali_val = rtc_clk_cal(cal_clk, cal_count);
}
return cali_val;
}
int heltec_version = 3;
#define CALIBRATE_ONE(cali_clk) calibrate_one(cali_clk, #cali_clk)
#endif
static int32_t ledBlinker() static int32_t ledBlinker()
{ {
static bool ledOn; static bool ledOn;
@@ -216,11 +235,63 @@ void setup()
digitalWrite(PIN_EINK_PWR_ON, HIGH); digitalWrite(PIN_EINK_PWR_ON, HIGH);
#endif #endif
#ifdef VEXT_ENABLE #ifdef ST7735_BL_V03 // Heltec Wireless Tracker PCB Change Detect/Hack
rtc_clk_32k_enable(true);
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
if (CALIBRATE_ONE(RTC_CAL_32K_XTAL) != 0) {
rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL);
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
CALIBRATE_ONE(RTC_CAL_32K_XTAL);
}
if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) {
heltec_version = 3;
} else {
heltec_version = 5;
}
#endif
#if defined(VEXT_ENABLE_V03)
if (heltec_version == 3) {
pinMode(VEXT_ENABLE_V03, OUTPUT);
digitalWrite(VEXT_ENABLE_V03, 0); // turn on the display power
LOG_DEBUG("HELTEC Detect Tracker V1.0\n");
} else {
pinMode(VEXT_ENABLE_V05, OUTPUT);
digitalWrite(VEXT_ENABLE_V05, 1); // turn on the display power
LOG_DEBUG("HELTEC Detect Tracker V1.1\n");
}
#elif defined(VEXT_ENABLE)
pinMode(VEXT_ENABLE, OUTPUT); pinMode(VEXT_ENABLE, OUTPUT);
digitalWrite(VEXT_ENABLE, 0); // turn on the display power digitalWrite(VEXT_ENABLE, 0); // turn on the display power
#endif #endif
#if defined(VGNSS_CTRL_V03)
if (heltec_version == 3) {
pinMode(VGNSS_CTRL_V03, OUTPUT);
digitalWrite(VGNSS_CTRL_V03, LOW);
} else {
pinMode(VGNSS_CTRL_V05, OUTPUT);
digitalWrite(VGNSS_CTRL_V05, LOW);
}
#endif
#if defined(VTFT_CTRL_V03)
if (heltec_version == 3) {
pinMode(VTFT_CTRL_V03, OUTPUT);
digitalWrite(VTFT_CTRL_V03, LOW);
} else {
pinMode(VTFT_CTRL_V05, OUTPUT);
digitalWrite(VTFT_CTRL_V05, LOW);
}
#endif
#if defined(VGNSS_CTRL)
pinMode(VGNSS_CTRL, OUTPUT);
digitalWrite(VGNSS_CTRL, LOW);
#endif
#if defined(VTFT_CTRL) #if defined(VTFT_CTRL)
pinMode(VTFT_CTRL, OUTPUT); pinMode(VTFT_CTRL, OUTPUT);
digitalWrite(VTFT_CTRL, LOW); digitalWrite(VTFT_CTRL, LOW);

View File

@@ -64,6 +64,8 @@ extern uint32_t shutdownAtMsec;
extern uint32_t serialSinceMsec; extern uint32_t serialSinceMsec;
extern int heltec_version;
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag // If a thread does something that might need for it to be rescheduled ASAP it can set this flag
// This will suppress the current delay and instead try to run ASAP. // This will suppress the current delay and instead try to run ASAP.
extern bool runASAP; extern bool runASAP;

View File

@@ -687,8 +687,8 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i, LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
p.longitude_i, p.altitude); p.longitude_i, p.altitude);
setLocalPosition(p);
info->position = ConvertToPositionLite(p); info->position = ConvertToPositionLite(p);
localPosition = p;
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) { } else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO // FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900) // (stop-gap fix for issue #900)

View File

@@ -131,6 +131,13 @@ class NodeDB
meshtastic_NodeInfoLite *getMeshNode(NodeNum n); meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
size_t getNumMeshNodes() { return *numMeshNodes; } size_t getNumMeshNodes() { return *numMeshNodes; }
void setLocalPosition(meshtastic_Position position)
{
LOG_DEBUG("Setting local position: latitude=%i, longitude=%i, time=%i\n", position.latitude_i, position.longitude_i,
position.time);
localPosition = position;
}
private: private:
/// Find a node in our DB, create an empty NodeInfoLite if missing /// Find a node in our DB, create an empty NodeInfoLite if missing
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n); meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);

View File

@@ -113,6 +113,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_PICOMPUTER_S3 = 52, meshtastic_HardwareModel_PICOMPUTER_S3 = 52,
/* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */ /* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */
meshtastic_HardwareModel_HELTEC_HT62 = 53, meshtastic_HardwareModel_HELTEC_HT62 = 53,
/* E22-900M series modules with ESP32-S3 */
meshtastic_HardwareModel_E22_900M_S3 = 54,
/* ------------------------------------------------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------------------------------------------------------------ */

View File

@@ -44,10 +44,11 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
// FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER) // FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER)
// to set fixed location, EUD-GPS location or just the time (see also issue #900) // to set fixed location, EUD-GPS location or just the time (see also issue #900)
bool isLocal = false;
if (nodeDB.getNodeNum() == getFrom(&mp)) { if (nodeDB.getNodeNum() == getFrom(&mp)) {
LOG_DEBUG("Incoming update from MYSELF\n"); LOG_DEBUG("Incoming update from MYSELF\n");
// LOG_DEBUG("Ignored an incoming update from MYSELF\n"); isLocal = true;
// return false; nodeDB.setLocalPosition(p);
} }
// Log packet size and data fields // Log packet size and data fields
@@ -64,7 +65,8 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
tv.tv_sec = secs; tv.tv_sec = secs;
tv.tv_usec = 0; tv.tv_usec = 0;
perhapsSetRTC(RTCQualityFromNet, &tv); // Set from phone RTC Quality to RTCQualityNTP since it should be approximately so
perhapsSetRTC(isLocal ? RTCQualityNTP : RTCQualityFromNet, &tv);
} }
nodeDB.updatePosition(getFrom(&mp), p); nodeDB.updatePosition(getFrom(&mp), p);
@@ -94,8 +96,9 @@ meshtastic_MeshPacket *PositionModule::allocReply()
// Populate a Position struct with ONLY the requested fields // Populate a Position struct with ONLY the requested fields
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
// if localPosition is totally empty, put our last saved position (lite) in there
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) { if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
localPosition = ConvertToPosition(node->position); nodeDB.setLocalPosition(ConvertToPosition(node->position));
} }
localPosition.seq_number++; localPosition.seq_number++;
@@ -178,12 +181,14 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
service.sendToMesh(p, RX_SRC_LOCAL, true); service.sendToMesh(p, RX_SRC_LOCAL, true);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER && config.power.is_power_saving) { if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER && config.power.is_power_saving) {
LOG_DEBUG("Starting next execution in 3 seconds and then going to sleep.\n"); LOG_DEBUG("Starting next execution in 5 seconds and then going to sleep.\n");
sleepOnNextExecution = true; sleepOnNextExecution = true;
setIntervalFromNow(3000); setIntervalFromNow(5000);
} }
} }
#define RUNONCE_INTERVAL 5000;
int32_t PositionModule::runOnce() int32_t PositionModule::runOnce()
{ {
if (sleepOnNextExecution == true) { if (sleepOnNextExecution == true) {
@@ -199,60 +204,58 @@ int32_t PositionModule::runOnce()
uint32_t now = millis(); uint32_t now = millis();
uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs); uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
uint32_t msSinceLastSend = now - lastGpsSend; uint32_t msSinceLastSend = now - lastGpsSend;
// Only send packets if the channel util. is less than 25% utilized or we're a tracker with less than 40% utilized.
if (!airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
return RUNONCE_INTERVAL;
}
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) { if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
// Only send packets if the channel is less than 40% utilized. if (hasValidPosition(node)) {
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) { lastGpsSend = now;
if (hasValidPosition(node)) {
lastGpsSend = now;
lastGpsLatitude = node->position.latitude_i; lastGpsLatitude = node->position.latitude_i;
lastGpsLongitude = node->position.longitude_i; lastGpsLongitude = node->position.longitude_i;
// If we changed channels, ask everyone else for their latest info // If we changed channels, ask everyone else for their latest info
bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration;
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
sendOurPosition(NODENUM_BROADCAST, requestReplies);
}
} else if (config.position.position_broadcast_smart_enabled) {
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
if (hasValidPosition(node2)) {
// The minimum time (in seconds) that would pass before we are able to send a new position packet.
const uint32_t minimumTimeThreshold =
getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) {
bool requestReplies = currentGeneration != radioGeneration; bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration; currentGeneration = radioGeneration;
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies); LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
"minTimeInterval=%ims)\n",
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold,
msSinceLastSend, minimumTimeThreshold);
sendOurPosition(NODENUM_BROADCAST, requestReplies); sendOurPosition(NODENUM_BROADCAST, requestReplies);
}
}
} else if (config.position.position_broadcast_smart_enabled) {
// Only send packets if the channel is less than 25% utilized or we're a tracker.
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
if (hasValidPosition(node2)) { // Set the current coords as our last ones, after we've compared distance with current and decided to send
// The minimum time (in seconds) that would pass before we are able to send a new position packet. lastGpsLatitude = node->position.latitude_i;
const uint32_t minimumTimeThreshold = lastGpsLongitude = node->position.longitude_i;
getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
auto smartPosition = getDistanceTraveledSinceLastSend(node->position); /* Update lastGpsSend to now. This means if the device is stationary, then
getPref_position_broadcast_secs will still apply.
if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) { */
bool requestReplies = currentGeneration != radioGeneration; lastGpsSend = now;
currentGeneration = radioGeneration;
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
"minTimeInterval=%ims)\n",
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold,
msSinceLastSend, minimumTimeThreshold);
sendOurPosition(NODENUM_BROADCAST, requestReplies);
// Set the current coords as our last ones, after we've compared distance with current and decided to send
lastGpsLatitude = node->position.latitude_i;
lastGpsLongitude = node->position.longitude_i;
/* Update lastGpsSend to now. This means if the device is stationary, then
getPref_position_broadcast_secs will still apply.
*/
lastGpsSend = now;
}
} }
} }
} }
return 5000; // to save power only wake for our callback occasionally return RUNONCE_INTERVAL; // to save power only wake for our callback occasionally
} }
struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition) struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition)
@@ -264,6 +267,23 @@ struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic
float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter( float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter(
lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7); lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7);
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("--------LAST POSITION------------------------------------\n");
LOG_DEBUG("lastGpsLatitude=%i, lastGpsLatitude=%i\n", lastGpsLatitude, lastGpsLongitude);
LOG_DEBUG("--------CURRENT POSITION---------------------------------\n");
LOG_DEBUG("currentPosition.latitude_i=%i, currentPosition.longitude_i=%i\n", lastGpsLatitude, lastGpsLongitude);
LOG_DEBUG("--------SMART POSITION-----------------------------------\n");
LOG_DEBUG("hasTraveledOverThreshold=%i, distanceTraveled=%d, distanceThreshold=% u\n",
abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold, abs(distanceTraveledSinceLastSend),
distanceTravelThreshold);
if (abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) {
LOG_DEBUG("\n\n\nSMART SEEEEEEEEENDING\n\n\n");
}
#endif
return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend), return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend),
.distanceThreshold = distanceTravelThreshold, .distanceThreshold = distanceTravelThreshold,
.hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold}; .hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold};

View File

@@ -8,6 +8,8 @@
#include "configuration.h" #include "configuration.h"
#include "main.h" #include "main.h"
#include "power.h" #include "power.h"
#include "sleep.h"
#include "target_specific.h"
#include <OLEDDisplay.h> #include <OLEDDisplay.h>
#include <OLEDDisplayUi.h> #include <OLEDDisplayUi.h>
@@ -51,6 +53,13 @@ SHT31Sensor sht31Sensor;
int32_t EnvironmentTelemetryModule::runOnce() int32_t EnvironmentTelemetryModule::runOnce()
{ {
if (sleepOnNextExecution == true) {
sleepOnNextExecution = false;
uint32_t nightyNightMs = getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval);
LOG_DEBUG("Sleeping for %ims, then awaking to send metrics again.\n", nightyNightMs);
doDeepSleep(nightyNightMs, true);
}
uint32_t result = UINT32_MAX; uint32_t result = UINT32_MAX;
/* /*
Uncomment the preferences below if you want to use the module Uncomment the preferences below if you want to use the module
@@ -266,6 +275,12 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
} else { } else {
LOG_INFO("Sending packet to mesh\n"); LOG_INFO("Sending packet to mesh\n");
service.sendToMesh(p, RX_SRC_LOCAL, true); service.sendToMesh(p, RX_SRC_LOCAL, true);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR && config.power.is_power_saving) {
LOG_DEBUG("Starting next execution in 5 seconds and then going to sleep.\n");
sleepOnNextExecution = true;
setIntervalFromNow(5000);
}
} }
} }
return valid; return valid;

View File

@@ -180,15 +180,19 @@ void cpuDeepSleep(uint32_t msecToWake)
digitalWrite(AQ_SET_PIN, LOW); digitalWrite(AQ_SET_PIN, LOW);
#endif #endif
#endif #endif
// FIXME, use system off mode with ram retention for key state? // Sleepy trackers or sensors can low power "sleep"
// FIXME, use non-init RAM per // Don't enter this if we're sleeping portMAX_DELAY, since that's a shutdown event
// https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled if (msecToWake != portMAX_DELAY &&
(config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER && config.power.is_power_saving == true) { config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) &&
config.power.is_power_saving == true) {
sd_power_mode_set(NRF_POWER_MODE_LOWPWR); sd_power_mode_set(NRF_POWER_MODE_LOWPWR);
delay(msecToWake); delay(msecToWake);
NVIC_SystemReset(); NVIC_SystemReset();
} else { } else {
// FIXME, use system off mode with ram retention for key state?
// FIXME, use non-init RAM per
// https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled
auto ok = sd_power_system_off(); auto ok = sd_power_system_off();
if (ok != NRF_SUCCESS) { if (ok != NRF_SUCCESS) {
LOG_ERROR("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!\n"); LOG_ERROR("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!\n");

View File

@@ -202,7 +202,13 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false)
digitalWrite(RESET_OLED, 1); // put the display in reset before killing its power digitalWrite(RESET_OLED, 1); // put the display in reset before killing its power
#endif #endif
#ifdef VEXT_ENABLE #if defined(VEXT_ENABLE_V03)
if (heltec_version == 3) {
digitalWrite(VEXT_ENABLE_V03, 1); // turn off the display power
} else {
digitalWrite(VEXT_ENABLE_V05, 0); // turn off the display power
}
#elif defined(VEXT_ENABLE)
digitalWrite(VEXT_ENABLE, 1); // turn off the display power digitalWrite(VEXT_ENABLE, 1); // turn off the display power
#endif #endif

View File

@@ -9,9 +9,11 @@
#define ST7735_RESET 39 #define ST7735_RESET 39
#define ST7735_MISO -1 #define ST7735_MISO -1
#define ST7735_BUSY -1 #define ST7735_BUSY -1
#define ST7735_BL 45 #define ST7735_BL_V03 45
#define ST7735_BL_V05 21 /* V1.1 PCB marking */
#define ST7735_SPI_HOST SPI3_HOST #define ST7735_SPI_HOST SPI3_HOST
#define ST7735_BACKLIGHT_EN 45 #define ST7735_BACKLIGHT_EN_V03 45
#define ST7735_BACKLIGHT_EN_V05 21
#define SPI_FREQUENCY 40000000 #define SPI_FREQUENCY 40000000
#define SPI_READ_FREQUENCY 16000000 #define SPI_READ_FREQUENCY 16000000
#define SCREEN_ROTATE #define SCREEN_ROTATE
@@ -19,17 +21,20 @@
#define TFT_WIDTH 80 #define TFT_WIDTH 80
#define TFT_OFFSET_X 26 #define TFT_OFFSET_X 26
#define TFT_OFFSET_Y 0 #define TFT_OFFSET_Y 0
#define VTFT_CTRL 46 // Heltec Tracker needs this pulled low for TFT #define VTFT_CTRL_V03 46 // Heltec Tracker needs this pulled low for TFT
#define VTFT_CTRL_V05 -1
#define SCREEN_TRANSITION_FRAMERATE 1 // fps #define SCREEN_TRANSITION_FRAMERATE 1 // fps
#define DISPLAY_FORCE_SMALL_FONTS #define DISPLAY_FORCE_SMALL_FONTS
#define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost #define VEXT_ENABLE_V03 Vext // active low, powers the oled display and the lora antenna boost
#define VEXT_ENABLE_V05 3 // active HIGH, powers the oled display
#define BUTTON_PIN 0 #define BUTTON_PIN 0
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_CHANNEL ADC1_GPIO1_CHANNEL
#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider
#define ADC_MULTIPLIER 4.9 #define ADC_MULTIPLIER 4.9
#define ADC_CTRL 2 // active HIGH, powers the voltage divider. Only on 1.1
#undef GPS_RX_PIN #undef GPS_RX_PIN
#undef GPS_TX_PIN #undef GPS_TX_PIN
@@ -37,9 +42,12 @@
#define GPS_TX_PIN 34 #define GPS_TX_PIN 34
#define PIN_GPS_RESET 35 #define PIN_GPS_RESET 35
#define PIN_GPS_PPS 36 #define PIN_GPS_PPS 36
#define VGNSS_CTRL 37 // Heltec Tracker needs this pulled low for GPS
#define PIN_GPS_EN VGNSS_CTRL #define VGNSS_CTRL_V03 37 // Heltec Tracker needs this pulled low for GPS
#define VGNSS_CTRL_V05 -1 // Heltec Tracker needs this pulled low for GPS
#define PIN_GPS_EN VGNSS_CTRL_V03
#define GPS_EN_ACTIVE LOW #define GPS_EN_ACTIVE LOW
#define GPS_RESET_MODE LOW #define GPS_RESET_MODE LOW
#define GPS_UC6580 #define GPS_UC6580

View File

@@ -8,8 +8,6 @@
#define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost #define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost
#define BUTTON_PIN 0 #define BUTTON_PIN 0
#define PIN_GPS_EN 46 // GPS power enable pin
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_CHANNEL ADC1_GPIO1_CHANNEL
#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider

View File

@@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 2 major = 2
minor = 2 minor = 2
build = 10 build = 11