Создание зарядного устройства, управляемого Arduino

Добавлено 29 февраля 2016 в 00:00

Arduino и добавленная к ней схема заряда могут быть использованы для мониторинга и управления зарядкой никель-металл-гидридных аккумуляторов, например, так:

законченное зарядное устройство на Arduino
Законченное устройство

Аккумуляторные батареи являются отличным способом для питания вашей портативной электроники. Они могут сэкономить вам много денег при правильной зарядке. Для того, чтобы вы могли получить максимальную отдачу от ваших аккумуляторных батарей, их необходимо правильно заряжать. Это означает, что вам необходимо хорошее зарядное устройство. Вы можете потратить кучу денег, купив готовое зарядное устройство, а можете получить удовольствие, сделав его сами. В данной статье мы рассмотрим, как можно создать зарядное устройство, управляемое Arduino.

Во-первых, важно отметить, что не существует универсального способа зарядки, который подходил бы для всех аккумуляторов. Разные типы аккумуляторов используют разные химические процессы, обеспечивающие их работу. В результате, разные типы аккумуляторов необходимо заряжать по-разному. В этой статье мы не сможем охватить все типы аккумуляторных батарей и методы зарядки. Поэтому для простоты мы сосредоточим внимание на наиболее распространенном типе аккумуляторных батарей размера AA, на никель-металл-гидридных аккумуляторах (NiMH).

Комплектующие

комплектующие

Список комплектующих слева направо:

Как заряжать NiMH AA аккумуляторы

NiMH аккумулятор
Увеличение скорости заряда увеличивает риск повреждения аккумулятора.

Существует много способов зарядки NiMH аккумуляторов. Выбор используемого вами метода главным образом зависит от того, как быстро вы хотите зарядить аккумулятор. Скорость заряда измеряется по отношению к емкости батареи. Если ваша батарея обладает емкостью 2500 мАч, и вы заряжаете ее током 2500 мА, то вы заряжаете ее со скоростью 1C. Если вы заряжаете этот же аккумулятор током 250 мА, то вы заряжаете его со скоростью C/10.

Во время быстрой зарядки аккумулятора (со скоростью выше C/10), вам необходимо тщательно контролировать напряжение на батарее и ее температуру, чтобы не перезарядить ее. Это может серьезно повредить аккумулятор. Тем не менее, когда вы заряжаете аккумулятор медленно (со скоростью ниже C/10), у вас гораздо меньше шансов повредить батарею, если случайно перезарядите ее. Поэтому медленные методы зарядки, как правило, считаются более безопасными и помогут вам увеличить срок службы батареи. Поэтому в нашем самодельном зарядном устройстве мы будем использовать скорость заряда C/10.

Цепь заряда

Для данного зарядного устройства основой является схема для управления источником питания с помощью Arduino. Схема питается от источника напряжения 5 вольт, например, от адаптера переменного тока или компьютерного блока питания. Большинство USB портов не подходит для данного проекта из-за ограничений по току. Источник 5В заряжает батарею через мощный резистор 10 Ом и мощный MOSFET транзистор. MOSFET транзистор устанавливает величину тока, протекающего через батарею. Резистор добавлен как простой способ контроля тока. Контроль величины тока выполняется подключением каждого вывода резистора к аналоговым входным выводам Arduino и измерением напряжения с каждой стороны. MOSFET транзистор управляется выходным ШИМ выводом Arduino. Импульсы сигнала широтно-импульсной модуляции сглаживаются до постоянного напряжения фильтром на резисторе 1 МОм и конденсаторе 1 мкФ. Данная схема позволяет Arduino отслеживать и управлять током, протекающим через батарею.

схема заряда

Датчик температуры

датчик температуры
Датчик температуры служит для предотвращения перезаряда батареи и обеспечения безопасности.

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

держатель батареи AAдержатель батареи на макетной плате
Держатель AA батареи перед и после установки на макетную плату

Код

arduino ide скетч

Код для данного проекта довольно прост. Переменные в начале исходного кода позволяют настроить зарядное устройство путем ввода значений емкости батареи и точного сопротивления мощного резистора. Также добавлены и переменные безопасных порогов. Максимально допустимое напряжение на батарее устанавливается в значение 1,6 вольта. Максимальная температура батареи установлена на 35 градусов по Цельсию. Максимальное время заряда установлено на 13 часов. Если какой-либо из этих порогов безопасности будет превышен, зарядное устройство выключается.

В теле программы вы можете увидеть, что система постоянно измеряет напряжения на выводах мощного резистора. Это используется для расчета значений напряжения на батарее и протекающего через нее тока. Ток сравнивается с целевым значением, которое составляет C/10. Если рассчитанный ток отличается от целевого значения более, чем на 10 мА, система автоматически подстраивает выходное значение, чтобы подкорректировать его.

