diff --git a/include/configuration.h b/include/configuration.h index dad752e..b59a713 100644 --- a/include/configuration.h +++ b/include/configuration.h @@ -102,7 +102,7 @@ public: int externalVoltagePin; bool monitorExternalVoltage; float externalSleepVoltage; - int externalI2CSensor; + bool useExternalI2CSensor; float voltageDividerR1; float voltageDividerR2; bool sendVoltageAsTelemetry; diff --git a/src/battery_utils.cpp b/src/battery_utils.cpp index 8b52b2e..1c4b6e1 100644 --- a/src/battery_utils.cpp +++ b/src/battery_utils.cpp @@ -16,7 +16,7 @@ * along with LoRa APRS iGate. If not, see . */ -#include +#include #include "battery_utils.h" #include "configuration.h" #include "board_pinout.h" @@ -37,6 +37,11 @@ float multiplyCorrection = 0.035; float voltageDividerTransformation = 0.0; +//bool externalI2CSensorFound = false; +uint8_t externalI2CSensorAddress = 0x00; +int externalI2CSensorType = 0; // 0 = None | 1 = INA219 | 2 = INA226 | 3 = INA3221 + +Adafruit_INA219 ina219; #ifdef HAS_ADC_CALIBRATION @@ -98,6 +103,30 @@ namespace BATTERY_Utils { #endif } + void getI2CVoltageSensorAddress() { + uint8_t err, addr; + for(addr = 1; addr < 0x7F; addr++) { + #if defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY) + Wire1.beginTransmission(addr); + err = Wire1.endTransmission(); + #else + Wire.beginTransmission(addr); + err = Wire.endTransmission(); + #endif + delay(5); + if (err == 0) { + if (addr == 0x40) { // INA219 + externalI2CSensorAddress = addr; + } + } + } + } + + bool detectINA219(uint8_t addr) { + ina219 = Adafruit_INA219(addr); + return ina219.begin(); + } + void setup() { if ((Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) && Config.battery.voltageDividerR2 != 0) voltageDividerTransformation = (Config.battery.voltageDividerR1 + Config.battery.voltageDividerR2) / Config.battery.voltageDividerR2; @@ -107,6 +136,14 @@ namespace BATTERY_Utils { adcCalibration(); } #endif + + getI2CVoltageSensorAddress(); + if (externalI2CSensorAddress != 0x00) { + if (detectINA219(externalI2CSensorAddress)) { + Serial.println("INA219 sensor found"); + externalI2CSensorType = 1; // INA219 + } + } } float checkInternalVoltage() { @@ -177,37 +214,49 @@ namespace BATTERY_Utils { } float checkExternalVoltage() { - int sample; - int sampleSum = 0; - for (int i = 0; i < 100; i++) { - #ifdef HAS_ADC_CALIBRATION - if (calibrationEnable){ - sample = adc1_get_raw(ExternalVoltage_ADC_Channel); - } else { + if (externalI2CSensorType == 0) { + int sample; + int sampleSum = 0; + for (int i = 0; i < 100; i++) { + #ifdef HAS_ADC_CALIBRATION + if (calibrationEnable){ + sample = adc1_get_raw(ExternalVoltage_ADC_Channel); + } else { + sample = analogRead(Config.battery.externalVoltagePin); + } + #else sample = analogRead(Config.battery.externalVoltagePin); + #endif + sampleSum += sample; + delayMicroseconds(50); + } + + float extVoltage; + #ifdef HAS_ADC_CALIBRATION + if (calibrationEnable) { + extVoltage = esp_adc_cal_raw_to_voltage(sampleSum / 100.0, &adc_chars) * voltageDividerTransformation; // in mV + extVoltage /= 1000.0; + } else { + extVoltage = ((((sampleSum/100.0)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection; } #else - sample = analogRead(Config.battery.externalVoltagePin); + extVoltage = ((((sampleSum/100.0)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection; #endif - sampleSum += sample; - delayMicroseconds(50); - } + + return extVoltage; // raw voltage without mapping - float extVoltage; - #ifdef HAS_ADC_CALIBRATION - 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 mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage + } else if (externalI2CSensorType == 1) { // INA219 + int sampleSum = 0; + for (int i = 0; i < 100; i++) { + sampleSum += ina219.getBusVoltage_V() * 1000.0; + delayMicroseconds(50); } - #else - extVoltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection; - #endif - - return extVoltage; // raw voltage without mapping - - // return mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage + float extVoltage = sampleSum/100.0; + return extVoltage/1000.0; + } else { + return 0.0; + } } void startupBatteryHealth() { diff --git a/src/configuration.cpp b/src/configuration.cpp index 3c313f3..c6c08e6 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -113,7 +113,7 @@ bool Configuration::writeFile() { data["battery"]["sendExternalVoltage"] = battery.sendExternalVoltage; data["battery"]["monitorExternalVoltage"] = battery.monitorExternalVoltage; data["battery"]["externalSleepVoltage"] = battery.externalSleepVoltage; - data["battery"]["externalI2CSensor"] = battery.externalI2CSensor; + data["battery"]["useExternalI2CSensor"] = battery.useExternalI2CSensor; data["battery"]["voltageDividerR1"] = battery.voltageDividerR1; data["battery"]["voltageDividerR2"] = battery.voltageDividerR2; data["battery"]["externalVoltagePin"] = battery.externalVoltagePin; @@ -300,7 +300,7 @@ bool Configuration::readFile() { !data["battery"].containsKey("sendExternalVoltage") || !data["battery"].containsKey("monitorExternalVoltage") || !data["battery"].containsKey("externalSleepVoltage") || - !data["battery"].containsKey("externalI2CSensor") || + !data["battery"].containsKey("useExternalI2CSensor") || !data["battery"].containsKey("voltageDividerR1") || !data["battery"].containsKey("voltageDividerR2") || !data["battery"].containsKey("externalVoltagePin") || @@ -311,7 +311,7 @@ bool Configuration::readFile() { battery.sendExternalVoltage = data["battery"]["sendExternalVoltage"] | false; battery.monitorExternalVoltage = data["battery"]["monitorExternalVoltage"] | false; battery.externalSleepVoltage = data["battery"]["externalSleepVoltage"] | 10.9; - battery.externalI2CSensor = data["battery"]["externalI2CSensor"] | 0; + battery.useExternalI2CSensor = data["battery"]["useExternalI2CSensor"] | false; battery.voltageDividerR1 = data["battery"]["voltageDividerR1"] | 100.0; battery.voltageDividerR2 = data["battery"]["voltageDividerR2"] | 27.0; battery.externalVoltagePin = data["battery"]["externalVoltagePin"] | 34; @@ -484,7 +484,7 @@ void Configuration::setDefaultValues() { battery.sendExternalVoltage = false; battery.monitorExternalVoltage = false; battery.externalSleepVoltage = 10.9; - battery.externalI2CSensor = 0; + battery.useExternalI2CSensor = false; battery.voltageDividerR1 = 100.0; battery.voltageDividerR2 = 27.0; battery.externalVoltagePin = 34; diff --git a/src/web_utils.cpp b/src/web_utils.cpp index f8bfc46..03c3200 100644 --- a/src/web_utils.cpp +++ b/src/web_utils.cpp @@ -228,6 +228,9 @@ namespace WEB_Utils { } Config.battery.sendExternalVoltage = request->hasParam("battery.sendExternalVoltage", true); + if (Config.battery.sendExternalVoltage) { + Config.battery.useExternalI2CSensor = request->hasParam("battery.useExternalI2CSensor", true); + } if (Config.battery.sendExternalVoltage) { Config.battery.externalVoltagePin = getParamIntSafe("battery.externalVoltagePin", Config.battery.externalVoltagePin); Config.battery.voltageDividerR1 = getParamFloatSafe("battery.voltageDividerR1", Config.battery.voltageDividerR1);