battery & power code sanitization

This commit is contained in:
Verkehrsrot 2019-09-07 23:10:53 +02:00
parent a1b7c102d0
commit 56f1ed4b8e
10 changed files with 107 additions and 100 deletions

View File

@ -1,14 +0,0 @@
#ifndef _BATTERY_H
#define _BATTERY_H
#include <driver/adc.h>
#include <esp_adc_cal.h>
#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate
#define NO_OF_SAMPLES 64 // we do some multisampling to get better values
uint16_t read_voltage(void);
void calibrate_voltage(void);
bool batt_sufficient(void);
#endif

View File

@ -121,6 +121,7 @@ extern time_t userUTCTime;
#include "led.h" #include "led.h"
#include "payload.h" #include "payload.h"
#include "blescan.h" #include "blescan.h"
#include "power.h"
#if (HAS_GPS) #if (HAS_GPS)
#include "gpsread.h" #include "gpsread.h"
@ -142,10 +143,6 @@ extern time_t userUTCTime;
#include "button.h" #include "button.h"
#endif #endif
#ifdef BAT_MEASURE_ADC
#include "battery.h"
#endif
#ifdef HAS_ANTENNA_SWITCH #ifdef HAS_ANTENNA_SWITCH
#include "antenna.h" #include "antenna.h"
#endif #endif

View File

@ -4,7 +4,6 @@
#ifdef USE_OTA #ifdef USE_OTA
#include "globals.h" #include "globals.h"
#include "battery.h"
#include <Update.h> #include <Update.h>
#include <WiFi.h> #include <WiFi.h>
#include <WiFiClientSecure.h> #include <WiFiClientSecure.h>

View File

@ -2,12 +2,20 @@
#define _POWER_H #define _POWER_H
#include <Arduino.h> #include <Arduino.h>
#include <driver/adc.h>
#include <esp_adc_cal.h>
#include "i2cscan.h" #include "i2cscan.h"
#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate
#define NO_OF_SAMPLES 64 // we do some multisampling to get better values
#ifdef HAS_PMU #ifdef HAS_PMU
#include <axp20x.h> #include <axp20x.h>
#endif #endif
void AXP192_init(void); void AXP192_init(void);
uint16_t read_voltage(void);
void calibrate_voltage(void);
uint8_t getBattLevel (void);
#endif #endif

View File

@ -1,73 +0,0 @@
#include "globals.h"
// Local logging tag
static const char TAG[] = __FILE__;
#ifdef BAT_MEASURE_ADC
esp_adc_cal_characteristics_t *adc_characs =
(esp_adc_cal_characteristics_t *)calloc(
1, sizeof(esp_adc_cal_characteristics_t));
static const adc1_channel_t adc_channel = BAT_MEASURE_ADC;
static const adc_atten_t atten = ADC_ATTEN_DB_11;
static const adc_unit_t unit = ADC_UNIT_1;
#endif
void calibrate_voltage(void) {
#ifdef BAT_MEASURE_ADC
// configure ADC
ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12));
ESP_ERROR_CHECK(adc1_config_channel_atten(adc_channel, atten));
// calibrate ADC
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(
unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_characs);
// show ADC characterization base
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
ESP_LOGI(TAG,
"ADC characterization based on Two Point values stored in eFuse");
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
ESP_LOGI(TAG,
"ADC characterization based on reference voltage stored in eFuse");
} else {
ESP_LOGI(TAG, "ADC characterization based on default reference voltage");
}
#endif
}
uint16_t read_voltage() {
#ifdef BAT_MEASURE_ADC
// multisample ADC
uint32_t adc_reading = 0;
for (int i = 0; i < NO_OF_SAMPLES; i++) {
adc_reading += adc1_get_raw(adc_channel);
}
adc_reading /= NO_OF_SAMPLES;
// Convert ADC reading to voltage in mV
uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_characs);
#ifdef BAT_VOLTAGE_DIVIDER
voltage *= BAT_VOLTAGE_DIVIDER;
#endif
#ifdef BAT_MEASURE_EN // turn ext. power off
digitalWrite(EXT_POWER_SW, EXT_POWER_OFF);
#endif
#ifdef HAS_PMU
voltage = axp.getBattVoltage();
#endif
return (uint16_t)voltage;
#else
return 0;
#endif
}
bool batt_sufficient() {
#ifdef BAT_MEASURE_ADC
uint16_t volts = read_voltage();
return ((volts < 1000) ||
(volts > OTA_MIN_BATT)); // no battery or battery sufficient
#else
return true;
#endif
}

View File

