From e57d356fd1afc2e3be333ccfe214e289d8df3017 Mon Sep 17 00:00:00 2001 From: richonguzman Date: Mon, 8 Jul 2024 23:02:45 -0400 Subject: [PATCH] new ADC calibration test --- platformio.ini | 2 + src/LoRa_APRS_iGate.cpp | 4 +- src/battery_utils.cpp | 120 +++++++++++++++++++++++++++++++++------- src/battery_utils.h | 3 + 4 files changed, 108 insertions(+), 21 deletions(-) diff --git a/platformio.ini b/platformio.ini index 6f91970..10a5102 100644 --- a/platformio.ini +++ b/platformio.ini @@ -46,6 +46,7 @@ build_flags = -Werror -Wall -DTTGO_T_LORA32_V2_1 -DHAS_SX1278 + -DHAS_ADC_CALIBRATION -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ${common.lib_deps} @@ -58,6 +59,7 @@ build_flags = -Werror -Wall -DTTGO_T_LORA32_V2_1_915 -DHAS_SX1276 + -DHAS_ADC_CALIBRATION -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ${common.lib_deps} diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 410679a..aae7d46 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -21,6 +21,7 @@ ________________________________________________________________________________ #include "aprs_is_utils.h" #include "station_utils.h" #include "boards_pinout.h" +#include "battery_utils.h" #include "syslog_utils.h" #include "query_utils.h" #include "power_utils.h" @@ -37,7 +38,7 @@ ________________________________________________________________________________ #include "A7670_utils.h" #endif -String versionDate = "2024.06.28"; +String versionDate = "2024.07.08"; Configuration Config; WiFiClient espClient; @@ -60,6 +61,7 @@ String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seven void setup() { Serial.begin(115200); POWER_Utils::setup(); + BATTERY_Utils::setup(); Utils::setupDisplay(); Config.check(); LoRa_Utils::setup(); diff --git a/src/battery_utils.cpp b/src/battery_utils.cpp index 2d46bd4..e2e3311 100644 --- a/src/battery_utils.cpp +++ b/src/battery_utils.cpp @@ -5,15 +5,42 @@ #include "power_utils.h" #include "utils.h" -extern Configuration Config; -extern uint32_t lastBatteryCheck; +extern Configuration Config; +extern uint32_t lastBatteryCheck; -bool shouldSleepLowVoltage = false; +bool shouldSleepLowVoltage = false; + +float adcReadingTransformation = (3.3/4095); +float voltageDividerCorrection = 0.288; +float readingCorrection = 0.125; +float multiplyCorrection = 0.035; +float adcVoltageCorrection = 0.041; + +float voltageDividerTransformation = 0.0; + + +#ifdef HAS_ADC_CALIBRATION + #include + + #if defined(TTGO_T_LORA32_V2_1) || defined(TTGO_T_LORA32_V2_1_915) + #define InternalBattery_ADC_Channel ADC1_CHANNEL_7 // t_lora32 pin35 + #define ExternalVoltage_ADC_Channel ADC1_CHANNEL_6 // t_lora32 pin34 + #endif + + #if CONFIG_IDF_TARGET_ESP32 + #define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_VREF + #elif CONFIG_IDF_TARGET_ESP32S2 + #define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP + #elif CONFIG_IDF_TARGET_ESP32C3 + #define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP + #elif CONFIG_IDF_TARGET_ESP32S3 + #define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP_FIT + #endif + + esp_adc_cal_characteristics_t adc_chars; + bool calibrationEnable = false; +#endif -float adcReadingTransformation = (3.3/4095); -float voltageDividerCorrection = 0.288; -float readingCorrection = 0.125; -float multiplyCorrection = 0.035; namespace BATTERY_Utils { @@ -22,6 +49,40 @@ namespace BATTERY_Utils { return (voltage - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } + void adcCalibration() { + if (calibrationEnable) { + adc1_config_width(ADC_WIDTH_BIT_12); + adc1_config_channel_atten(InternalBattery_ADC_Channel, ADC_ATTEN_DB_12); + adc1_config_channel_atten(ExternalVoltage_ADC_Channel, ADC_ATTEN_DB_12); + } + } + + void adcCalibrationCheck() { + esp_err_t ret; + ret = esp_adc_cal_check_efuse(ADC_EXAMPLE_CALI_SCHEME); + /*if (ret == ESP_ERR_NOT_SUPPORTED) { + Serial.println("Calibration scheme not supported, skip software calibration"); + } else if (ret == ESP_ERR_INVALID_VERSION) { + Serial.println("eFuse not burnt, skip software calibration"); + } else */ + if (ret == ESP_OK) { + esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_12, 1100, &adc_chars); + //Serial.printf("eFuse Vref:%u mV\n", adc_chars.vref); + calibrationEnable = true; + } /*else { + Serial.println("Invalid Calibration Arg"); + }*/ + } + + void setup() { + if (Config.battery.voltageDividerR2 != 0) voltageDividerTransformation = (Config.battery.voltageDividerR1 + Config.battery.voltageDividerR2) / Config.battery.voltageDividerR2; + + #if defined(HAS_ADC_CALIBRATION) + adcCalibrationCheck(); + adcCalibration(); + #endif + } + float checkInternalVoltage() { #if defined(HAS_AXP192) || defined(HAS_AXP2101) if(POWER_Utils::isBatteryConnected()) { @@ -42,12 +103,15 @@ namespace BATTERY_Utils { #endif for (int i = 0; i < 100; i++) { - #ifdef BATTERY_PIN - sample = analogRead(BATTERY_PIN); - #endif - #if defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa) + #if defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_LoRa_915) || defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915) sample = 0; - #endif + #else + if (calibrationEnable) { + sample = adc1_get_raw(InternalBattery_ADC_Channel); + } else { + sample = analogRead(BATTERY_PIN); + } + #endif sampleSum += sample; delayMicroseconds(50); } @@ -62,9 +126,16 @@ namespace BATTERY_Utils { double inputDivider = (1.0 / (390.0 + 100.0)) * 100.0; // The voltage divider is a 390k + 100k resistor in series, 100k on the low side. return (((sampleSum/100) * adcReadingTransformation) / inputDivider) + 0.285; // Yes, this offset is excessive, but the ADC on the ESP32s3 is quite inaccurate and noisy. Adjust to own measurements. #else - return (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection; // raw voltage without mapping + if (calibrationEnable){ + float voltage = esp_adc_cal_raw_to_voltage(sampleSum / 100, &adc_chars); + voltage *= 2; // for 100K/100K voltage divider + voltage /= 1000; + voltage -= adcVoltageCorrection; + return voltage; + } else { + return (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection; // raw voltage without mapping + } #endif - // return mapVoltage(voltage, 3.34, 4.71, 3.0, 4.2); // mapped voltage #endif } @@ -73,14 +144,23 @@ namespace BATTERY_Utils { int sample; int sampleSum = 0; for (int i = 0; i < 100; i++) { - sample = analogRead(Config.battery.externalVoltagePin); + if(calibrationEnable){ + sample = adc1_get_raw(ExternalVoltage_ADC_Channel); + } else { + sample = analogRead(Config.battery.externalVoltagePin); + } sampleSum += sample; - delayMicroseconds(50); + delayMicroseconds(50); } - float voltageDividerTransformation = (Config.battery.voltageDividerR1 + Config.battery.voltageDividerR2) / Config.battery.voltageDividerR2; - float voltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection; - - return voltage; // raw voltage without mapping + + float extVoltage; + if (calibrationEnable){ + extVoltage = esp_adc_cal_raw_to_voltage(sampleSum / 100, &adc_chars) * voltageDividerTransformation; // in mV + extVoltage /= 1000; + } else { + extVoltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection; + } + return extVoltage; // raw voltage without mapping // return mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage } diff --git a/src/battery_utils.h b/src/battery_utils.h index 4bc0dd9..57153c3 100644 --- a/src/battery_utils.h +++ b/src/battery_utils.h @@ -6,6 +6,9 @@ namespace BATTERY_Utils { + void adcCalibration(); + void adcCalibrationCheck(); + void setup(); float checkInternalVoltage(); float checkExternalVoltage(); void checkIfShouldSleep(); // ????