Как измерить напряжение аккумулятора с помощью внутреннего АЦП ESP32 - PullRequest
1 голос
/ 01 июля 2019

Я использую беспроводной сенсорный узел (esp32, DHT11, влажность почвы и nrf24l01), и я хочу добавить батарею для питания этих датчиков, также необходимо измерить напряжение батареи. Что касается аккумулятора, напряжение всегда изменяется, и его нельзя использовать в качестве эталона Vcc, поэтому я обнаружил, что есть внутреннее эталонное напряжение. Может ли кто-нибудь сделать с этим дать мне некоторые инструкции. Спасибо

Я собираюсь использовать LIFEPO4 3,3 В по норме (3,6 В при макс.) Или 18650 3,7 В / 4,2 В макс.

1 Ответ

1 голос
/ 01 июля 2019

В соответствии с документами :

Полномасштабное напряжение АЦП по умолчанию составляет 1,1 В.Для считывания более высоких напряжений (до максимального напряжения на выводе, обычно 3,3 В) требуется настройка ослабления сигнала> 0 дБ для этого канала АЦП.

Поэтому я установил его на ноль для 1,1 В, затем вы можете простопрочитайте напряжение (в цикле для лучшей точности), а затем преобразуйте его в действительное напряжение и найдите процент уровня заряда батареи.

В приведенном ниже примере функция вернет процент уровня заряда батареи.Не забудьте отредактировать battery_max и battery_min в зависимости от уровня напряжения батареи.Я предположил, что вы подключаете аккумулятор к каналу 0 ADC1 (GPIO 36).

Кроме того, я рекомендую вам создать схему делителя резистора для снижения уровня напряжения, потому что, если ваш входной источник питания упадет, Arduino будетПодача напрямую с аналогового входа, что нежелательно, также помните, что ваш уровень напряжения не должен превышать 3,9 В.

#include <driver/adc.h>

float battery_read()
{
    //read battery voltage per %
    long sum = 0;                  // sum of samples taken
    float voltage = 0.0;           // calculated voltage
    float output = 0.0;            //output value
    const float battery_max = 3.6; //maximum voltage of battery
    const float battery_min = 3.3; //minimum voltage of battery before shutdown

    float R1 = 100000.0; // resistance of R1 (100K)
    float R2 = 10000.0;  // resistance of R2 (10K)

    for (int i = 0; i < 500; i++)
    {
        sum += adc1_get_voltage(ADC1_CHANNEL_0);
        delayMicroseconds(1000);
    }
    // calculate the voltage
    voltage = sum / (float)500;
    voltage = (voltage * 1.1) / 4096.0; //for internal 1.1v reference
    // use if added divider circuit
    // voltage = voltage / (R2/(R1+R2));
    //round value by two precision
    voltage = roundf(voltage * 100) / 100;
    Serial.print("voltage: ");
    Serial.println(voltage, 2);
    output = ((voltage - battery_min) / (battery_max - battery_min)) * 100;
    if (output < 100)
        return output;
    else
        return 100.0f;
}

void setup()
{
    adc1_config_width(ADC_WIDTH_12Bit);
    adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_0db); //set reference voltage to internal
    Serial.begin(9600);
}

void loop()
{
    Serial.print("Battery Level: ");
    Serial.println(battery_read(), 2);
    delay(1000);
}

Если вы добавите делительную цепь, измените battery_min и battery_max в соответствии с новым выходомцепь делителя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...