Skip to content

Commit

Permalink
for meshtastic#4154 use internal pull-ups to power ADC_Ctrl
Browse files Browse the repository at this point in the history
* Currently only on heltec tracker, but could use ADC_USE_PULLUP on other boards that could benefit
* Thanks @todd-herbert and @StevenCellist for the instructions ;-)
* Remove nasty Heltec_wireless #ifdefs that got somehow added to Power.cpp, instead use proper variant defs
* Cleanup adc enable/disable code a bit for less copy-paste cruft
  • Loading branch information
geeksville committed Aug 21, 2024
1 parent 48e0fd7 commit d017fc7
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 37 deletions.
60 changes: 28 additions & 32 deletions src/Power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,30 @@ using namespace meshtastic;
*/
static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level sensor

static void adcEnable()
{
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLUP);
#else
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
#endif
delay(10);
#endif
}

static void adcDisable()
{
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLDOWN);
#else
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
#endif
#endif
}

/**
* A simple battery level sensor that assumes the battery voltage is attached via a voltage-divider to an analog input
*/
Expand Down Expand Up @@ -226,25 +250,19 @@ class AnalogBatteryLevel : public HasBatteryLevel
uint32_t raw = 0;
float scaled = 0;

adcEnable();
#ifdef ARCH_ESP32 // ADC block for espressif platforms
raw = espAdcRead();
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
scaled *= operativeAdcMultiplier;
#else // block for all other platforms
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
delay(10);
#endif
#else // block for all other platforms
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
raw += analogRead(BATTERY_PIN);
}
raw = raw / BATTERY_SENSE_SAMPLES;
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
#endif
#endif
adcDisable();

if (!initial_read_done) {
// Flush the smoothing filter with an ADC reading, if the reading is plausibly correct
Expand Down Expand Up @@ -275,11 +293,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
uint8_t raw_c = 0; // raw reading counter

#ifndef BAT_MEASURE_ADC_UNIT // ADC1
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
delay(10);
#endif
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
int val_ = adc1_get_raw(adc_channel);
if (val_ >= 0) { // save only valid readings
Expand All @@ -288,18 +301,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
}
// delayMicroseconds(100);
}
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
#endif
#else // ADC2
#ifdef ADC_CTRL
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0)
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, LOW); // ACTIVE LOW
delay(10);
#endif
#endif // End ADC_CTRL

#else // ADC2
#ifdef CONFIG_IDF_TARGET_ESP32S3 // ESP32S3
// ADC2 wifi bug workaround not required, breaks compile
// On ESP32S3, ADC2 can take turns with Wifi (?)
Expand Down Expand Up @@ -334,12 +336,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
}
#endif // BAT_MEASURE_ADC_UNIT

#ifdef ADC_CTRL
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0)
digitalWrite(ADC_CTRL, HIGH);
#endif
#endif // End ADC_CTRL

#endif // End BAT_MEASURE_ADC_UNIT
return (raw / (raw_c < 1 ? 1 : raw_c));
}
Expand Down
3 changes: 2 additions & 1 deletion variants/heltec_wireless_paper/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define BAT_MEASURE_ADC_UNIT 2 // Use ADC2
#define ADC_ATTENUATION ADC_ATTEN_DB_12 // Voltage divider output is quite high
#define HAS_32768HZ
#define ADC_CTRL_ENABLED LOW

// LoRa
#define USE_SX1262
Expand All @@ -49,4 +50,4 @@
#define SX126X_RESET LORA_RESET

#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
3 changes: 2 additions & 1 deletion variants/heltec_wireless_paper_v1/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define BAT_MEASURE_ADC_UNIT 2 // Use ADC2
#define ADC_ATTENUATION ADC_ATTEN_DB_12 // Voltage divider output is quite high
#define HAS_32768HZ
#define ADC_CTRL_ENABLED LOW

// LoRa
#define USE_SX1262
Expand All @@ -49,4 +50,4 @@
#define SX126X_RESET LORA_RESET

#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
6 changes: 3 additions & 3 deletions variants/heltec_wireless_tracker/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL
#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider
#define ADC_MULTIPLIER 4.9 * 1.045
#define ADC_CTRL 2 // active HIGH, powers the voltage divider. Only on 1.1
#define ADC_CTRL_ENABLED HIGH
#define ADC_CTRL 2 // active HIGH, powers the voltage divider. Only on 1.1
#define ADC_USE_PULLUP // Use internal pullup/pulldown instead of actively driving the output

#undef GPS_RX_PIN
#undef GPS_TX_PIN
Expand Down Expand Up @@ -72,4 +72,4 @@
#define SX126X_RESET LORA_RESET

#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

0 comments on commit d017fc7

Please sign in to comment.