diff --git a/examples/simple_repeater/UITask.cpp b/examples/simple_repeater/UITask.cpp index 5d37cad1..c377b65c 100644 --- a/examples/simple_repeater/UITask.cpp +++ b/examples/simple_repeater/UITask.cpp @@ -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; } diff --git a/src/helpers/ESP32Board.h b/src/helpers/ESP32Board.h index b38eb958..35396763 100644 --- a/src/helpers/ESP32Board.h +++ b/src/helpers/ESP32Board.h @@ -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 diff --git a/src/helpers/esp32/TBeamBoard.h b/src/helpers/esp32/TBeamBoard.h index 79f9f93f..2867964c 100644 --- a/src/helpers/esp32/TBeamBoard.h +++ b/src/helpers/esp32/TBeamBoard.h @@ -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; } diff --git a/variants/heltec_e213/HeltecE213Board.cpp b/variants/heltec_e213/HeltecE213Board.cpp index 88737c4d..c2b0080b 100644 --- a/variants/heltec_e213/HeltecE213Board.cpp +++ b/variants/heltec_e213/HeltecE213Board.cpp @@ -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 { diff --git a/variants/heltec_e213/HeltecE213Board.h b/variants/heltec_e213/HeltecE213Board.h index fadc038f..04da5bc7 100644 --- a/variants/heltec_e213/HeltecE213Board.h +++ b/variants/heltec_e213/HeltecE213Board.h @@ -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 ; }; diff --git a/variants/heltec_e290/HeltecE290Board.cpp b/variants/heltec_e290/HeltecE290Board.cpp index 96ec59c9..22580e45 100644 --- a/variants/heltec_e290/HeltecE290Board.cpp +++ b/variants/heltec_e290/HeltecE290Board.cpp @@ -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 { diff --git a/variants/heltec_e290/HeltecE290Board.h b/variants/heltec_e290/HeltecE290Board.h index f287227c..af380d9a 100644 --- a/variants/heltec_e290/HeltecE290Board.h +++ b/variants/heltec_e290/HeltecE290Board.h @@ -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 ; diff --git a/variants/heltec_t190/HeltecT190Board.cpp b/variants/heltec_t190/HeltecT190Board.cpp index 0a16b52b..e41df039 100644 --- a/variants/heltec_t190/HeltecT190Board.cpp +++ b/variants/heltec_t190/HeltecT190Board.cpp @@ -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 { diff --git a/variants/heltec_t190/HeltecT190Board.h b/variants/heltec_t190/HeltecT190Board.h index 557c070e..ca7641e7 100644 --- a/variants/heltec_t190/HeltecT190Board.h +++ b/variants/heltec_t190/HeltecT190Board.h @@ -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 ; diff --git a/variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp b/variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp index 753824a0..9a6bd7cd 100644 --- a/variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp +++ b/variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp @@ -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 { diff --git a/variants/heltec_tracker_v2/HeltecTrackerV2Board.h b/variants/heltec_tracker_v2/HeltecTrackerV2Board.h index 5fed2b65..e5f0651a 100644 --- a/variants/heltec_tracker_v2/HeltecTrackerV2Board.h +++ b/variants/heltec_tracker_v2/HeltecTrackerV2Board.h @@ -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 ; diff --git a/variants/heltec_v2/HeltecV2Board.h b/variants/heltec_v2/HeltecV2Board.h index 9b08fe94..d16c4b93 100644 --- a/variants/heltec_v2/HeltecV2Board.h +++ b/variants/heltec_v2/HeltecV2Board.h @@ -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 { diff --git a/variants/meshadventurer/MeshadventurerBoard.h b/variants/meshadventurer/MeshadventurerBoard.h index c8ecd6d2..b5db9974 100644 --- a/variants/meshadventurer/MeshadventurerBoard.h +++ b/variants/meshadventurer/MeshadventurerBoard.h @@ -17,9 +17,26 @@ #include +// Базовый множитель делителя батареи. 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 { diff --git a/variants/station_g2/StationG2Board.h b/variants/station_g2/StationG2Board.h index d1989ee0..23020bdc 100644 --- a/variants/station_g2/StationG2Board.h +++ b/variants/station_g2/StationG2Board.h @@ -20,6 +20,8 @@ public: } } + // батарея измеряется не через ADC (или не измеряется) — подстройка множителя не поддерживается + float adcMultiplierBase() const override { return 0.0f; } uint16_t getBattMilliVolts() override { return 0; } diff --git a/variants/station_g3_esp32/StationG3Board.h b/variants/station_g3_esp32/StationG3Board.h index b4c5838c..18639987 100644 --- a/variants/station_g3_esp32/StationG3Board.h +++ b/variants/station_g3_esp32/StationG3Board.h @@ -55,6 +55,8 @@ public: void powerOff() override; + // батарея измеряется не через ADC (или не измеряется) — подстройка множителя не поддерживается + float adcMultiplierBase() const override { return 0.0f; } uint16_t getBattMilliVolts() override { return 0; } diff --git a/variants/thinknode_m2/ThinknodeM2Board.cpp b/variants/thinknode_m2/ThinknodeM2Board.cpp index 8d68006d..2c7a0d13 100644 --- a/variants/thinknode_m2/ThinknodeM2Board.cpp +++ b/variants/thinknode_m2/ThinknodeM2Board.cpp @@ -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(mv * ADC_MULTIPLIER); + return static_cast(mv * adcMultiplier()); } const char *ThinknodeM2Board::getManufacturerName() const { diff --git a/variants/thinknode_m2/ThinknodeM2Board.h b/variants/thinknode_m2/ThinknodeM2Board.h index 02556777..b5b4d05b 100644 --- a/variants/thinknode_m2/ThinknodeM2Board.h +++ b/variants/thinknode_m2/ThinknodeM2Board.h @@ -8,6 +8,7 @@ class ThinknodeM2Board : public ESP32Board { public: void begin(); + float adcMultiplierBase() const override; uint16_t getBattMilliVolts() override; const char* getManufacturerName() const override ; diff --git a/variants/thinknode_m5/ThinknodeM5Board.cpp b/variants/thinknode_m5/ThinknodeM5Board.cpp index 2cb138e6..aa181eff 100644 --- a/variants/thinknode_m5/ThinknodeM5Board.cpp +++ b/variants/thinknode_m5/ThinknodeM5Board.cpp @@ -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(mv * ADC_MULTIPLIER ); + return static_cast(mv * adcMultiplier() ); } const char* ThinknodeM5Board::getManufacturerName() const { diff --git a/variants/thinknode_m5/ThinknodeM5Board.h b/variants/thinknode_m5/ThinknodeM5Board.h index 57ff0d00..61630198 100644 --- a/variants/thinknode_m5/ThinknodeM5Board.h +++ b/variants/thinknode_m5/ThinknodeM5Board.h @@ -12,6 +12,7 @@ class ThinknodeM5Board : public ESP32Board { public: void begin(); + float adcMultiplierBase() const override; uint16_t getBattMilliVolts() override; const char* getManufacturerName() const override ;