Arduino использует последовательный интерфейс для отображения всех текущих данных. Если вы хотите проконтролировать работу вашего зарядного устройства, то можете подключить Arduino к USB порту компьютера, но это необязательно, так как Arduino питается от источника напряжения 5В зарядного устройства.

int batteryCapacity = 2500;      // значение емкости батареи в мАч
float resistance = 10.0;         // измеренное сопротивление мощного резистора
int cutoffVoltage = 1600;        // максимальное напряжение на батарее (в мВ), которое не должно быть превышено
float cutoffTemperatureC = 35;   // максимальная температура батареи, которая не должна быть превышена (в градусах C)
//float cutoffTemperatureF = 95; // максимальная температура батареи, которая не должна быть превышена (в градусах F)
long cutoffTime = 46800000;      // максимальное время заряда в 13 часов, которое не должно быть превышено

int outputPin = 9;         // провод выходного сигнала подключен к цифровому выводу 9
int outputValue = 150;     // значение выходного ШИМ сигнала 

int analogPinOne = 0;      // первый датчик напряжения подключен к аналоговому выводу 0
float valueProbeOne = 0;   // переменная для хранения значения на analogPinOne
float voltageProbeOne = 0; // рассчитанное напряжение на analogPinOne

int analogPinTwo = 1;      // второй датчик напряжения подключен к аналоговому выводу 1
float valueProbeTwo = 0;   // переменная для хранения значения на analogPinTwo
float voltageProbeTwo = 0; // рассчитанное напряжение на analogPinTwo

int analogPinThree = 2;     // третий датчик напряжения подключен к аналоговому выводу 2
float valueProbeThree = 0;  // переменная для хранения значения на analogPinThree
float tmp36Voltage = 0;     // рассчитанное напряжение на analogPinThree
float temperatureC = 0;     // рассчитанная температура датчика в градусах C
//float temperatureF = 0;   // рассчитанная температура датчика в градусах F

float voltageDifference = 0;                   // разница между напряжениями на analogPinOne и analogPinTwo
float batteryVoltage = 0;                      // рассчитанное напряжение на батарее
float current = 0;                             // рассчитанный ток, протекающий через нагрузку в (мА)
float targetCurrent = batteryCapacity / 10;    // целевой выходной ток (в мА) устанавливается в значение 
                                               // C/10 или 1/10 от емкости батареи
float currentError = 0;         // разница между целевым и фактическим токами (в мА)



void setup()
{
  Serial.begin(9600);             // настройка последовательного интерфейса
  pinMode(outputPin, OUTPUT);     // установить вывод, как выход
}



