Merge branch 'meshtastic:master' into master

This commit is contained in:
Mictronics 2024-01-29 18:49:21 +01:00 committed by GitHub
commit ee92162974
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 161 additions and 108 deletions

View File

@ -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#04435d06e39916a6c019d511518d8e95c659dfbd platform = https://github.com/meshtastic/platform-native.git#a28dd5a9ccd5c48a9bede46037855ff83915d74b
framework = arduino framework = arduino
build_src_filter = build_src_filter =

View File

@ -60,6 +60,11 @@ GPIO:
GPS: GPS:
# SerialPath: /dev/ttyS0 # SerialPath: /dev/ttyS0
### Specify I2C device, or leave blank for none
I2C:
# I2CDevice: /dev/i2c-1
### Set up SPI displays here. Note that I2C displays are generally auto-detected. ### Set up SPI displays here. Note that I2C displays are generally auto-detected.
Display: Display:

@ -1 +1 @@
Subproject commit 44e369e1813f8ec9c7aefe1aac7d0adc75e11f8a Subproject commit e894709e4a96867ea8fad59a12f582e1029a6f8e

View File

@ -164,7 +164,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
#endif #endif
#ifndef BATTERY_SENSE_SAMPLES #ifndef BATTERY_SENSE_SAMPLES
#define BATTERY_SENSE_SAMPLES 30 #define BATTERY_SENSE_SAMPLES \
30 // Set the number of samples, it has an effect of increasing sensitivity in complex electromagnetic environment.
#endif #endif
#ifdef BATTERY_PIN #ifdef BATTERY_PIN
@ -176,66 +177,71 @@ class AnalogBatteryLevel : public HasBatteryLevel
if (millis() - last_read_time_ms > min_read_interval) { if (millis() - last_read_time_ms > min_read_interval) {
last_read_time_ms = millis(); last_read_time_ms = millis();
// Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic
// environment.
uint32_t raw = 0; uint32_t raw = 0;
#ifdef ARCH_ESP32 float scaled = 0;
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
#ifdef ADC_CTRL #ifdef ARCH_ESP32 // ADC block for espressif platforms
if (heltec_version == 5) { raw = espAdcRead();
pinMode(ADC_CTRL, OUTPUT); scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
digitalWrite(ADC_CTRL, HIGH); scaled *= operativeAdcMultiplier;
delay(10); #else // block for all other platforms
}
#endif
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
raw += adc1_get_raw(adc_channel);
}
#ifdef ADC_CTRL
if (heltec_version == 5) {
digitalWrite(ADC_CTRL, LOW);
}
#endif
#else // ADC2
int32_t adc_buf = 0;
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
// ADC2 wifi bug workaround, see
// https://github.com/espressif/arduino-esp32/issues/102
WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, RTC_reg_b);
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
adc2_get_raw(adc_channel, ADC_WIDTH_BIT_12, &adc_buf);
raw += adc_buf;
}
#endif // BAT_MEASURE_ADC_UNIT
#else // !ARCH_ESP32
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) { for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
raw += analogRead(BATTERY_PIN); raw += analogRead(BATTERY_PIN);
} }
#endif
raw = raw / BATTERY_SENSE_SAMPLES; raw = raw / BATTERY_SENSE_SAMPLES;
float scaled; scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
#ifdef ARCH_ESP32 #endif
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs); // LOG_DEBUG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled));
scaled *= operativeAdcMultiplier;
#else
#ifndef VBAT_RAW_TO_SCALED
scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw;
#else
scaled = VBAT_RAW_TO_SCALED(raw); // defined in variant.h
#endif // VBAT RAW TO SCALED
#endif // ARCH_ESP32
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled));
last_read_value = scaled; last_read_value = scaled;
return scaled; return scaled;
} else { } else {
return last_read_value; return last_read_value;
} }
#else
return 0;
#endif // BATTERY_PIN #endif // BATTERY_PIN
return 0;
} }
#if defined(ARCH_ESP32) && !defined(HAS_PMU) && defined(BATTERY_PIN)
/**
* ESP32 specific function for getting calibrated ADC reads
*/
uint32_t espAdcRead()
{
uint32_t raw = 0;
#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++) {
raw += adc1_get_raw(adc_channel);
}
#ifdef ADC_CTRL
if (heltec_version == 5) {
digitalWrite(ADC_CTRL, LOW);
}
#endif
#else // ADC2
int32_t adc_buf = 0;
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
// ADC2 wifi bug workaround, see
// https://github.com/espressif/arduino-esp32/issues/102
WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, RTC_reg_b);
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
adc2_get_raw(adc_channel, ADC_WIDTH_BIT_12, &adc_buf);
raw += adc_buf;
}
#endif // BAT_MEASURE_ADC_UNIT
raw = raw / BATTERY_SENSE_SAMPLES;
return raw;
}
#endif
/** /**
* return true if there is a battery installed in this unit * return true if there is a battery installed in this unit
*/ */
@ -894,4 +900,4 @@ bool Power::axpChipInit()
#else #else
return false; return false;
#endif #endif
} }

