mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-19 16:27:28 +00:00
Compare commits
31 Commits
v2.3.7.30f
...
v2.3.8.d49
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d490a332a7 | ||
|
|
5dfa4b837f | ||
|
|
9501f3bda9 | ||
|
|
b69a1cada9 | ||
|
|
06e7d2b845 | ||
|
|
71400103b3 | ||
|
|
40e361e6d0 | ||
|
|
d1b6f11429 | ||
|
|
0527fb10ce | ||
|
|
5f929a8024 | ||
|
|
4f54862d63 | ||
|
|
0f4ac94559 | ||
|
|
45c1b46bd0 | ||
|
|
5095efc55f | ||
|
|
ec92f7a5a3 | ||
|
|
57da37cfbc | ||
|
|
3619ac87b8 | ||
|
|
e51ee91c39 | ||
|
|
21311bbeda | ||
|
|
18e69a0906 | ||
|
|
93f77ea7d2 | ||
|
|
ee4c4ae6c9 | ||
|
|
6cc7dee95c | ||
|
|
38c4d35a7b | ||
|
|
e683d8f552 | ||
|
|
e66aec8223 | ||
|
|
a06a01d25e | ||
|
|
f8c3f43ea6 | ||
|
|
dfcabba0b2 | ||
|
|
827bacdfc8 | ||
|
|
5806a266d3 |
@@ -1,6 +1,6 @@
|
|||||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||||
[portduino_base]
|
[portduino_base]
|
||||||
platform = https://github.com/meshtastic/platform-native.git#659e49346aa33008b150dfb206b1817ddabc7132
|
platform = https://github.com/meshtastic/platform-native.git#9881bf3721d610cccacf5ae8e3a07839cce75d63
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
@@ -24,7 +24,7 @@ lib_deps =
|
|||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
https://github.com/lovyan03/LovyanGFX.git#d35e60f269dfecbb18a8cb0fd07d594c2fb7e7a8
|
https://github.com/lovyan03/LovyanGFX.git#5a39989aa2c9492572255b22f033843ec8900233
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"extra_flags": [
|
"extra_flags": [
|
||||||
"-DBOARD_HAS_PSRAM",
|
"-DBOARD_HAS_PSRAM",
|
||||||
"-DLILYGO_TBEAM_S3_CORE",
|
"-DLILYGO_TBEAM_S3_CORE",
|
||||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
"-DARDUINO_USB_MODE=1",
|
"-DARDUINO_USB_MODE=1",
|
||||||
"-DARDUINO_RUNNING_CORE=1",
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ lib_deps =
|
|||||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; ESP8266_SSD1306
|
https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; ESP8266_SSD1306
|
||||||
mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
|
mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
|
||||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||||
https://github.com/meshtastic/TinyGPSPlus.git#964f75a72cccd6b53cd74e4add1f7a42c6f7344d
|
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
|
||||||
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
|
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
|
||||||
nanopb/Nanopb@^0.4.7
|
nanopb/Nanopb@^0.4.7
|
||||||
erriez/ErriezCRC32@^1.0.1
|
erriez/ErriezCRC32@^1.0.1
|
||||||
|
|||||||
Submodule protobufs updated: 86640f20db...e21899aa6b
@@ -136,9 +136,12 @@ int32_t ButtonThread::runOnce()
|
|||||||
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
||||||
LOG_BUTTON("Double press!\n");
|
LOG_BUTTON("Double press!\n");
|
||||||
service.refreshLocalMeshNode();
|
service.refreshLocalMeshNode();
|
||||||
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
auto sentPosition = service.trySendPosition(NODENUM_BROADCAST, true);
|
||||||
if (screen) {
|
if (screen) {
|
||||||
screen->print("Sent ad-hoc ping\n");
|
if (sentPosition)
|
||||||
|
screen->print("Sent ad-hoc position\n");
|
||||||
|
else
|
||||||
|
screen->print("Sent ad-hoc nodeinfo\n");
|
||||||
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -193,15 +196,13 @@ int32_t ButtonThread::runOnce()
|
|||||||
#ifdef BUTTON_PIN_TOUCH
|
#ifdef BUTTON_PIN_TOUCH
|
||||||
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
|
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
|
||||||
LOG_BUTTON("Touch press!\n");
|
LOG_BUTTON("Touch press!\n");
|
||||||
if (config.display.wake_on_tap_or_motion) {
|
if (screen) {
|
||||||
if (screen) {
|
// Wake if asleep
|
||||||
// Wake if asleep
|
if (powerFSM.getState() == &stateDARK)
|
||||||
if (powerFSM.getState() == &stateDARK)
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
|
|
||||||
// Update display (legacy behaviour)
|
// Update display (legacy behaviour)
|
||||||
screen->forceDisplay();
|
screen->forceDisplay();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
virtual uint16_t getBattVoltage() override
|
virtual uint16_t getBattVoltage() override
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
||||||
if (hasINA()) {
|
if (hasINA()) {
|
||||||
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
|
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
|
||||||
return getINAVoltage();
|
return getINAVoltage();
|
||||||
@@ -223,7 +223,17 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
raw = raw / BATTERY_SENSE_SAMPLES;
|
raw = raw / BATTERY_SENSE_SAMPLES;
|
||||||
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
|
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
|
||||||
#endif
|
#endif
|
||||||
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
|
|
||||||
|
if (!initial_read_done) {
|
||||||
|
// Flush the smoothing filter with an ADC reading, if the reading is plausibly correct
|
||||||
|
if (scaled > last_read_value)
|
||||||
|
last_read_value = scaled;
|
||||||
|
initial_read_done = true;
|
||||||
|
} else {
|
||||||
|
// Already initialized - filter this reading
|
||||||
|
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
|
||||||
|
}
|
||||||
|
|
||||||
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t)
|
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t)
|
||||||
// (last_read_value));
|
// (last_read_value));
|
||||||
}
|
}
|
||||||
@@ -357,10 +367,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
const float noBatVolt = (OCV[NUM_OCV_POINTS - 1] - 500) * NUM_CELLS;
|
const float noBatVolt = (OCV[NUM_OCV_POINTS - 1] - 500) * NUM_CELLS;
|
||||||
// Start value from minimum voltage for the filter to not start from 0
|
// Start value from minimum voltage for the filter to not start from 0
|
||||||
// that could trigger some events.
|
// that could trigger some events.
|
||||||
|
// This value is over-written by the first ADC reading, it the voltage seems reasonable.
|
||||||
|
bool initial_read_done = false;
|
||||||
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
|
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
|
||||||
uint32_t last_read_time_ms = 0;
|
uint32_t last_read_time_ms = 0;
|
||||||
|
|
||||||
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||||
uint16_t getINAVoltage()
|
uint16_t getINAVoltage()
|
||||||
{
|
{
|
||||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
||||||
|
|||||||
@@ -1467,7 +1467,7 @@ bool GPS::lookForLocation()
|
|||||||
#endif // GPS_EXTRAVERBOSE
|
#endif // GPS_EXTRAVERBOSE
|
||||||
|
|
||||||
// Is this a new point or are we re-reading the previous one?
|
// Is this a new point or are we re-reading the previous one?
|
||||||
if (!reader.location.isUpdated())
|
if (!reader.location.isUpdated() && !reader.altitude.isUpdated())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check if a complete GPS solution set is available for reading
|
// check if a complete GPS solution set is available for reading
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ int32_t getTZOffset()
|
|||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
gmt = gmtime(&now);
|
gmt = gmtime(&now);
|
||||||
gmt->tm_isdst = -1;
|
gmt->tm_isdst = -1;
|
||||||
return (int16_t)difftime(now, mktime(gmt));
|
return (int32_t)difftime(now, mktime(gmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
_panel_instance = new lgfx::Panel_ILI9341;
|
_panel_instance = new lgfx::Panel_ILI9341;
|
||||||
auto buscfg = _bus_instance.config();
|
auto buscfg = _bus_instance.config();
|
||||||
buscfg.spi_mode = 0;
|
buscfg.spi_mode = 0;
|
||||||
_bus_instance.spi_device(DisplaySPI);
|
buscfg.spi_host = settingsMap[displayspidev];
|
||||||
|
|
||||||
buscfg.pin_dc = settingsMap[displayDC]; // Set SPI DC pin number (-1 = disable)
|
buscfg.pin_dc = settingsMap[displayDC]; // Set SPI DC pin number (-1 = disable)
|
||||||
|
|
||||||
@@ -397,6 +397,8 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
touch_cfg.offset_rotation = 1;
|
touch_cfg.offset_rotation = 1;
|
||||||
if (settingsMap[touchscreenI2CAddr] != -1) {
|
if (settingsMap[touchscreenI2CAddr] != -1) {
|
||||||
touch_cfg.i2c_addr = settingsMap[touchscreenI2CAddr];
|
touch_cfg.i2c_addr = settingsMap[touchscreenI2CAddr];
|
||||||
|
} else {
|
||||||
|
touch_cfg.spi_host = settingsMap[touchscreenspidev];
|
||||||
}
|
}
|
||||||
|
|
||||||
_touch_instance->config(touch_cfg);
|
_touch_instance->config(touch_cfg);
|
||||||
|
|||||||
14
src/main.cpp
14
src/main.cpp
@@ -693,6 +693,12 @@ void setup()
|
|||||||
// Now that the mesh service is created, create any modules
|
// Now that the mesh service is created, create any modules
|
||||||
setupModules();
|
setupModules();
|
||||||
|
|
||||||
|
#ifdef LED_PIN
|
||||||
|
// Turn LED off after boot, if heartbeat by config
|
||||||
|
if (config.device.led_heartbeat_disabled)
|
||||||
|
digitalWrite(LED_PIN, LOW ^ LED_INVERTED);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Do this after service.init (because that clears error_code)
|
// Do this after service.init (because that clears error_code)
|
||||||
#ifdef HAS_PMU
|
#ifdef HAS_PMU
|
||||||
if (!pmu_found)
|
if (!pmu_found)
|
||||||
@@ -729,7 +735,7 @@ void setup()
|
|||||||
if (settingsMap[use_sx1262]) {
|
if (settingsMap[use_sx1262]) {
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings);
|
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||||
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
settingsMap[busy]);
|
settingsMap[busy]);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
@@ -743,7 +749,7 @@ void setup()
|
|||||||
} else if (settingsMap[use_rf95]) {
|
} else if (settingsMap[use_rf95]) {
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings);
|
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||||
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
settingsMap[busy]);
|
settingsMap[busy]);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
@@ -758,7 +764,7 @@ void setup()
|
|||||||
} else if (settingsMap[use_sx1280]) {
|
} else if (settingsMap[use_sx1280]) {
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings);
|
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||||
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
settingsMap[busy]);
|
settingsMap[busy]);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
@@ -773,7 +779,7 @@ void setup()
|
|||||||
} else if (settingsMap[use_sx1268]) {
|
} else if (settingsMap[use_sx1268]) {
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings);
|
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||||
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
settingsMap[busy]);
|
settingsMap[busy]);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
|
|||||||
@@ -35,11 +35,10 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
|
|
||||||
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
|
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
|
||||||
{
|
{
|
||||||
bool isAck =
|
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
|
||||||
((c && c->error_reason == meshtastic_Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK
|
if (isAckorReply && p->to != getNodeNum() && p->to != NODENUM_BROADCAST) {
|
||||||
if (isAck && p->to != getNodeNum()) {
|
// do not flood direct message that is ACKed or replied to
|
||||||
// do not flood direct message that is ACKed
|
LOG_DEBUG("Receiving an ACK or reply not for me, but don't need to rebroadcast this direct message anymore.\n");
|
||||||
LOG_DEBUG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
|
|
||||||
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
|
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
|
||||||
}
|
}
|
||||||
if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
|
if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
|
||||||
|
|||||||
@@ -193,10 +193,7 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (p.from != 0) { // We don't let phones assign nodenums to their sent messages
|
if (p.from != 0) { // We don't let phones assign nodenums to their sent messages
|
||||||
LOG_WARN("phone tried to pick a nodenum, we don't allow that.\n");
|
|
||||||
p.from = 0;
|
p.from = 0;
|
||||||
} else {
|
|
||||||
// p.from = nodeDB->getNodeNum();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.id == 0)
|
if (p.id == 0)
|
||||||
@@ -267,7 +264,7 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
bool MeshService::trySendPosition(NodeNum dest, bool wantReplies)
|
||||||
{
|
{
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||||
|
|
||||||
@@ -278,6 +275,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
|||||||
if (positionModule) {
|
if (positionModule) {
|
||||||
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
|
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
|
||||||
positionModule->sendOurPosition(dest, wantReplies, node->channel);
|
positionModule->sendOurPosition(dest, wantReplies, node->channel);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
@@ -286,6 +284,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
|||||||
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
|
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
||||||
|
|||||||
@@ -108,8 +108,9 @@ class MeshService
|
|||||||
void reloadOwner(bool shouldSave = true);
|
void reloadOwner(bool shouldSave = true);
|
||||||
|
|
||||||
/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least
|
/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least
|
||||||
/// sends our owner
|
/// sends our nodeinfo
|
||||||
void sendNetworkPing(NodeNum dest, bool wantReplies = false);
|
/// returns true if we sent a position
|
||||||
|
bool trySendPosition(NodeNum dest, bool wantReplies = false);
|
||||||
|
|
||||||
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
|
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
|
||||||
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
|
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
|
||||||
|
|||||||
@@ -352,9 +352,6 @@ void NodeDB::installDefaultModuleConfig()
|
|||||||
moduleConfig.external_notification.alert_message = true;
|
moduleConfig.external_notification.alert_message = true;
|
||||||
moduleConfig.external_notification.output_ms = 100;
|
moduleConfig.external_notification.output_ms = 100;
|
||||||
moduleConfig.external_notification.active = true;
|
moduleConfig.external_notification.active = true;
|
||||||
#endif
|
|
||||||
#ifdef TTGO_T_ECHO
|
|
||||||
config.display.wake_on_tap_or_motion = true; // Enable touch button for screen-on / refresh
|
|
||||||
#endif
|
#endif
|
||||||
moduleConfig.has_canned_message = true;
|
moduleConfig.has_canned_message = true;
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ extern const pb_msgdesc_t meshtastic_ChannelSet_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size
|
#define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size
|
||||||
#define meshtastic_ChannelSet_size 658
|
#define meshtastic_ChannelSet_size 674
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ typedef enum _meshtastic_Channel_Role {
|
|||||||
typedef struct _meshtastic_ModuleSettings {
|
typedef struct _meshtastic_ModuleSettings {
|
||||||
/* Bits of precision for the location sent in position packets. */
|
/* Bits of precision for the location sent in position packets. */
|
||||||
uint32_t position_precision;
|
uint32_t position_precision;
|
||||||
|
/* Controls whether or not the phone / clients should mute the current channel
|
||||||
|
Useful for noisy public channels you don't necessarily want to disable */
|
||||||
|
bool is_client_muted;
|
||||||
} meshtastic_ModuleSettings;
|
} meshtastic_ModuleSettings;
|
||||||
|
|
||||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t;
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t;
|
||||||
@@ -126,14 +129,15 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default}
|
#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default}
|
||||||
#define meshtastic_ModuleSettings_init_default {0}
|
#define meshtastic_ModuleSettings_init_default {0, 0}
|
||||||
#define meshtastic_Channel_init_default {0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN}
|
#define meshtastic_Channel_init_default {0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN}
|
||||||
#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero}
|
#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero}
|
||||||
#define meshtastic_ModuleSettings_init_zero {0}
|
#define meshtastic_ModuleSettings_init_zero {0, 0}
|
||||||
#define meshtastic_Channel_init_zero {0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN}
|
#define meshtastic_Channel_init_zero {0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
#define meshtastic_ModuleSettings_position_precision_tag 1
|
#define meshtastic_ModuleSettings_position_precision_tag 1
|
||||||
|
#define meshtastic_ModuleSettings_is_client_muted_tag 2
|
||||||
#define meshtastic_ChannelSettings_channel_num_tag 1
|
#define meshtastic_ChannelSettings_channel_num_tag 1
|
||||||
#define meshtastic_ChannelSettings_psk_tag 2
|
#define meshtastic_ChannelSettings_psk_tag 2
|
||||||
#define meshtastic_ChannelSettings_name_tag 3
|
#define meshtastic_ChannelSettings_name_tag 3
|
||||||
@@ -159,7 +163,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, module_settings, 7)
|
|||||||
#define meshtastic_ChannelSettings_module_settings_MSGTYPE meshtastic_ModuleSettings
|
#define meshtastic_ChannelSettings_module_settings_MSGTYPE meshtastic_ModuleSettings
|
||||||
|
|
||||||
#define meshtastic_ModuleSettings_FIELDLIST(X, a) \
|
#define meshtastic_ModuleSettings_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, position_precision, 1)
|
X(a, STATIC, SINGULAR, UINT32, position_precision, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, is_client_muted, 2)
|
||||||
#define meshtastic_ModuleSettings_CALLBACK NULL
|
#define meshtastic_ModuleSettings_CALLBACK NULL
|
||||||
#define meshtastic_ModuleSettings_DEFAULT NULL
|
#define meshtastic_ModuleSettings_DEFAULT NULL
|
||||||
|
|
||||||
@@ -182,9 +187,9 @@ extern const pb_msgdesc_t meshtastic_Channel_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_MAX_SIZE meshtastic_Channel_size
|
#define MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_MAX_SIZE meshtastic_Channel_size
|
||||||
#define meshtastic_ChannelSettings_size 70
|
#define meshtastic_ChannelSettings_size 72
|
||||||
#define meshtastic_Channel_size 85
|
#define meshtastic_Channel_size 87
|
||||||
#define meshtastic_ModuleSettings_size 6
|
#define meshtastic_ModuleSettings_size 8
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
|
|||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
/* meshtastic_DeviceState_size depends on runtime parameters */
|
/* meshtastic_DeviceState_size depends on runtime parameters */
|
||||||
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
|
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
|
||||||
#define meshtastic_ChannelFile_size 702
|
#define meshtastic_ChannelFile_size 718
|
||||||
#define meshtastic_NodeInfoLite_size 166
|
#define meshtastic_NodeInfoLite_size 166
|
||||||
#define meshtastic_OEMStore_size 3346
|
#define meshtastic_OEMStore_size 3346
|
||||||
#define meshtastic_PositionLite_size 28
|
#define meshtastic_PositionLite_size 28
|
||||||
|
|||||||
@@ -23,6 +23,10 @@
|
|||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !MESHTASTIC_EXCLUDE_GPS
|
||||||
|
#include "GPS.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
AdminModule *adminModule;
|
AdminModule *adminModule;
|
||||||
bool hasOpenEditTransaction;
|
bool hasOpenEditTransaction;
|
||||||
|
|
||||||
@@ -217,6 +221,10 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
|||||||
nodeDB->setLocalPosition(r->set_fixed_position);
|
nodeDB->setLocalPosition(r->set_fixed_position);
|
||||||
config.position.fixed_position = true;
|
config.position.fixed_position = true;
|
||||||
saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false);
|
saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false);
|
||||||
|
#if !MESHTASTIC_EXCLUDE_GPS
|
||||||
|
if (gps != nullptr)
|
||||||
|
gps->enable();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -233,14 +233,16 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
{
|
{
|
||||||
if (((!moduleConfig.canned_message.enabled) && !CANNED_MESSAGE_MODULE_ENABLE) ||
|
if (((!moduleConfig.canned_message.enabled) && !CANNED_MESSAGE_MODULE_ENABLE) ||
|
||||||
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
|
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
|
||||||
|
temporaryMessage = "";
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
}
|
}
|
||||||
// LOG_DEBUG("Check status\n");
|
// LOG_DEBUG("Check status\n");
|
||||||
UIFrameEvent e = {false, true};
|
UIFrameEvent e = {false, true};
|
||||||
if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) ||
|
if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) ||
|
||||||
(this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED)) {
|
(this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) || (this->runState == CANNED_MESSAGE_RUN_STATE_MESSAGE)) {
|
||||||
// TODO: might have some feedback of sendig state
|
// TODO: might have some feedback of sending state
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
|
temporaryMessage = "";
|
||||||
e.frameChanged = true;
|
e.frameChanged = true;
|
||||||
this->currentMessageIndex = -1;
|
this->currentMessageIndex = -1;
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
@@ -434,7 +436,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
}
|
}
|
||||||
if (screen)
|
if (screen)
|
||||||
screen->forceDisplay();
|
screen->forceDisplay();
|
||||||
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
showTemporaryMessage("GPS Toggled");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// mute (switch off/toggle) external notifications on fn+m
|
// mute (switch off/toggle) external notifications on fn+m
|
||||||
@@ -442,18 +444,21 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
if (moduleConfig.external_notification.enabled == true) {
|
if (moduleConfig.external_notification.enabled == true) {
|
||||||
if (externalNotificationModule->getMute()) {
|
if (externalNotificationModule->getMute()) {
|
||||||
externalNotificationModule->setMute(false);
|
externalNotificationModule->setMute(false);
|
||||||
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
showTemporaryMessage("Notifications \nEnabled");
|
||||||
} else {
|
} else {
|
||||||
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
|
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
|
||||||
externalNotificationModule->setMute(true);
|
externalNotificationModule->setMute(true);
|
||||||
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
showTemporaryMessage("Notifications \nDisabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xaf: // fn+space send network ping like double press does
|
case 0xaf: // fn+space send network ping like double press does
|
||||||
service.refreshLocalMeshNode();
|
service.refreshLocalMeshNode();
|
||||||
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
if (service.trySendPosition(NODENUM_BROADCAST, true)) {
|
||||||
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
showTemporaryMessage("Position \nUpdate Sent");
|
||||||
|
} else {
|
||||||
|
showTemporaryMessage("Node Info \nUpdate Sent");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (this->cursor == this->freetext.length()) {
|
if (this->cursor == this->freetext.length()) {
|
||||||
@@ -542,12 +547,27 @@ int CannedMessageModule::getPrevIndex()
|
|||||||
return this->currentMessageIndex - 1;
|
return this->currentMessageIndex - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void CannedMessageModule::showTemporaryMessage(const String &message)
|
||||||
|
{
|
||||||
|
temporaryMessage = message;
|
||||||
|
UIFrameEvent e = {false, true};
|
||||||
|
e.frameChanged = true;
|
||||||
|
notifyObservers(&e);
|
||||||
|
runState = CANNED_MESSAGE_RUN_STATE_MESSAGE;
|
||||||
|
// run this loop again in 2 seconds, next iteration will clear the display
|
||||||
|
setIntervalFromNow(2000);
|
||||||
|
}
|
||||||
|
|
||||||
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
char buffer[50];
|
char buffer[50];
|
||||||
|
|
||||||
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) {
|
if (temporaryMessage.length() != 0) {
|
||||||
|
LOG_DEBUG("Drawing temporary message: %s", temporaryMessage.c_str());
|
||||||
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
|
display->setFont(FONT_MEDIUM);
|
||||||
|
display->drawString(display->getWidth() / 2 + x, 0 + y + 12, temporaryMessage);
|
||||||
|
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) {
|
||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
display->setFont(FONT_MEDIUM);
|
display->setFont(FONT_MEDIUM);
|
||||||
String displayString;
|
String displayString;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ enum cannedMessageModuleRunState {
|
|||||||
CANNED_MESSAGE_RUN_STATE_FREETEXT,
|
CANNED_MESSAGE_RUN_STATE_FREETEXT,
|
||||||
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
|
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
|
||||||
CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED,
|
CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED,
|
||||||
|
CANNED_MESSAGE_RUN_STATE_MESSAGE,
|
||||||
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
|
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
|
||||||
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
|
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
|
||||||
CANNED_MESSAGE_RUN_STATE_ACTION_DOWN,
|
CANNED_MESSAGE_RUN_STATE_ACTION_DOWN,
|
||||||
@@ -51,6 +52,8 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
void handleGetCannedMessageModuleMessages(const meshtastic_MeshPacket &req, meshtastic_AdminMessage *response);
|
void handleGetCannedMessageModuleMessages(const meshtastic_MeshPacket &req, meshtastic_AdminMessage *response);
|
||||||
void handleSetCannedMessageModuleMessages(const char *from_msg);
|
void handleSetCannedMessageModuleMessages(const char *from_msg);
|
||||||
|
|
||||||
|
void showTemporaryMessage(const String &message);
|
||||||
|
|
||||||
String drawWithCursor(String text, int cursor);
|
String drawWithCursor(String text, int cursor);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -112,6 +115,7 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
|
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
|
||||||
int messagesCount = 0;
|
int messagesCount = 0;
|
||||||
unsigned long lastTouchMillis = 0;
|
unsigned long lastTouchMillis = 0;
|
||||||
|
String temporaryMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CannedMessageModule *cannedMessageModule;
|
extern CannedMessageModule *cannedMessageModule;
|
||||||
|
|||||||
@@ -87,6 +87,23 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
|||||||
return false; // Let others look at this message also if they want
|
return false; // Let others look at this message also if they want
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PositionModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_Position *p)
|
||||||
|
{
|
||||||
|
// Phone position packets need to be truncated to the channel precision
|
||||||
|
if (nodeDB->getNodeNum() == getFrom(&mp) && (precision < 32 && precision > 0)) {
|
||||||
|
LOG_DEBUG("Truncating phone position to channel precision %i\n", precision);
|
||||||
|
p->latitude_i = p->latitude_i & (UINT32_MAX << (32 - precision));
|
||||||
|
p->longitude_i = p->longitude_i & (UINT32_MAX << (32 - precision));
|
||||||
|
|
||||||
|
// We want the imprecise position to be the middle of the possible location, not
|
||||||
|
p->latitude_i += (1 << (31 - precision));
|
||||||
|
p->longitude_i += (1 << (31 - precision));
|
||||||
|
|
||||||
|
mp.decoded.payload.size =
|
||||||
|
pb_encode_to_bytes(mp.decoded.payload.bytes, sizeof(mp.decoded.payload.bytes), &meshtastic_Position_msg, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PositionModule::trySetRtc(meshtastic_Position p, bool isLocal)
|
void PositionModule::trySetRtc(meshtastic_Position p, bool isLocal)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
|
|||||||
*/
|
*/
|
||||||
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *p) override;
|
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *p) override;
|
||||||
|
|
||||||
|
virtual void alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_Position *p) override;
|
||||||
|
|
||||||
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
||||||
* so that subclasses can (optionally) send a response back to the original sender. */
|
* so that subclasses can (optionally) send a response back to the original sender. */
|
||||||
virtual meshtastic_MeshPacket *allocReply() override;
|
virtual meshtastic_MeshPacket *allocReply() override;
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
|||||||
JSONObject json;
|
JSONObject json;
|
||||||
json = json_value->AsObject();
|
json = json_value->AsObject();
|
||||||
|
|
||||||
// parse the channel name from the topic string by looking for "json/"
|
// parse the channel name from the topic string
|
||||||
const char *jsonSlash = "json/";
|
// the topic has been checked above for having jsonTopic prefix, so just move past it
|
||||||
char *ptr = strstr(topic, jsonSlash) + sizeof(jsonSlash) + 1; // set pointer to after "json/"
|
char *ptr = topic + jsonTopic.length();
|
||||||
ptr = strtok(ptr, "/") ? strtok(ptr, "/") : ptr; // if another "/" was added, parse string up to that character
|
ptr = strtok(ptr, "/") ? strtok(ptr, "/") : ptr; // if another "/" was added, parse string up to that character
|
||||||
meshtastic_Channel sendChannel = channels.getByName(ptr);
|
meshtastic_Channel sendChannel = channels.getByName(ptr);
|
||||||
// We allow downlink JSON packets only on a channel named "mqtt"
|
// We allow downlink JSON packets only on a channel named "mqtt"
|
||||||
@@ -76,6 +76,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
|||||||
p->channel = json["channel"]->AsNumber();
|
p->channel = json["channel"]->AsNumber();
|
||||||
if (json.find("to") != json.end() && json["to"]->IsNumber())
|
if (json.find("to") != json.end() && json["to"]->IsNumber())
|
||||||
p->to = json["to"]->AsNumber();
|
p->to = json["to"]->AsNumber();
|
||||||
|
if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber())
|
||||||
|
p->hop_limit = json["hopLimit"]->AsNumber();
|
||||||
if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
|
if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
|
||||||
memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||||
p->decoded.payload.size = jsonPayloadStr.length();
|
p->decoded.payload.size = jsonPayloadStr.length();
|
||||||
@@ -105,6 +107,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
|||||||
p->channel = json["channel"]->AsNumber();
|
p->channel = json["channel"]->AsNumber();
|
||||||
if (json.find("to") != json.end() && json["to"]->IsNumber())
|
if (json.find("to") != json.end() && json["to"]->IsNumber())
|
||||||
p->to = json["to"]->AsNumber();
|
p->to = json["to"]->AsNumber();
|
||||||
|
if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber())
|
||||||
|
p->hop_limit = json["hopLimit"]->AsNumber();
|
||||||
p->decoded.payload.size =
|
p->decoded.payload.size =
|
||||||
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes),
|
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes),
|
||||||
&meshtastic_Position_msg, &pos); // make the Data protobuf from position
|
&meshtastic_Position_msg, &pos); // make the Data protobuf from position
|
||||||
@@ -907,6 +911,7 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json)
|
|||||||
{
|
{
|
||||||
// if "sender" is provided, avoid processing packets we uplinked
|
// if "sender" is provided, avoid processing packets we uplinked
|
||||||
return (json.find("sender") != json.end() ? (json["sender"]->AsString().compare(owner.id) != 0) : true) &&
|
return (json.find("sender") != json.end() ? (json["sender"]->AsString().compare(owner.id) != 0) : true) &&
|
||||||
|
(json.find("hopLimit") != json.end() ? json["hopLimit"]->IsNumber() : true) && // hop limit should be a number
|
||||||
(json.find("from") != json.end()) && json["from"]->IsNumber() &&
|
(json.find("from") != json.end()) && json["from"]->IsNumber() &&
|
||||||
(json["from"]->AsNumber() == nodeDB->getNodeNum()) && // only accept message if the "from" is us
|
(json["from"]->AsNumber() == nodeDB->getNodeNum()) && // only accept message if the "from" is us
|
||||||
(json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type
|
(json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
HardwareSPI *DisplaySPI;
|
|
||||||
HardwareSPI *LoraSPI;
|
|
||||||
std::map<configNames, int> settingsMap;
|
std::map<configNames, int> settingsMap;
|
||||||
std::map<configNames, std::string> settingsStrings;
|
std::map<configNames, std::string> settingsStrings;
|
||||||
char *configPath = nullptr;
|
char *configPath = nullptr;
|
||||||
@@ -76,7 +74,21 @@ void portduinoCustomInit()
|
|||||||
void portduinoSetup()
|
void portduinoSetup()
|
||||||
{
|
{
|
||||||
printf("Setting up Meshtastic on Portduino...\n");
|
printf("Setting up Meshtastic on Portduino...\n");
|
||||||
gpioInit();
|
int max_GPIO = 0;
|
||||||
|
configNames GPIO_lines[] = {cs,
|
||||||
|
irq,
|
||||||
|
busy,
|
||||||
|
reset,
|
||||||
|
txen,
|
||||||
|
rxen,
|
||||||
|
displayDC,
|
||||||
|
displayCS,
|
||||||
|
displayBacklight,
|
||||||
|
displayBacklightPWMChannel,
|
||||||
|
displayReset,
|
||||||
|
touchscreenCS,
|
||||||
|
touchscreenIRQ,
|
||||||
|
user};
|
||||||
|
|
||||||
std::string gpioChipName = "gpiochip";
|
std::string gpioChipName = "gpiochip";
|
||||||
settingsStrings[i2cdev] = "";
|
settingsStrings[i2cdev] = "";
|
||||||
@@ -159,6 +171,15 @@ void portduinoSetup()
|
|||||||
gpioChipName += std::to_string(settingsMap[gpiochip]);
|
gpioChipName += std::to_string(settingsMap[gpiochip]);
|
||||||
|
|
||||||
settingsStrings[spidev] = "/dev/" + yamlConfig["Lora"]["spidev"].as<std::string>("spidev0.0");
|
settingsStrings[spidev] = "/dev/" + yamlConfig["Lora"]["spidev"].as<std::string>("spidev0.0");
|
||||||
|
if (settingsStrings[spidev].length() == 14) {
|
||||||
|
int x = settingsStrings[spidev].at(11) - '0';
|
||||||
|
int y = settingsStrings[spidev].at(13) - '0';
|
||||||
|
if (x >= 0 && x < 10 && y >= 0 && y < 10) {
|
||||||
|
settingsMap[spidev] = x + y << 4;
|
||||||
|
settingsMap[displayspidev] = settingsMap[spidev];
|
||||||
|
settingsMap[touchscreenspidev] = settingsMap[spidev];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (yamlConfig["GPIO"]) {
|
if (yamlConfig["GPIO"]) {
|
||||||
settingsMap[user] = yamlConfig["GPIO"]["User"].as<int>(RADIOLIB_NC);
|
settingsMap[user] = yamlConfig["GPIO"]["User"].as<int>(RADIOLIB_NC);
|
||||||
@@ -208,6 +229,14 @@ void portduinoSetup()
|
|||||||
settingsMap[displayBusFrequency] = yamlConfig["Display"]["BusFrequency"].as<int>(40000000);
|
settingsMap[displayBusFrequency] = yamlConfig["Display"]["BusFrequency"].as<int>(40000000);
|
||||||
if (yamlConfig["Display"]["spidev"]) {
|
if (yamlConfig["Display"]["spidev"]) {
|
||||||
settingsStrings[displayspidev] = "/dev/" + yamlConfig["Display"]["spidev"].as<std::string>("spidev0.1");
|
settingsStrings[displayspidev] = "/dev/" + yamlConfig["Display"]["spidev"].as<std::string>("spidev0.1");
|
||||||
|
if (settingsStrings[displayspidev].length() == 14) {
|
||||||
|
int x = settingsStrings[displayspidev].at(11) - '0';
|
||||||
|
int y = settingsStrings[displayspidev].at(13) - '0';
|
||||||
|
if (x >= 0 && x < 10 && y >= 0 && y < 10) {
|
||||||
|
settingsMap[displayspidev] = x + y << 4;
|
||||||
|
settingsMap[touchscreenspidev] = settingsMap[displayspidev];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settingsMap[touchscreenModule] = no_touchscreen;
|
settingsMap[touchscreenModule] = no_touchscreen;
|
||||||
@@ -227,6 +256,13 @@ void portduinoSetup()
|
|||||||
settingsMap[touchscreenI2CAddr] = yamlConfig["Touchscreen"]["I2CAddr"].as<int>(-1);
|
settingsMap[touchscreenI2CAddr] = yamlConfig["Touchscreen"]["I2CAddr"].as<int>(-1);
|
||||||
if (yamlConfig["Touchscreen"]["spidev"]) {
|
if (yamlConfig["Touchscreen"]["spidev"]) {
|
||||||
settingsStrings[touchscreenspidev] = "/dev/" + yamlConfig["Touchscreen"]["spidev"].as<std::string>("");
|
settingsStrings[touchscreenspidev] = "/dev/" + yamlConfig["Touchscreen"]["spidev"].as<std::string>("");
|
||||||
|
if (settingsStrings[touchscreenspidev].length() == 14) {
|
||||||
|
int x = settingsStrings[touchscreenspidev].at(11) - '0';
|
||||||
|
int y = settingsStrings[touchscreenspidev].at(13) - '0';
|
||||||
|
if (x >= 0 && x < 10 && y >= 0 && y < 10) {
|
||||||
|
settingsMap[touchscreenspidev] = x + y << 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (yamlConfig["Input"]) {
|
if (yamlConfig["Input"]) {
|
||||||
@@ -245,6 +281,13 @@ void portduinoSetup()
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (configNames i : GPIO_lines) {
|
||||||
|
if (settingsMap[i] > max_GPIO)
|
||||||
|
max_GPIO = settingsMap[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioInit(max_GPIO + 1); // Done here so we can inform Portduino how many GPIOs we need.
|
||||||
|
|
||||||
// Need to bind all the configured GPIO pins so they're not simulated
|
// Need to bind all the configured GPIO pins so they're not simulated
|
||||||
if (settingsMap.count(cs) > 0 && settingsMap[cs] != RADIOLIB_NC) {
|
if (settingsMap.count(cs) > 0 && settingsMap[cs] != RADIOLIB_NC) {
|
||||||
if (initGPIOPin(settingsMap[cs], gpioChipName) != ERRNO_OK) {
|
if (initGPIOPin(settingsMap[cs], gpioChipName) != ERRNO_OK) {
|
||||||
@@ -298,27 +341,9 @@ void portduinoSetup()
|
|||||||
if (settingsMap[touchscreenIRQ] > 0)
|
if (settingsMap[touchscreenIRQ] > 0)
|
||||||
initGPIOPin(settingsMap[touchscreenIRQ], gpioChipName);
|
initGPIOPin(settingsMap[touchscreenIRQ], gpioChipName);
|
||||||
}
|
}
|
||||||
|
if (settingsStrings[spidev] != "") {
|
||||||
// if we specify a touchscreen dev, that is SPI.
|
|
||||||
// else if we specify a screen dev, that is SPI
|
|
||||||
// else if we specify a LoRa dev, that is SPI.
|
|
||||||
if (settingsStrings[touchscreenspidev] != "") {
|
|
||||||
SPI.begin(settingsStrings[touchscreenspidev].c_str());
|
|
||||||
DisplaySPI = new HardwareSPI;
|
|
||||||
DisplaySPI->begin(settingsStrings[displayspidev].c_str());
|
|
||||||
LoraSPI = new HardwareSPI;
|
|
||||||
LoraSPI->begin(settingsStrings[spidev].c_str());
|
|
||||||
} else if (settingsStrings[displayspidev] != "") {
|
|
||||||
SPI.begin(settingsStrings[displayspidev].c_str());
|
|
||||||
DisplaySPI = &SPI;
|
|
||||||
LoraSPI = new HardwareSPI;
|
|
||||||
LoraSPI->begin(settingsStrings[spidev].c_str());
|
|
||||||
} else {
|
|
||||||
SPI.begin(settingsStrings[spidev].c_str());
|
SPI.begin(settingsStrings[spidev].c_str());
|
||||||
LoraSPI = &SPI;
|
|
||||||
DisplaySPI = &SPI;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,5 +57,3 @@ enum { level_error, level_warn, level_info, level_debug };
|
|||||||
extern std::map<configNames, int> settingsMap;
|
extern std::map<configNames, int> settingsMap;
|
||||||
extern std::map<configNames, std::string> settingsStrings;
|
extern std::map<configNames, std::string> settingsStrings;
|
||||||
int initGPIOPin(int pinNum, std::string gpioChipname);
|
int initGPIOPin(int pinNum, std::string gpioChipname);
|
||||||
extern HardwareSPI *DisplaySPI;
|
|
||||||
extern HardwareSPI *LoraSPI;
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[env:TWC_mesh_v4]
|
[env:TWC_mesh_v4]
|
||||||
extends = nrf52840_base
|
extends = nrf52840_base
|
||||||
board = TWC_mesh_v4
|
board = nordic_pca10059
|
||||||
board_level = extra
|
board_level = extra
|
||||||
build_flags = ${nrf52840_base.build_flags} -I variants/TWC_mesh_v4 -D TWC_mesh_v4 -L".pio\libdeps\TWC_mesh_v4\BSEC2 Software Library\src\cortex-m4\fpv4-sp-d16-hard"
|
build_flags = ${nrf52840_base.build_flags} -I variants/TWC_mesh_v4 -D TWC_mesh_v4 -L".pio\libdeps\TWC_mesh_v4\BSEC2 Software Library\src\cortex-m4\fpv4-sp-d16-hard"
|
||||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/TWC_mesh_v4>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/TWC_mesh_v4>
|
||||||
|
|||||||
@@ -1,24 +1,16 @@
|
|||||||
#define I2C_SDA 1
|
|
||||||
#define I2C_SCL 0
|
|
||||||
|
|
||||||
#define BUTTON_PIN 9
|
#define BUTTON_PIN 9
|
||||||
#define BUTTON_NEED_PULLUP
|
|
||||||
|
|
||||||
// LED flashes brighter
|
// LED pin on HT-DEV-ESP_V2 and HT-DEV-ESP_V3
|
||||||
// https://resource.heltec.cn/download/HT-CT62/HT-CT62_Reference_Design.pdf
|
// https://resource.heltec.cn/download/HT-CT62/HT-CT62_Reference_Design.pdf
|
||||||
#define LED_PIN 18 // LED
|
// https://resource.heltec.cn/download/HT-DEV-ESP/HT-DEV-ESP_V3_Sch.pdf
|
||||||
#define LED_INVERTED 1
|
#define LED_PIN 2 // LED
|
||||||
|
#define LED_INVERTED 0
|
||||||
|
|
||||||
#define HAS_SCREEN 1
|
#define HAS_SCREEN 0
|
||||||
#define HAS_GPS 0
|
#define HAS_GPS 0
|
||||||
#undef GPS_RX_PIN
|
#undef GPS_RX_PIN
|
||||||
#undef GPS_TX_PIN
|
#undef GPS_TX_PIN
|
||||||
|
|
||||||
#undef LORA_SCK
|
|
||||||
#undef LORA_MISO
|
|
||||||
#undef LORA_MOSI
|
|
||||||
#undef LORA_CS
|
|
||||||
|
|
||||||
#define USE_SX1262
|
#define USE_SX1262
|
||||||
#define LORA_SCK 10
|
#define LORA_SCK 10
|
||||||
#define LORA_MISO 6
|
#define LORA_MISO 6
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ External serial flash WP25R1635FZUIL0
|
|||||||
// Note DIO2 is attached internally to the module to an analog switch for TX/RX switching
|
// Note DIO2 is attached internally to the module to an analog switch for TX/RX switching
|
||||||
#define SX1262_DIO3 \
|
#define SX1262_DIO3 \
|
||||||
(0 + 21) // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main
|
(0 + 21) // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main
|
||||||
// CPU?
|
// CPU?
|
||||||
#define SX126X_BUSY (0 + 17)
|
#define SX126X_BUSY (0 + 17)
|
||||||
#define SX126X_RESET (0 + 25)
|
#define SX126X_RESET (0 + 25)
|
||||||
// Not really an E22 but TTGO seems to be trying to clone that
|
// Not really an E22 but TTGO seems to be trying to clone that
|
||||||
@@ -177,13 +177,13 @@ External serial flash WP25R1635FZUIL0
|
|||||||
#define PIN_GPS_STANDBY (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake
|
#define PIN_GPS_STANDBY (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake
|
||||||
// Seems to be missing on this new board
|
// Seems to be missing on this new board
|
||||||
// #define PIN_GPS_PPS (32 + 4) // Pulse per second input from the GPS
|
// #define PIN_GPS_PPS (32 + 4) // Pulse per second input from the GPS
|
||||||
#define PIN_GPS_TX (32 + 9) // This is for bits going TOWARDS the CPU
|
#define GPS_TX_PIN (32 + 9) // This is for bits going TOWARDS the CPU
|
||||||
#define PIN_GPS_RX (32 + 8) // This is for bits going TOWARDS the GPS
|
#define GPS_RX_PIN (32 + 8) // This is for bits going TOWARDS the GPS
|
||||||
|
|
||||||
#define GPS_THREAD_INTERVAL 50
|
#define GPS_THREAD_INTERVAL 50
|
||||||
|
|
||||||
#define PIN_SERIAL1_RX PIN_GPS_TX
|
#define PIN_SERIAL1_RX GPS_TX_PIN
|
||||||
#define PIN_SERIAL1_TX PIN_GPS_RX
|
#define PIN_SERIAL1_TX GPS_RX_PIN
|
||||||
|
|
||||||
// PCF8563 RTC Module
|
// PCF8563 RTC Module
|
||||||
#define PCF8563_RTC 0x51
|
#define PCF8563_RTC 0x51
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
extends = esp32s3_base
|
extends = esp32s3_base
|
||||||
board = tbeam-s3-core
|
board = tbeam-s3-core
|
||||||
|
|
||||||
|
platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.15
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
lewisxhe/PCF8563_Library@1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ static const uint8_t SCL = PIN_WIRE_SCL;
|
|||||||
#define BAT_READ \
|
#define BAT_READ \
|
||||||
14 // P0_14 = 14 Reads battery voltage from divider on signal board. (PIN_VBAT is reading voltage divider on XIAO and is
|
14 // P0_14 = 14 Reads battery voltage from divider on signal board. (PIN_VBAT is reading voltage divider on XIAO and is
|
||||||
// program pin 32 / or P0.31)
|
// program pin 32 / or P0.31)
|
||||||
|
#define BATTERY_SENSE_RESOLUTION_BITS 10
|
||||||
#define CHARGE_LED 23 // P0_17 = 17 D23 YELLOW CHARGE LED
|
#define CHARGE_LED 23 // P0_17 = 17 D23 YELLOW CHARGE LED
|
||||||
#define HICHG 22 // P0_13 = 13 D22 Charge-select pin for Lipo for 100 mA instead of default 50mA charge
|
#define HICHG 22 // P0_13 = 13 D22 Charge-select pin for Lipo for 100 mA instead of default 50mA charge
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 2
|
major = 2
|
||||||
minor = 3
|
minor = 3
|
||||||
build = 7
|
build = 8
|
||||||
|
|||||||
Reference in New Issue
Block a user