void loop()
{
    
  analogWrite(outputPin, outputValue);  // записать выходное значение в выходной вывод

  Serial.print("Output: ");     // показать выходные значения для контроля на компьютере
  Serial.println(outputValue); 

  valueProbeOne = analogRead(analogPinOne);     // считать входное значение на первом пробнике
  voltageProbeOne = (valueProbeOne*5000)/1023;  // рассчитать напряжение на первом пробнике в милливольтах
  Serial.print("Voltage Probe One (mV): ");     // показать напряжение на первом пробнике
  Serial.println(voltageProbeOne);  
  
  valueProbeTwo = analogRead(analogPinTwo);    // считать входное значение на втором пробнике
  voltageProbeTwo = (valueProbeTwo*5000)/1023; // рассчитать напряжение на втором пробнике в милливольтах
  Serial.print("Voltage Probe Two (mV): ");    // показать напряжение на втором пробнике
  Serial.println(voltageProbeTwo);  
  
  batteryVoltage = 5000 - voltageProbeTwo;     // рассчитать напряжение на батарее
  Serial.print("Battery Voltage (mV): ");      // показать напряжение на батарее
  Serial.println(batteryVoltage); 

  current = (voltageProbeTwo - voltageProbeOne) / resistance;     // рассчитать ток заряда
  Serial.print("Target Current (mA): ");                          // показать целевой ток 
  Serial.println(targetCurrent);  
  Serial.print("Battery Current (mA): ");                         // показать фактический ток
  Serial.println(current);  
      
  currentError = targetCurrent - current;    // разница между целевым и измеренным токами
  Serial.print("Current Error  (mA): ");     // показать ошибку установки тока 
  Serial.println(currentError);     

  valueProbeThree = analogRead(analogPinThree);  // считать входное значение третьего пробника,  
  tmp36Voltage = valueProbeThree * 5.0;          // преобразуя его в напряжение
  tmp36Voltage /= 1024.0; 
 
  temperatureC = (tmp36Voltage - 0.5) * 100 ;     // преобразование, исходя из зависимости в 10 мВ на градус со сдвиком в 500 мВ
                                                  // ((напряжение - 500 мВ) умножить на 100)
  Serial.print("Temperature (degrees C) ");       // показать температуру в градусах Цельсия
  Serial.println(temperatureC); 
 
 /*
  temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;     //преобразовать в градусы Фаренгейта
  Serial.print("Temperature (degrees F) ");
  Serial.println(temperatureF); 
 */
 
  Serial.println();     // дополнительные пустые строки, чтобы облегчить чтение данных при отладке
  Serial.println();  



  if(abs(currentError) > 10)     // если ошибка установки тока достаточно велика, то подстроить выходное напряжение
   {
    outputValue = outputValue + currentError / 10;

    if(outputValue < 1)    // выходное значение никогда не может быть ниже 0
     {
      outputValue = 0;
     }

    if(outputValue > 254)  // выходное значение никогда не может быть выше 255
     {
      outputValue = 255;
     }
    
    analogWrite(outputPin, outputValue);     // записать новое выходное значение
   }
 
 
  if(temperatureC > cutoffTemperatureC)     // остановить зарядку, если температура батареи превысила безопасный порог
   {
    outputValue = 0;
    Serial.print("Max Temperature Exceeded");
   }
   
  /*
  if(temperatureF > cutoffTemperatureF)     // остановить зарядку, если температура батареи превысила безопасный порог
   {
    outputValue = 0;
   }
   */
   
   if(batteryVoltage > cutoffVoltage)       // остановить зарядку, если напряжение на батарее превысило безопасный порог
   {
    outputValue = 0;
    Serial.print("Max Voltage Exceeded");
   }  
 
   if(millis() > cutoffTime)                // остановить зарядку, если время заряда превысило порог
   {
    outputValue = 0;
    Serial.print("Max Charge Time Exceeded");
   }  

   delay(10000);     // задержка в 10 секунд перед следующей итерацией цикла
}


Скачиваемую версию исходного кода вы можете найти по ссылке, приведенной ниже.

Теперь вы можете создать собственное зарядное устройство. Но обязательно контролируйте скорость заряда и соблюдайте технику безопасности, так как избыточная зарядка аккумулятора может быть опасна.

Теги

ArduinoMOSFET / МОП транзисторNiMH (никель-металлогидридный) аккумуляторАккумуляторЗарядное устройство

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.


  • 2020-11-17Владимир

    А нет фотки готового устройства сверху? Не могу рассмотреть куда идут некоторые провода

  • 2020-11-09antzol

    Добрый день!
    В этом случае лучше разделить цепи заряда аккумуляторов - собрать отдельные схемы на MOSFET транзистора и подключить их к одной Arduino.
    Но тогда может начать не хватать аналоговых входов. Тогда вместо аналоговых датчиков температуры будет лучше использовать датчики с цифровым интерфейсом (например, те же DS18B20, пример того, как подключить несколько DS18B20 к Arduino - https://radioprog.ru/post/763 ).
    Ну и соответственно подправить код прошивки.

  • 2020-11-09Игорь

    Здравствуйте! А если заряжать одновременно 3 АКБ, то что поменяется в схеме?

  • 2020-01-30Владимир Викторович Желтобрюхо

    1. RC цепочка прекрасно сглаживает ШИМ, избавляться от нее ни в коем случае нельзя. Она не влияет на точность измерения)
    2. Подавать "чистое" опорное смысла нет - погрешность на уровни милливольт - мечта. Китайские зарядки прекрасно работают с погрешностью 50мВ.

  • 2019-12-26Владимир Лукьянчиков

    Чтобы повысить точность измерений падения напряжения - нужно избавиться от RC цепочки у транзистора. Потому что, чтобы ты не делал, а пульсации всё равно будут после ШИМ(по крайней мере этой частоты) :) Предлагаю вариант обычного делителя на цифровом потенциометре X9C103S. В этом случае можно будет полностью избавиться главной проблемы. Далее... Чтобы повысить ещё точность измерений падения напряжения на резисторе - можно на вход ref подать хорошее опорное напряжение что-нибудь на AD584 более чем достаточно :) С хорошим опорным напряжение и стабильный напряжением управления транзистором - можно уже будет говорить не о мощном резисторе, а каком-нить канталовом шунте. Просто если повышать точность измерений, то нужно не забывать о том, что у токоизмеряющих, мощных резисторов, есть температурный коэффециент, который учесть достаточно сложно. С канталовым шунтом вместо резистора(можно вытащить из блоков питания для компа) - температурной шунта, можно пренебречь(по крайней мере коэффициент более предсказуемый).