View File

@ -363,6 +363,13 @@ void setup()
Wire.begin(); Wire.begin();
#elif defined(I2C_SDA) && !defined(ARCH_RP2040) #elif defined(I2C_SDA) && !defined(ARCH_RP2040)
Wire.begin(I2C_SDA, I2C_SCL); Wire.begin(I2C_SDA, I2C_SCL);
#elif defined(ARCH_PORTDUINO)
if (settingsStrings[i2cdev] != "") {
LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev]);
Wire.begin(settingsStrings[i2cdev].c_str());
} else {
LOG_INFO("No I2C device configured, skipping.\n");
}
#elif HAS_WIRE #elif HAS_WIRE
Wire.begin(); Wire.begin();
#endif #endif
@ -408,8 +415,9 @@ void setup()
// We need to scan here to decide if we have a screen for nodeDB.init() and because power has been applied to // We need to scan here to decide if we have a screen for nodeDB.init() and because power has been applied to
// accessories // accessories
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire()); auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
#ifdef HAS_WIRE
LOG_INFO("Scanning for i2c devices...\n"); LOG_INFO("Scanning for i2c devices...\n");
#endif
#if defined(I2C_SDA1) && defined(ARCH_RP2040) #if defined(I2C_SDA1) && defined(ARCH_RP2040)
Wire1.setSDA(I2C_SDA1); Wire1.setSDA(I2C_SDA1);
@ -429,6 +437,11 @@ void setup()
#elif defined(I2C_SDA) && !defined(ARCH_RP2040) #elif defined(I2C_SDA) && !defined(ARCH_RP2040)
Wire.begin(I2C_SDA, I2C_SCL); Wire.begin(I2C_SDA, I2C_SCL);
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE); i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
#elif defined(ARCH_PORTDUINO)
if (settingsStrings[i2cdev] != "") {
LOG_INFO("Scanning for i2c devices...\n");
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
}
#elif HAS_WIRE #elif HAS_WIRE
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE); i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
#endif #endif

View File

@ -15,6 +15,7 @@ Channels channels;
const char *Channels::adminChannel = "admin"; const char *Channels::adminChannel = "admin";
const char *Channels::gpioChannel = "gpio"; const char *Channels::gpioChannel = "gpio";
const char *Channels::serialChannel = "serial"; const char *Channels::serialChannel = "serial";
const char *Channels::mqttChannel = "mqtt";
uint8_t xorHash(const uint8_t *p, size_t len) uint8_t xorHash(const uint8_t *p, size_t len)
{ {
@ -313,4 +314,4 @@ bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
int16_t Channels::setActiveByIndex(ChannelIndex channelIndex) int16_t Channels::setActiveByIndex(ChannelIndex channelIndex)
{ {
return setCrypto(channelIndex); return setCrypto(channelIndex);
} }

View File

@ -32,7 +32,7 @@ class Channels
Channels() {} Channels() {}
/// Well known channel names /// Well known channel names
static const char *adminChannel, *gpioChannel, *serialChannel; static const char *adminChannel, *gpioChannel, *serialChannel, *mqttChannel;
const meshtastic_ChannelSettings &getPrimary() { return getByIndex(getPrimaryIndex()).settings; } const meshtastic_ChannelSettings &getPrimary() { return getByIndex(getPrimaryIndex()).settings; }
@ -139,4 +139,4 @@ class Channels
}; };
/// Singleton channel table /// Singleton channel table
extern Channels channels; extern Channels channels;

View File

