[Из песочницы] Arduino: определение заряда аккумуляторов и вывод информации в консоль

Наверное, каждый, создавая собственного автономного робота, хотел определять уровень заряда аккумуляторов и выводить их на дисплей или в консоль. Эта функция в основном необходима для отладки, однако в некоторых случаях определение заряда — важная часть функционала робота. Сложность в выполнении этой задачи составляет ограничение максимального входного напряжения на аналогово-цифровом преобразователе (), а также огромные скачки полученного значения. В этом посте я хотел бы показать свой способ считывания напряжения с аккумуляторов и определение заряда.
В первую очередь необходимо припаять к штекеру питания два резистора по 1 кΩ вот этой схеме делителя напряжения:

image

Таким образом, если выходное напряжение полностью заряженных аккумуляторов не превышает 10В, то напряжение после делителя будет меньше 5В, а значит, будет адекватно распознаваться аналого-цифровым преобразователем.

Теперь необходимо подключить выход делителя к любому аналоговому входу на Arduino. В моем случае это ножка А5. Затем попробуем считать напряжение с батареек:

void setup() {
  Serial.begin(9600);
  pinMode(A5, INPUT);
}

void loop() {
  float k = 2;
  float voltage = k*analogRead(A5);
}


Получается непонятно что, так как мы забыли конвертировать значение в десятеричную систему счисления. Для этого делим все на 1024:

void loop() {
  float k = 2/1024;
  float voltage = k*analogRead(A5);
}


Теперь подбираем при помощи вольтметра коэффициент, при котором voltage будет примерно равно реальному напряжению:

  float k = 2*1.12;
  float voltage = k*4.5f/1024*analogRead(A5);


Мы получили сильно прыгающее вверх-вниз напряжение, зачастую не схожее с требуемым. Для исправления этой ошибки добавляем низкочастотную фильтрацию с наиболее оптимальным для вашего проекта коэффициентом сглаживания:


void loop() {
  float k = 2*1.12;
  float voltage = k*4.5f/1024*analogRead(A5);
  float chargeLevel_procents;
  float chargeLevel;
  float y;
  int z;

  //Сглаживание значения заряда батареи

  float A_v = voltage; //Значение
  float A_K = 0.3; //Коэффициент сглаживания
  static float A_y; //Выходное значение
  
  A_y = A_y - A_K * (A_y - A_v);
}


Теперь осталось измерить напряжение на полностью заряженных аккумуляторах и полностью разряженных. В моем случае разница составляет ровно 1В.

После этого необходимо найти заряд аккумулятора в процентах:

  y = A_y / 8.4 * 100;
  
  chargeLevel_procents = y;
  chargeLevel = z;


Нам осталось только перевести это в значок батарейки (или в квадратики, как у меня) и вывести в консоль:


if(chargeLevel_procents >= 0 && chargeLevel_procents < 33) {
    z = 1; // 1/3 заряда
  }
  
  else if(chargeLevel_procents >= 33 && chargeLevel_procents < 66) {
    z = 2; // 2/3 заряда
  }

  
  else if(chargeLevel_procents >= 66 && chargeLevel_procents <= 100) {
    z = 3; // Полный заряд
  }

Serial.print("\t Voltage: ");
    Serial.print(A_y);
    Serial.print(" V ");
    Serial.print("\t Charge: ");
    if(z == 1) {
      Serial.print("■");
    }
    else if(z == 2) {
      Serial.print("■■");
    }
    else if(z == 3) {
      Serial.print("■■■");
    }
    else {
      Serial.print("ERROR");
    }
    Serial.print("\r\n");  


Для просмотра результата рекомендую использовать PuTTY, т. к. она поддерживает любые кодировки, в отличие от обычного «монитора порта» в Arduino IDE.

© Geektimes