feat: ADC-поправка батареи для всех плат, вариант A на экране загрузки

- ESP32Board: общий механизм adcMultiplierBase()/adcMultiplier(); setAdcMultiplier
  возвращает false только там, где батарея измеряется не через ADC
- платы со своей формулой переведены на общий механизм: Heltec E213/E290/T190,
  heltec_tracker_v2, Heltec v2, ThinkNode M2/M5; Station G2/G3 и T-Beam сообщают,
  что подстройка не поддерживается
- мастер настройки: поле ADC стартует от действующего значения платы
  (getAdcMultiplier) и работает с тремя знаками (x.xxx), например 5.420;
  0.000 возвращает заводское значение платы
- Meshadventurer: добавлена поддержка множителя (раньше делитель был зашит числом 2
  и set adc.multiplier отвечал Error: unsupported)
- экран загрузки: meshcore.io, версия с датой и posadmesh.ru; строка < Repeater > убрана

Проверено сборкой: heltec_v4_repeater_mqtt, Meshadventurer_sx1262_repeater_mqtt
This commit is contained in:
shade committed 2026-10-16 11:35:07 +03:00
1 parent 82ec2f4c83
commit b3a6be4a7f
19 files changed
+86 -33

No files matched your search

+21 -24
View File
@@ -240,21 +240,23 @@ void UITask::beginBwEdit() {
}
void UITask::beginAdcEdit() {
// Множитель ADC: x.xx, где 0.00 означает «использовать заводское значение платы»
// Множитель ADC: x.xxx. Стартуем от значения платы — базового или уже
// сохранённого, а не от нуля; 0.000 в поле означает «вернуть заводское значение».
_digit_int = 1;
_digit_count = 3;
_digit_count = 4;
for (int i = 0; i < _digit_count; i++) _digit_applied[i] = false;
_digit_index = 0;
_digit_editing = false;
float v = _node_prefs ? _node_prefs->adc_multiplier : 0.0f;
float v = _board ? _board->getAdcMultiplier() : 0.0f;
if (v <= 0.0f && _node_prefs) v = _node_prefs->adc_multiplier;
if (v < 0) v = 0;
if (v > 9.99f) v = 9.99f;
if (v > 9.999f) v = 9.999f;
int ip = (int)v;
int fp = (int)((v - ip) * 100.0f + 0.5f);
if (fp > 99) { fp = 0; ip++; }
int fp = (int)((v - ip) * 1000.0f + 0.5f);
if (fp > 999) { fp = 0; ip++; }
char buf[8];
snprintf(buf, sizeof(buf), "%d%02d", ip % 10, fp);
snprintf(buf, sizeof(buf), "%d%03d", ip % 10, fp);
memcpy(_digit_digits, buf, _digit_count);
_screen = SCREEN_DIGITS;
}
@@ -272,9 +274,9 @@ double UITask::digitValue() const {
void UITask::applyDigits() {
if (_menu_index == MENU_ADC) {
char cmd[48];
snprintf(cmd, sizeof(cmd), "set adc.multiplier %d.%02d",
snprintf(cmd, sizeof(cmd), "set adc.multiplier %d.%03d",
_digit_digits[0] - '0',
(_digit_digits[1] - '0') * 10 + (_digit_digits[2] - '0'));
(_digit_digits[1] - '0') * 100 + (_digit_digits[2] - '0') * 10 + (_digit_digits[3] - '0'));
runCommand(cmd);
return;
}
@@ -886,11 +888,14 @@ void UITask::renderBattery() {
if (fill > 0) _display->fillRect(4, 29, fill, 5);
}
const float adc = _node_prefs ? _node_prefs->adc_multiplier : 0.0f;
if (adc > 0.0f) {
snprintf(line, sizeof(line), "ADC %.3f", (double)adc);
// Текущий множитель ADC: показываем действующее значение платы и помечаем,
// что оно заводское (в настройках 0 = «использовать базовое значение платы»)
const float adc_eff = _board ? _board->getAdcMultiplier() : 0.0f;
const bool adc_is_base = (_node_prefs == nullptr) || (_node_prefs->adc_multiplier <= 0.0f);
if (adc_eff > 0.0f) {
snprintf(line, sizeof(line), "ADC %.3f%s", (double)adc_eff, adc_is_base ? " base" : "");
} else {
snprintf(line, sizeof(line), "ADC default");
snprintf(line, sizeof(line), "ADC n/a");
}
_display->setColor(UIColor::primary_txt);
_display->setCursor(2, 40);
@@ -1048,19 +1053,11 @@ void UITask::renderCurrScreen() {
int logoWidth = 128;
_display->drawXbm((_display->width() - logoWidth) / 2, 3, meshcore_logo, logoWidth, 13);
// meshcore website
const char* website = "https://meshcore.io";
_display->setColor(UIColor::primary_txt);
_display->setTextSize(1);
_display->drawTextCentered(_display->width() / 2, 22, website);
// version info
_display->setTextSize(1);
_display->drawTextCentered(_display->width() / 2, 35, _version_info);
// node type
const char* node_type = "< Repeater >";
_display->drawTextCentered(_display->width() / 2, 48, node_type);
_display->drawTextCentered(_display->width() / 2, 20, "meshcore.io");
_display->drawTextCentered(_display->width() / 2, 32, _version_info);
_display->drawTextCentered(_display->width() / 2, 44, "posadmesh.ru");
return;
}
+20 -1
View File
@@ -140,6 +140,25 @@ public:
}
#endif
// --- Поправка ADC для измерения батареи ------------------------------------
// adcMultiplierBase() — заводской множитель делителя у этой платы.
// 0 означает, что плата не измеряет батарею через ADC (например питается
// через PMU), и подстройка множителя не поддерживается.
virtual float adcMultiplierBase() const { return 2.0f; } // базовая реализация ниже делит на 2
bool setAdcMultiplier(float multiplier) override {
if (adcMultiplierBase() <= 0.0f) return false;
_adc_mult = multiplier; // 0 = вернуть заводское значение платы
return true;
}
float getAdcMultiplier() const override { return adcMultiplier(); }
protected:
float adcMultiplier() const { return _adc_mult > 0.0f ? _adc_mult : adcMultiplierBase(); }
private:
float _adc_mult = 0.0f;
public:
uint16_t getBattMilliVolts() override {
#ifdef PIN_VBAT_READ
analogReadResolution(12);
@@ -150,7 +169,7 @@ public:
}
raw = raw / 4;
return (2 * raw);
return (uint16_t)(adcMultiplier() * raw);
#else
return 0; // not supported
#endif
+2
View File
@@ -154,6 +154,8 @@ public:
esp_deep_sleep_start(); // CPU halts here and never returns!
}
// батарея измеряется не через ADC (или не измеряется) — подстройка множителя не поддерживается
float adcMultiplierBase() const override { return 0.0f; }
uint16_t getBattMilliVolts() override {
return PMU != NULL ? PMU->getBattVoltage() : 0;
}
+1 -1
View File
@@ -32,7 +32,7 @@ void HeltecE213Board::begin() {
digitalWrite(PIN_ADC_CTRL, LOW);
return (5.42 * (3.3 / 1024.0) * raw) * 1000;
return (adcMultiplier() * (3.3 / 1024.0) * raw) * 1000;
}
const char* HeltecE213Board::getManufacturerName() const {
+1
View File
@@ -12,6 +12,7 @@ public:
HeltecE213Board() : periph_power(PIN_VEXT_EN,PIN_VEXT_EN_ACTIVE) { }
void begin();
float adcMultiplierBase() const override { return 5.42f; } // заводской множитель делителя
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override ;
};
+1 -1
View File
@@ -32,7 +32,7 @@ void HeltecE290Board::begin() {
digitalWrite(PIN_ADC_CTRL, LOW);
return (5.42 * (3.3 / 1024.0) * raw) * 1000;
return (adcMultiplier() * (3.3 / 1024.0) * raw) * 1000;
}
const char* HeltecE290Board::getManufacturerName() const {
+1
View File
@@ -12,6 +12,7 @@ public:
HeltecE290Board() : periph_power(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE) { }
void begin();
float adcMultiplierBase() const override { return 5.42f; } // заводской множитель делителя
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override ;
+1 -1
View File
@@ -32,7 +32,7 @@ void HeltecT190Board::begin() {
digitalWrite(PIN_ADC_CTRL, LOW);
return (5.42 * (3.3 / 1024.0) * raw) * 1000;
return (adcMultiplier() * (3.3 / 1024.0) * raw) * 1000;
}
const char* HeltecT190Board::getManufacturerName() const {
+1
View File
@@ -12,6 +12,7 @@ public:
HeltecT190Board() : periph_power(PIN_VEXT_EN,PIN_VEXT_EN_ACTIVE) { }
void begin();
float adcMultiplierBase() const override { return 5.42f; } // заводской множитель делителя
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override ;
@@ -55,7 +55,7 @@ void HeltecTrackerV2Board::begin() {
digitalWrite(PIN_ADC_CTRL, LOW);
return (5.42 * (3.3 / 1024.0) * raw) * 1000;
return (adcMultiplier() * (3.3 / 1024.0) * raw) * 1000;
}
const char* HeltecTrackerV2Board::getManufacturerName() const {
@@ -24,6 +24,7 @@ public:
void onBeforeTransmit(void) override;
void onAfterTransmit(void) override;
void powerOff() override;
float adcMultiplierBase() const override { return 5.42f; } // заводской множитель делителя
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override ;
+1 -1
View File
@@ -33,7 +33,7 @@ public:
}
raw = raw / 8;
return (1.98 * (2 / 1024.0) * raw) * 1000;
return (adcMultiplier() * (2 / 1024.0) * raw) * 1000;
}
const char* getManufacturerName() const override {
+18 -1
View File
@@ -17,9 +17,26 @@
#include <driver/rtc_io.h>
// Базовый множитель делителя батареи. variant.h может быть не подключён к этому
// заголовку, поэтому держим значение здесь, как это сделано у других вариантов.
#ifndef ADC_MULTIPLIER
#define ADC_MULTIPLIER 2
#endif
class MeshadventurerBoard : public ESP32Board {
private:
// Базовый множитель делителя батареи из variant.h (ADC_MULTIPLIER).
// Через CLI/мастер настройки его можно подстроить под конкретную плату:
// set adc.multiplier 0 возвращает заводское значение.
float adc_mult = ADC_MULTIPLIER;
public:
bool setAdcMultiplier(float multiplier) override {
adc_mult = (multiplier == 0.0f) ? (float)ADC_MULTIPLIER : multiplier;
return true;
}
float getAdcMultiplier() const override { return adc_mult; }
void begin() {
ESP32Board::begin();
@@ -72,7 +89,7 @@ public:
}
raw = raw / 4;
return (2 * raw);
return (uint16_t)(adc_mult * raw); // множитель делителя, настраивается через set adc.multiplier
}
const char* getManufacturerName() const override {
+2
View File
@@ -20,6 +20,8 @@ public:
}
}
// батарея измеряется не через ADC (или не измеряется) — подстройка множителя не поддерживается
float adcMultiplierBase() const override { return 0.0f; }
uint16_t getBattMilliVolts() override {
return 0;
}
@@ -55,6 +55,8 @@ public:
void powerOff() override;
// батарея измеряется не через ADC (или не измеряется) — подстройка множителя не поддерживается
float adcMultiplierBase() const override { return 0.0f; }
uint16_t getBattMilliVolts() override {
return 0;
}
+5 -1
View File
@@ -1,5 +1,9 @@
#include "ThinknodeM2Board.h"
float ThinknodeM2Board::adcMultiplierBase() const {
return (float)ADC_MULTIPLIER; // заводской множитель делителя из variant.h
}
void ThinknodeM2Board::begin() {
pinMode(PIN_VEXT_EN, OUTPUT);
digitalWrite(PIN_VEXT_EN, !PIN_VEXT_EN_ACTIVE); // force power cycle
@@ -22,7 +26,7 @@ uint16_t ThinknodeM2Board::getBattMilliVolts() {
mv /= 8;
analogReadResolution(10);
return static_cast<uint16_t>(mv * ADC_MULTIPLIER);
return static_cast<uint16_t>(mv * adcMultiplier());
}
const char *ThinknodeM2Board::getManufacturerName() const {
+1
View File
@@ -8,6 +8,7 @@ class ThinknodeM2Board : public ESP32Board {
public:
void begin();
float adcMultiplierBase() const override;
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override ;
+5 -1
View File
@@ -2,6 +2,10 @@
PCA9557 expander (0x18, &Wire1);
float ThinknodeM5Board::adcMultiplierBase() const {
return (float)ADC_MULTIPLIER; // заводской множитель делителя из variant.h
}
void ThinknodeM5Board::begin() {
// Start expander and configure pins
Wire1.begin(48, 47);
@@ -31,7 +35,7 @@ void ThinknodeM5Board::begin() {
mv /= 8;
analogReadResolution(10);
return static_cast<uint16_t>(mv * ADC_MULTIPLIER );
return static_cast<uint16_t>(mv * adcMultiplier() );
}
const char* ThinknodeM5Board::getManufacturerName() const {
+1
View File
@@ -12,6 +12,7 @@ class ThinknodeM5Board : public ESP32Board {
public:
void begin();
float adcMultiplierBase() const override;
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override ;