@ -134,6 +134,8 @@ typedef struct _meshtastic_AdminMessage {
/* Enter (UF2) DFU mode /* Enter (UF2) DFU mode
Only implemented on NRF52 currently */ Only implemented on NRF52 currently */
bool enter_dfu_mode_request; bool enter_dfu_mode_request;
/* Delete the file by the specified path from the device */
char delete_file_request[201];
/* Set the owner for this node */ /* Set the owner for this node */
meshtastic_User set_owner; meshtastic_User set_owner;
/* Set channels (using the new API). /* Set channels (using the new API).
@ -228,6 +230,7 @@ extern "C" {
#define meshtastic_AdminMessage_get_node_remote_hardware_pins_request_tag 19 #define meshtastic_AdminMessage_get_node_remote_hardware_pins_request_tag 19
#define meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag 20 #define meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag 20
#define meshtastic_AdminMessage_enter_dfu_mode_request_tag 21 #define meshtastic_AdminMessage_enter_dfu_mode_request_tag 21
#define meshtastic_AdminMessage_delete_file_request_tag 22
#define meshtastic_AdminMessage_set_owner_tag 32 #define meshtastic_AdminMessage_set_owner_tag 32
#define meshtastic_AdminMessage_set_channel_tag 33 #define meshtastic_AdminMessage_set_channel_tag 33
#define meshtastic_AdminMessage_set_config_tag 34 #define meshtastic_AdminMessage_set_config_tag 34
@ -266,6 +269,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_ham_mode,set_ham_mode),
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_node_remote_hardware_pins_request,get_node_remote_hardware_pins_request), 19) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,get_node_remote_hardware_pins_request,get_node_remote_hardware_pins_request), 19) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_node_remote_hardware_pins_response,get_node_remote_hardware_pins_response), 20) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_node_remote_hardware_pins_response,get_node_remote_hardware_pins_response), 20) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,enter_dfu_mode_request,enter_dfu_mode_request), 21) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,enter_dfu_mode_request,enter_dfu_mode_request), 21) \
X(a, STATIC, ONEOF, STRING, (payload_variant,delete_file_request,delete_file_request), 22) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_owner,set_owner), 32) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_owner,set_owner), 32) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 33) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 33) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_config,set_config), 34) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_config,set_config), 34) \

View File

@ -3,6 +3,7 @@
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include <FSCommon.h>
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "BleOta.h" #include "BleOta.h"
#endif #endif
@ -194,6 +195,15 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
#endif #endif
break; break;
} }
case meshtastic_AdminMessage_delete_file_request_tag: {
LOG_DEBUG("Client is requesting to delete file: %s\n", r->delete_file_request);
if (FSCom.remove(r->delete_file_request)) {
LOG_DEBUG("Successfully deleted file\n");
} else {
LOG_DEBUG("Failed to delete file\n");
}
break;
}
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
case meshtastic_AdminMessage_exit_simulator_tag: case meshtastic_AdminMessage_exit_simulator_tag:
LOG_INFO("Exiting simulator\n"); LOG_INFO("Exiting simulator\n");

View File

@ -17,7 +17,6 @@
#include "mesh/wifi/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#include <WiFi.h> #include <WiFi.h>
#endif #endif
#include "mqtt/JSON.h"
#include <assert.h> #include <assert.h>
const int reconnectMax = 5; const int reconnectMax = 5;
@ -49,8 +48,6 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
payloadStr[length] = 0; // null terminated string payloadStr[length] = 0; // null terminated string
JSONValue *json_value = JSON::Parse(payloadStr); JSONValue *json_value = JSON::Parse(payloadStr);
if (json_value != NULL) { if (json_value != NULL) {
LOG_INFO("JSON Received on MQTT, parsing..\n");
// check if it is a valid envelope // check if it is a valid envelope
JSONObject json; JSONObject json;
json = json_value->AsObject(); json = json_value->AsObject();
@ -61,22 +58,21 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
ptr = strtok(NULL, "/"); ptr = strtok(NULL, "/");
} }
meshtastic_Channel sendChannel = channels.getByName(ptr); meshtastic_Channel sendChannel = channels.getByName(ptr);
LOG_DEBUG("Found Channel name: %s (Index %d)\n", channels.getGlobalId(sendChannel.index), sendChannel.index); // We allow downlink JSON packets only on a channel named "mqtt"
if (strncasecmp(channels.getGlobalId(sendChannel.index), Channels::mqttChannel, strlen(Channels::mqttChannel)) == 0 &&
sendChannel.settings.downlink_enabled) {
if (isValidJsonEnvelope(json)) {
// this is a valid envelope
if (json["type"]->AsString().compare("sendtext") == 0 && json["payload"]->IsString()) {
std::string jsonPayloadStr = json["payload"]->AsString();
LOG_INFO("JSON payload %s, length %u\n", jsonPayloadStr.c_str(), jsonPayloadStr.length());
if ((json.find("sender") != json.end()) && (json.find("payload") != json.end()) && // construct protobuf data packet using TEXT_MESSAGE, send it to the mesh
(json.find("type") != json.end()) && json["type"]->IsString() && meshtastic_MeshPacket *p = router->allocForSending();
(json["type"]->AsString().compare("sendtext") == 0)) { p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
// this is a valid envelope p->channel = sendChannel.index;
if (json["payload"]->IsString() && json["type"]->IsString() && if (json.find("to") != json.end() && json["to"]->IsNumber())
(json["sender"]->AsString().compare(owner.id) != 0)) { p->to = json["to"]->AsNumber();
std::string jsonPayloadStr = json["payload"]->AsString();
LOG_INFO("JSON payload %s, length %u\n", jsonPayloadStr.c_str(), jsonPayloadStr.length());
// construct protobuf data packet using TEXT_MESSAGE, send it to the mesh
meshtastic_MeshPacket *p = router->allocForSending();
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
p->channel = sendChannel.index;
if (sendChannel.settings.downlink_enabled) {
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();
@ -85,49 +81,42 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
} else { } else {
LOG_WARN("Received MQTT json payload too long, dropping\n"); LOG_WARN("Received MQTT json payload too long, dropping\n");
} }
} else { } else if (json["type"]->AsString().compare("sendposition") == 0 && json["payload"]->IsObject()) {
LOG_WARN("Received MQTT json payload on channel %s, but downlink is disabled, dropping\n", // invent the "sendposition" type for a valid envelope
sendChannel.settings.name); JSONObject posit;
} posit = json["payload"]->AsObject(); // get nested JSON Position
} else { meshtastic_Position pos = meshtastic_Position_init_default;
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n"); if (posit.find("latitude_i") != posit.end() && posit["latitude_i"]->IsNumber())
} pos.latitude_i = posit["latitude_i"]->AsNumber();
} else if ((json.find("sender") != json.end()) && (json.find("payload") != json.end()) && if (posit.find("longitude_i") != posit.end() && posit["longitude_i"]->IsNumber())
(json.find("type") != json.end()) && json["type"]->IsString() && pos.longitude_i = posit["longitude_i"]->AsNumber();
(json["type"]->AsString().compare("sendposition") == 0)) { if (posit.find("altitude") != posit.end() && posit["altitude"]->IsNumber())
// invent the "sendposition" type for a valid envelope pos.altitude = posit["altitude"]->AsNumber();
if (json["payload"]->IsObject() && json["type"]->IsString() && if (posit.find("time") != posit.end() && posit["time"]->IsNumber())
(json["sender"]->AsString().compare(owner.id) != 0)) { pos.time = posit["time"]->AsNumber();
JSONObject posit;
posit = json["payload"]->AsObject(); // get nested JSON Position
meshtastic_Position pos = meshtastic_Position_init_default;
pos.latitude_i = posit["latitude_i"]->AsNumber();
pos.longitude_i = posit["longitude_i"]->AsNumber();
pos.altitude = posit["altitude"]->AsNumber();
pos.time = posit["time"]->AsNumber();
// construct protobuf data packet using POSITION, send it to the mesh // construct protobuf data packet using POSITION, send it to the mesh
meshtastic_MeshPacket *p = router->allocForSending(); meshtastic_MeshPacket *p = router->allocForSending();
p->decoded.portnum = meshtastic_PortNum_POSITION_APP; p->decoded.portnum = meshtastic_PortNum_POSITION_APP;
p->channel = sendChannel.index; p->channel = sendChannel.index;
if (sendChannel.settings.downlink_enabled) { if (json.find("to") != json.end() && json["to"]->IsNumber())
p->to = json["to"]->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
service.sendToMesh(p, RX_SRC_LOCAL); service.sendToMesh(p, RX_SRC_LOCAL);
} else { } else {
LOG_WARN("Received MQTT json payload on channel %s, but downlink is disabled, dropping\n", LOG_DEBUG("JSON Ignoring downlink message with unsupported type.\n");
sendChannel.settings.name);
} }
} else { } else {
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n"); LOG_ERROR("JSON Received payload on MQTT but not a valid envelope.\n");
} }
} else { } else {
LOG_ERROR("JSON Received payload on MQTT but not a valid envelope\n"); LOG_WARN("JSON downlink received on channel not called 'mqtt' or without downlink enabled.\n");
} }
} else { } else {
// no json, this is an invalid payload // no json, this is an invalid payload
LOG_ERROR("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length); LOG_ERROR("JSON Received payload on MQTT but not a valid JSON\n");
} }
delete json_value; delete json_value;
} else { } else {
@ -818,4 +807,14 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
delete value; delete value;
return jsonStr; return jsonStr;
}
bool MQTT::isValidJsonEnvelope(JSONObject &json)
{
// if "sender" is provided, avoid processing packets we uplinked
return (json.find("sender") != json.end() ? (json["sender"]->AsString().compare(owner.id) != 0) : true) &&
(json.find("from") != json.end()) && json["from"]->IsNumber() &&
(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("payload") != json.end()); // should have a payload
} }

View File

@ -5,6 +5,7 @@
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "mesh/Channels.h" #include "mesh/Channels.h"
#include "mesh/generated/meshtastic/mqtt.pb.h" #include "mesh/generated/meshtastic/mqtt.pb.h"
#include "mqtt/JSON.h"
#if HAS_WIFI #if HAS_WIFI
#include <WiFiClient.h> #include <WiFiClient.h>
#define HAS_NETWORKING 1 #define HAS_NETWORKING 1
@ -100,6 +101,9 @@ class MQTT : private concurrency::OSThread
void publishStatus(); void publishStatus();
void publishQueuedMessages(); void publishQueuedMessages();
// returns true if this is a valid JSON envelope which we accept on downlink
bool isValidJsonEnvelope(JSONObject &json);
/// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server /// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server
// int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; } // int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; }
}; };

View File

@ -150,6 +150,9 @@ void portduinoSetup()
settingsMap[has_gps] = 1; settingsMap[has_gps] = 1;
} }
} }
if (yamlConfig["I2C"]) {
settingsStrings[i2cdev] = yamlConfig["I2C"]["I2CDevice"].as<std::string>("");
}
settingsMap[displayPanel] = no_screen; settingsMap[displayPanel] = no_screen;
if (yamlConfig["Display"]) { if (yamlConfig["Display"]) {
if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7789") if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7789")

View File

@ -16,6 +16,7 @@ enum configNames {
user, user,
gpiochip, gpiochip,
spidev, spidev,
i2cdev,
has_gps, has_gps,
touchscreenModule, touchscreenModule,
touchscreenCS, touchscreenCS,

View File

@ -80,6 +80,7 @@ static const uint8_t A5 = PIN_A5;
// Other pins // Other pins
#define PIN_AREF PIN_A5 #define PIN_AREF PIN_A5
#define PIN_VBAT PIN_A4 #define PIN_VBAT PIN_A4
#define BATTERY_PIN PIN_VBAT
#define PIN_NFC1 (33) #define PIN_NFC1 (33)
#define PIN_NFC2 (2) #define PIN_NFC2 (2)
#define PIN_PIEZO (37) #define PIN_PIEZO (37)

View File

@ -100,6 +100,7 @@ static const uint8_t A5 = PIN_A5;
// Other pins // Other pins
#define PIN_AREF PIN_A5 #define PIN_AREF PIN_A5
#define PIN_VBAT PIN_A4 #define PIN_VBAT PIN_A4
#define BATTERY_PIN PIN_VBAT
#define PIN_NFC1 (33) #define PIN_NFC1 (33)
#define PIN_NFC2 (2) #define PIN_NFC2 (2)
#define PIN_PIEZO (37) #define PIN_PIEZO (37)

View File

@ -170,7 +170,7 @@ External serial flash W25Q16JV_IQ
// Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K)) // Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K))
#define VBAT_DIVIDER (0.5F) #define VBAT_DIVIDER (0.5F)
// Compensation factor for the VBAT divider // Compensation factor for the VBAT divider
#define VBAT_DIVIDER_COMP (2.0) #define VBAT_DIVIDER_COMP (2.0F)
// Fixed calculation of milliVolt from compensation value // Fixed calculation of milliVolt from compensation value
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#undef AREF_VOLTAGE #undef AREF_VOLTAGE

View File

@ -1,3 +1,2 @@
#define HAS_WIRE 1
#define HAS_SCREEN 1 #define HAS_SCREEN 1
#define CANNED_MESSAGE_MODULE_ENABLE 1 #define CANNED_MESSAGE_MODULE_ENABLE 1

View File

@ -56,6 +56,8 @@ static const uint8_t SCK = 33;
#define LED_PIN LED_BLUE #define LED_PIN LED_BLUE
#define PIN_VBAT WB_A0 #define PIN_VBAT WB_A0
#define BATTERY_PIN PIN_VBAT
#define ADC_CHANNEL ADC1_GPIO36_CHANNEL
// https://docs.rakwireless.com/Product-Categories/WisBlock/RAK13300/ // https://docs.rakwireless.com/Product-Categories/WisBlock/RAK13300/

View File

@ -12,6 +12,7 @@
// #define EXT_NOTIFY_OUT 4 // #define EXT_NOTIFY_OUT 4
#define BATTERY_PIN 26 #define BATTERY_PIN 26
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
// ratio of voltage divider = 3.0 (R17=200k, R18=100k) // ratio of voltage divider = 3.0 (R17=200k, R18=100k)
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic #define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic

View File

@ -254,7 +254,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M)) // Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))
#define VBAT_DIVIDER (0.4F) #define VBAT_DIVIDER (0.4F)
// Compensation factor for the VBAT divider // Compensation factor for the VBAT divider
#define VBAT_DIVIDER_COMP (1.73) #define VBAT_DIVIDER_COMP (1.73F)
// Fixed calculation of milliVolt from compensation value // Fixed calculation of milliVolt from compensation value
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#undef AREF_VOLTAGE #undef AREF_VOLTAGE

View File

@ -223,7 +223,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M)) // Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))
#define VBAT_DIVIDER (0.4F) #define VBAT_DIVIDER (0.4F)
// Compensation factor for the VBAT divider // Compensation factor for the VBAT divider
#define VBAT_DIVIDER_COMP (1.73) #define VBAT_DIVIDER_COMP (1.73F)
// Fixed calculation of milliVolt from compensation value // Fixed calculation of milliVolt from compensation value
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#undef AREF_VOLTAGE #undef AREF_VOLTAGE

View File

@ -22,6 +22,7 @@
#define BATTERY_PIN 26 #define BATTERY_PIN 26
// ratio of voltage divider = 3.0 (R17=200k, R18=100k) // ratio of voltage divider = 3.0 (R17=200k, R18=100k)
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic #define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
#define USE_SX1262 #define USE_SX1262

View File

@ -24,6 +24,7 @@
#define BATTERY_PIN 26 #define BATTERY_PIN 26
// ratio of voltage divider = 3.0 (R17=200k, R18=100k) // ratio of voltage divider = 3.0 (R17=200k, R18=100k)
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic #define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
#define USE_SX1262 #define USE_SX1262

View File

@ -8,6 +8,7 @@
#define LED_PIN PIN_LED #define LED_PIN PIN_LED
#undef BATTERY_PIN #undef BATTERY_PIN
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
#undef LORA_SCK #undef LORA_SCK
#undef LORA_MISO #undef LORA_MISO

View File

@ -213,7 +213,7 @@ External serial flash WP25R1635FZUIL0
// Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K)) // Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K))
#define VBAT_DIVIDER (0.5F) #define VBAT_DIVIDER (0.5F)
// Compensation factor for the VBAT divider // Compensation factor for the VBAT divider
#define VBAT_DIVIDER_COMP (2.0) #define VBAT_DIVIDER_COMP (2.0F)
// Fixed calculation of milliVolt from compensation value // Fixed calculation of milliVolt from compensation value
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#undef AREF_VOLTAGE #undef AREF_VOLTAGE