Campamento de Programación - Parte 5: Leer el Voltaje de la Batería Integrada en el ODROID-GO

En esta guía vamos a aprender cómo obtener el estado de la batería con Arduino. La pantalla LCD mostrará el voltaje restante de la batería en voltios.

Figure 1 - The ODROID-GO has a ~3.7V battery module
Figura 1 - El ODROID-GO tiene un módulo de batería de unos 3.7V

Podemos leer el nivel de la batería a través de uno de los ADCs SAR de 12 bits que están integrados en ESP32. Estos ADCs son:

  • ADC1: 8 canales, conectado a GPIOs 32-39.
  • ADC2: 10 canales, conectado a GPIOs 0, 2, 4, 12-15, 25-27.

Existen algunas limitaciones a la hora de usar ADC2 en una aplicación. La batería está conectada al número pin GPIO 36, de modo que deberíamos leer un valor al usar ADC1. Existe una librería para controlar ADC para ESP32 que se llama adc.h. En esta guía, la vamos a usar para leer el nivel actual de la batería en voltios y mostrarlo en la pantalla LCD. En primer lugar, prepara el código tal como se muestra a continuación para mostrarlo en la pantalla LCD:

#include

void setup() {
// put your setup code here, to run once:
GO.begin();

GO.lcd.setTextSize(2);
}

double readBatteryVoltage() {

}

void showBatteryVoltage(double voltage) {
GO.lcd.clear();
GO.lcd.setCursor(0, 0);

GO.lcd.printf("Current Voltage: %1.3lf V \n", voltage);
}

void loop() {
// put your main code here, to run repeatedly:
showBatteryVoltage(readBatteryVoltage());
delay(1000);
}
Definimos dos funciones por adelantado:

  • readBatteryVoltage(): devuelve el voltaje completamente calculado.
  • showBatteryVoltage(): recibe este voltaje y lo muestra en pantalla.

Ajusta el canal con los correspondientes valores tal y como lo hemos diseñado. Antes de configurarlo, es importante saber que el voltaje de la batería GPIO está dividido por 2 debido a la limitación de entrada de datos del ADC integrado. Por lo tanto, si el valor original que procede de la batería es de 3.7V, entonces el valor de entrada al pin GPIO será de aproximadamente 1.85V. Así pues, tenemos que multiplicar el valor por 2 para conocer el voltaje real.

Utilizamos el ADC SAR de 12 bits para el canal con una atenuación de 11 dB. Deberíamos usar estos rangos para calcular igualmente el resultado. En primer lugar, define este valor extra como una macro Preprocesador e incluye las librerías necesarias para usar ADC en ESP32:

  • driver/adc.h: para obtener el valor bruto ADC sobre el voltaje.
  • esp_adc_cal.h: para calcular el voltaje correcto utilizando el AP.

A continuación, configura el canal con el valor adecuado usando dos funciones:

  • adc1_config_width(): configura el ancho del ADC.
  • adc1_config_channel_atten(): configura la atenuación del canal. El número de pin GPIO 36 utiliza el canal número 1.

Para conseguir un voltaje ADC preciso, es necesario recurrir a la calibración. El voltaje de referencia del ADC es originalmente 1.1V por defecto, pero en realidad difiere un poco en cada módulo ESP32. El fabricante escribe los datos de calibración en efuse:

  • esp_adc_cal_characterize(): devuelve una característica de su AP como una estructura.

La función readBatteryVoltage () lee un valor ADC con la función adc1_get_raw (). Devuelve un voltaje calculado como un valor de tipo doble utilizando la función esp_adc_cal_raw_to_voltage ():

#include 
#include <driver/adc.h>
#include

#define RESISTANCE_NUM 2
#define DEFAULT_VREF 1100

static esp_adc_cal_characteristics_t adc_chars;

void setup() {
// put your setup code here, to run once:
GO.begin();

GO.lcd.setTextSize(2);

adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, DEFAULT_VREF, &adc_chars);
}

double readBatteryVoltage() {
return (double) esp_adc_cal_raw_to_voltage(adc1_get_raw(ADC1_CHANNEL_0), &adc_chars) * RESISTANCE_NUM / 1000;
}

void showBatteryVoltage(double voltage) {
GO.lcd.clear();
GO.lcd.setCursor(0, 0);

GO.lcd.printf("Current Voltage: %1.3lf V \n", voltage);
}

void loop() {
// put your main code here, to run repeatedly:
showBatteryVoltage(readBatteryVoltage());
delay(1000);
}
Opcionalmente, podemos realizar el cálculo con una mayor precisión mediante un muestreo múltiple del valor ADC
Lee el valor 64 veces y lo divide por el total de repeticiones.
#include 
#include <driver/adc.h>
#include

#define RESISTANCE_NUM 2
#define DEFAULT_VREF 1100
#define NO_OF_SAMPLES 64

static esp_adc_cal_characteristics_t adc_chars;

void setup() {
// put your setup code here, to run once:
GO.begin();

GO.lcd.setTextSize(2);

adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, DEFAULT_VREF, &adc_chars);
}

double readBatteryVoltage() {
uint32_t adc_reading = 0;
for (int i = 0; i < NO_OF_SAMPLES; i++) {
adc_reading += adc1_get_raw((adc1_channel_t) ADC1_CHANNEL_0);
}
adc_reading /= NO_OF_SAMPLES;

return (double) esp_adc_cal_raw_to_voltage(adc_reading, &adc_chars) * RESISTANCE_NUM / 1000;
}

void showBatteryVoltage(double voltage) {
GO.lcd.clear();
GO.lcd.setCursor(0, 0);

GO.lcd.printf("Current Voltage: %1.3lf V \n", voltage);
}

void loop() {
// put your main code here, to run repeatedly:
showBatteryVoltage(readBatteryVoltage());
delay(1000);
}
Presiona CTRL-U para compilar y cargar el esquema. El voltaje actual de la batería aparecerá en la pantalla LCD.

Ejemplo completo

El ejemplo completo lo tienes disponible haciendo clic en el menú Files → Examples → ODROID-GO → Battery para importar y presiona CTRL-U para compilar/cargar, tal y como se muestra en la Figura 2.

Figure 2 - Accessing the completed example
Figura 2 - Accediendo al ejemplo completo

Para comentarios, preguntas y sugerencias, visita el artículo original en https://wiki.odroid.com/odroid_go/arduino/05_battery.

Be the first to comment

Leave a Reply