@ -54,7 +54,7 @@ void doHousekeeping() {
#endif #endif
// read battery voltage into global variable // read battery voltage into global variable
#ifdef BAT_MEASURE_ADC #if (defined BAT_MEASURE_ADC || defined HAS_PMU)
batt_voltage = read_voltage(); batt_voltage = read_voltage();
ESP_LOGI(TAG, "Voltage: %dmV", batt_voltage); ESP_LOGI(TAG, "Voltage: %dmV", batt_voltage);
#endif #endif

View File

@ -188,7 +188,7 @@ void draw_page(time_t t, uint8_t page) {
case 0: case 0:
// update Battery status (line 2) // update Battery status (line 2)
#ifdef BAT_MEASURE_ADC #if (defined BAT_MEASURE_ADC || defined HAS_PMU)
u8x8.setCursor(0, 2); u8x8.setCursor(0, 2);
u8x8.printf("B:%.2fV", batt_voltage / 1000.0); u8x8.printf("B:%.2fV", batt_voltage / 1000.0);
#endif #endif

View File

@ -248,7 +248,7 @@ void setup() {
#endif #endif
// initialize battery status // initialize battery status
#ifdef BAT_MEASURE_ADC #if (defined BAT_MEASURE_ADC || defined HAS_PMU)
strcat_P(features, " BATT"); strcat_P(features, " BATT");
calibrate_voltage(); calibrate_voltage();
batt_voltage = read_voltage(); batt_voltage = read_voltage();

View File

@ -41,7 +41,7 @@ inline String getHeaderValue(String header, String headerName) {
void start_ota_update() { void start_ota_update() {
// check battery status if we can before doing ota // check battery status if we can before doing ota
if (!batt_sufficient()) { if (getBattLevel() == MCMD_DEVS_BATT_MIN) {
ESP_LOGE(TAG, "Battery voltage %dmV too low for OTA", batt_voltage); ESP_LOGE(TAG, "Battery voltage %dmV too low for OTA", batt_voltage);
return; return;
} }

View File

@ -2,11 +2,14 @@
#include "globals.h" #include "globals.h"
#include "power.h" #include "power.h"
// Local logging tag
static const char TAG[] = __FILE__;
#ifdef HAS_PMU #ifdef HAS_PMU
void AXP192_init(void) { AXP20X_Class axp;
AXP20X_Class axp; void AXP192_init(void) {
if (axp.begin(Wire, AXP192_PRIMARY_ADDRESS)) if (axp.begin(Wire, AXP192_PRIMARY_ADDRESS))
ESP_LOGI(TAG, "AXP192 PMU initialization failed"); ESP_LOGI(TAG, "AXP192 PMU initialization failed");
@ -40,3 +43,90 @@ void AXP192_init(void) {
} }
} }
#endif // HAS_PMU #endif // HAS_PMU
#ifdef BAT_MEASURE_ADC
esp_adc_cal_characteristics_t *adc_characs =
(esp_adc_cal_characteristics_t *)calloc(
1, sizeof(esp_adc_cal_characteristics_t));
static const adc1_channel_t adc_channel = BAT_MEASURE_ADC;
static const adc_atten_t atten = ADC_ATTEN_DB_11;
static const adc_unit_t unit = ADC_UNIT_1;
#endif
void calibrate_voltage(void) {
#ifdef BAT_MEASURE_ADC
// configure ADC
ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12));
ESP_ERROR_CHECK(adc1_config_channel_atten(adc_channel, atten));
// calibrate ADC
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(
unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_characs);
// show ADC characterization base
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
ESP_LOGI(TAG,
"ADC characterization based on Two Point values stored in eFuse");
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
ESP_LOGI(TAG,
"ADC characterization based on reference voltage stored in eFuse");
} else {
ESP_LOGI(TAG, "ADC characterization based on default reference voltage");
}
#endif
}
uint8_t getBattLevel() {
/*
return values:
MCMD_DEVS_EXT_POWER = 0x00, // external power supply
MCMD_DEVS_BATT_MIN = 0x01, // min battery value
MCMD_DEVS_BATT_MAX = 0xFE, // max battery value
MCMD_DEVS_BATT_NOINFO = 0xFF, // unknown battery level
*/
#if (defined HAS_PMU || defined BAT_MEASURE_ADC)
uint16_t voltage = read_voltage();
switch (voltage) {
case 0:
return MCMD_DEVS_BATT_NOINFO;
case 0xffff:
return MCMD_DEVS_EXT_POWER;
default:
return (voltage > OTA_MIN_BATT ? MCMD_DEVS_BATT_MAX : MCMD_DEVS_BATT_MIN);
}
#else // we don't have any info on battery level
return MCMD_DEVS_BATT_NOINFO;
#endif
} // getBattLevel()
// u1_t os_getBattLevel(void) { return getBattLevel(); };
uint16_t read_voltage() {
uint16_t voltage = 0;
#ifdef HAS_PMU
voltage = axp.isVBUSPlug() ? 0xffff : axp.getBattVoltage();
#else
#ifdef BAT_MEASURE_ADC
// multisample ADC
uint32_t adc_reading = 0;
for (int i = 0; i < NO_OF_SAMPLES; i++) {
adc_reading += adc1_get_raw(adc_channel);
}
adc_reading /= NO_OF_SAMPLES;
// Convert ADC reading to voltage in mV
voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_characs);
#endif
#ifdef BAT_VOLTAGE_DIVIDER
voltage *= BAT_VOLTAGE_DIVIDER;
#endif
#endif // HAS_PMU
return voltage;
}