С развитием технологий наши электронные гаджеты становятся все меньше в размерах, при этом становясь все более функциональными. Одновременно с этим растут и требования к их электропитанию. К аккумуляторам мобильных устройств предъявляются все большие требования к их емкости с одновременным ужесточением требований к их размерам.
В наше время существует достаточно много типов аккумуляторов (батарей) — свинцово-кислотные, никель-кадмиевые, никель-металлогидридные. Но все эти типы батарей неудобны для применения в мобильных устройствах поскольку при достаточно большом весе они не обеспечивают требуемый ток и емкость. Поэтому в настоящее время в мобильных устройствах наибольшее применение находят литий-ионные аккумуляторы, обеспечивающие при малой массе и размерах достаточно большой ток и емкость.
Зачем нужен тестер емкости батарей
В настоящее время существует достаточно много производителей литиевых аккумуляторов (батарей), при этом, если перефразировать известную поговорку, то “не все производители являются одинаково полезными”. Некоторые из них предлагают сравнительно дешевые аккумуляторы со впечатляющими характеристиками. При покупке данных аккумуляторов часто оказывается так, что они либо вообще не работают, либо обеспечивают слишком малый ток, что делает их непригодными для использования в мобильных устройствах. Так каким образом проверить действительно ли перед вами качественный литиевый аккумулятор либо это дешевая подделка? Одним из таких способов является измерение напряжения на аккумуляторе под нагрузкой и без нагрузки, однако он не всегда является достаточно надежным.
В данной статье мы рассмотрим создание тестера емкости аккумуляторов типа 18650 на основе платы Arduino, принцип действия которого будет основан на разрядке полностью заряженного аккумулятора 18650 через резистор с одновременным измерением тока через данный резистор – это позволит затем рассчитать емкость аккумулятора. Если вы не получили заявленной емкости аккумулятора при “нормальном” напряжении на нем (не выходящем за допустимые ограничения), значит этот аккумулятор поврежден (с изъяном) и его нецелесообразно будет использовать в электронных устройствах поскольку он будет слишком быстро разряжаться, а его использование в составе пака аккумуляторов может привести к образованию локального токового контура, перегреву, и, возможно, к возгоранию.
Также на нашем сайте вы можете посмотреть более «продвинутый» проект подобного тестера емкости литий-ионных батарей 18650 на Arduino с регулировкой тока разряда аккумулятора, измерением температуры аккумулятора во время его разряда и OLED дисплеем для отображения необходимой информации.
Необходимые компоненты
- Плата Arduino Nano (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Микросхема операционного усилителя LM741 (купить на AliExpress).
- Резистор 2,2 Ом, 5 Вт.
- Регулятор напряжения LM7805 (купить на AliExpress).
- Mosfet транзистор с каналом N-типа IRF540N (купить на AliExpress).
- Подстроечный потенциометр 10 кОм (купить на AliExpress).
- Конденсатор 0,47 мкФ (купить на AliExpress).
- Резистор 33 кОм (купить на AliExpress).
- Источник питания с напряжением 12 В.
- Разъем постоянного тока (DC Power Barrel Jack Connector).
- Перфорированная плата.
- Соединительные провода.
- Набор для пайки.
- Теплоотводы.
Реклама: ООО «АЛИБАБА.КОМ (РУ)» ИНН: 7703380158
Схема проекта
Схема тестера емкости литиевых аккумуляторов 18650 на основе платы Arduino представлена на следующем рисунке.
Блок вычислений и отображения информации
Эта часть схемы разделена на две части: первая часть – это плата Arduino Nano и алфавитно-цифровой ЖК дисплей, а вторая – это схема подачи питания на данные компоненты схемы. Для подачи питания на схему можно использовать импульсный источник питания (SMPS) 12V или батарейку на 12V. Максимальный потребляемый ток для питания платы Arduino и ЖК дисплея будет составлять 60-70mA.
Для понижения напряжения питания с 12 В до 5 В мы использовали регулятор напряжения питания на основе микросхемы LM7805. Для получения стабилизированного напряжения питания 5 В на выходе данного регулятора нам необходимо подать на его вход как минимум 7,5 В. Максимальное входное напряжение для данного регулятора составляет 35 В, однако если входное напряжение на нем превышает 12 В, то в этом случае необходимо использовать теплоотвод чтобы не повредить микросхему регулятора напряжения. ЖК дисплей также запитывается от напряжения 5V и подключен к плате Arduino в 4-битном режиме. Также в схему мы добавили подстроечный резистор сопротивлением 10 кОм для управления контрастностью ЖК дисплея.
Схема нагрузки (разряда)
Следующей важной частью нашего тестера является схема нагрузки, через которую будет разряжаться аккумулятор. Она должна обеспечивать постоянство разрядного тока с учетом того что напряжение на выходе аккумулятора будет уменьшаться. Данная схема состоит из микросхемы операционного усилителя LM741 и MOSFET транзистора IRF540N с каналом N-типа, которая управляет током через MOSFET транзистор при помощи его включения и выключения в соответствии с уровнем напряжения, устанавливаемом нами.
Операционный усилитель здесь работает в режиме компарации (сравнения), в этом режиме на выходе операционного усилителя будет напряжение высокого уровня (high) всегда когда напряжение на его неинвертирующем контакте будет больше чем напряжение на инвертирующем контакте. Соответственно, если напряжение на инвертирующем контакте будет больше напряжения на неинвертирующем контакте, на выходе операционного усилителя будет напряжение низкого уровня. В нашей схеме уровень напряжения на неинвертирующем контакте операционного усилителя управляется ШИМ (широтно-импульсная модуляция) контактом D9 платы Arduino Nano, напряжение на котором переключается с частотой 500 Гц и которое затем поступает на RC фильтр со значением сопротивления 33 кОм и емкостью 0,47 мкФ, с выхода которого подается сигнал практически постоянного уровня на неинвертирующий контакт операционного усилителя. Инвертирующий контакт операционного усилителя подключен к нагрузочному резистору, который считывает значение напряжения между резистором и корпусом (землей). Выходной контакт операционного усилителя подключен к управляющему контакту (вывод затвора) MOSFET транзистора чтобы включать и выключать его. Операционный усилитель будет пытаться поддерживать одинаковое напряжение на своих двух входах (инвертирующем и неинвертирующем) при помощи переключения состояния MOSFET транзистора, таким образом, ток, протекающий через резистор нагрузки, будет пропорционален значению ШИМ, которое мы будем устанавливать на контакте D9 платы Arduino Nano. В нашем проекте мы ограничили максимальное значение тока в схеме величиной 1.3A, что приемлемо поскольку для теста мы использовали аккумулятор с максимальным током 10A.
Измерение напряжения
Максимальное напряжение на выходе полностью заряженного литий-ионного аккумулятора составляет величину от 4.1V до 4.3V, что меньше чем ограничение напряжения 5V на аналоговых входах платы Arduino Nano, которая имеет внутренние резисторы на этих входах сопротивлением более 10 кОм, поэтому мы можем непосредственно подсоединять аккумулятор к любому аналоговому входу платы не беспокоясь насчет тока, который потечет через этот контакт. В этом проекте нам будет необходимо измерять напряжение на аккумуляторе чтобы мы могли сделать вывод о том, соответствует ли это напряжение норме и разряжен ли полностью аккумулятор или нет.
Нам необходимо измерять ток, протекающий через резистор. В то же время мы не можем использовать шунт тока поскольку это увеличит сложность схемы, а увеличение сопротивления нагрузки будет уменьшать скорость разряда аккумулятора. Использование меньшего шунтирующего резистора потребует использования дополнительной схемы усилителя чтобы обеспечить возможность считывания с него напряжения с помощью платы Arduino.
Таким образом, в нашем проекте мы будем непосредственно считывать напряжение с резистора нагрузки и затем с помощью закона Ома определять ток, протекающий через данный резистор. Отрицательный вывод резистора непосредственно подключен к GND (земле), поэтому мы можем с высокой долей уверенности предполагать, что напряжение, которое мы считываем с резистора, будет правильным.
Объяснение программы для Arduino
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Первым делом в программе нам необходимо подключить заголовочный файл библиотеки для работы с ЖК дисплеем 16×2 и объявить необходимые для нашей программы переменные. Также нам необходимо объявить контакты, через которые мы будем управлять ЖК дисплеем, и контакт, на котором мы будем формировать ШИМ сигнал.
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <LiquidCrystal.h> //Default Arduino LCD Librarey is included const int rs = 3, en = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8; //Mention the pin number for LCD connection LiquidCrystal lcd(rs, en, d4, d5, d6, d7); const float BAT_LOW = 3.0; //to define the low voltage limit of the Li Ion cell const float BAT_HIGH = 4.5; //to define the high voltage limit of the cell const int MOSFET_Pin=9; const int PWM_VALUE=150; unsigned long previousMillis = 0; // Previous time in ms unsigned long millisPassed = 0; // Current time in ms float Capacity=0; //Variable to define the battery Capacity float Resistor=2.2; // Load Resistor Value is 2.2ohms float mA; |
Далее в функции setup мы инициализируем последовательную связь со скоростью 9600 бод (для целей отладки с помощью монитора последовательной связи) и ЖК дисплей, а также высветим приветственное сообщение “Battery Capacity Tester Circuit” на экране дисплея.
1 2 3 4 5 6 7 8 9 10 11 |
void setup() { Serial.begin(9600); lcd.begin(16, 2); lcd.setCursor(0, 0); // Set the cursor on the first column and first row. lcd.print("Battery Capacity"); lcd.setCursor(0,1); lcd.print("Tester Circuit"); delay(3000); lcd.clear(); } |
Нам не нужно задавать режим работы ШИМ контакта Arduino на вывод данных (Output) поскольку функция AnalogWrite, которую мы используем в основном цикле программы, делает это самостоятельно. Но необходимо с особой тщательностью подходить к выбору значения ШИМ, которое мы будем подавать на этот контакт. Его необходимо выбирать исходя из требуемого тока разряда. Слишком большое значение ШИМ приведет к большому току и большому падению напряжения на аккумуляторе, а слишком низкое значение ШИМ приведет к значительному увеличению времени разряда аккумулятора.
В основной функции loop программы мы будем считывать напряжение с выходов контактов A0 и A1 платы Arduino – с выходов 10-битных АЦП (аналого-цифровой преобразователь) данных контактов мы будем получать значения в диапазоне 0-1023, которые мы будем преобразовывать в диапазон 0-5V при помощи их умножения на множитель 5.0/1023.0. Но перед этим вам необходимо убедиться в том, что напряжение между контактами 5V и GND платы Arduino действительно составляет 5V (делать это нужно с помощью калиброванного вольтметра или мультиметра) поскольку в большинстве случаев оно не равно точно 5V. Небольшое изменение этого опорного напряжения может приводить к существенным погрешностям в работе нашей схемы, поэтому измерьте с максимальной точностью это напряжение и скорректируйте соответствующим образом множитель 5.0/1023.0.
Далее в программе мы будем непрерывно измерять напряжение на аккумуляторе и если напряжение на нем превышает верхний допустимый для него предел, задаваемый нами в программе, то мы будем высвечивать на экране ЖК дисплея сообщение об ошибке, которое будет свидетельствовать о том, что аккумулятор слишком сильно заряжен или об ошибке в соединениях в схеме, которая приводит к тому, что напряжение на управляющий контакт MOSFET транзистора не подается, поэтому и ток через резистор нагрузки не протекает. Крайне важно, чтобы аккумулятор был полностью заряжен перед подключением его к схеме нашего тестера емкости аккумуляторов – только в этом случае мы сможем правильно определить его емкость.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
analogWrite(MOSFET_Pin, PWM_VALUE); // read the input on analog pin 0: int sensorValue_voltage_Cell = analogRead(A0); // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V): float voltage = sensorValue_voltage_Cell * (5.08 / 1023.0); Serial.print("VOLTAGE: "); Serial.println(voltage); // Here the voltage is being printed on Serial Monitor lcd.setCursor(0, 0); // Set the cursor on the first column and first row. lcd.print("Voltage: "); // Print the voltage reading on the screen lcd.print(voltage); delay(100); int sensorValue_Shunt_Resistor= analogRead(A1); float voltage1= sensorValue_Shunt_Resistor *(5.08 / 1023.0); float current= voltage1/Resistor; Serial.print("Current: "); Serial.println(current); lcd.setCursor(0, 1); //Set the cursor on the first column and the second row (counting starts at 0!). lcd.print("Current: "); lcd.print(current); |
Теперь, когда мы убедились в том, что напряжение на аккумуляторе находится между нижней и верхней границей, мы с помощью платы Arduino будем определять значение тока по описанной выше методике, умножать его на значение времени, в течение которого ток протекал, и сохранять полученное значение произведения в специальной переменной, которую мы определили ранее для хранения значения мАч.
Во время всего процесса разрядки значения тока и напряжения отображаются на экране ЖК дисплея, также при желании вы их можете отображать и в окне монитора последовательной связи. Процесс разряда будет продолжаться до тех пор, пока напряжение на аккумуляторе не опустится ниже минимальной границы, определенной нами в программе. После этого полная емкость аккумулятора отобразится на экране ЖК дисплея, а ток через резистор нагрузки не будет протекать поскольку на управляющий контакт MOSFET транзистора мы подадим напряжение низкого уровня (low).
1 2 3 4 5 6 7 8 9 |
else if(voltage > BAT_LOW && voltage < BAT_HIGH ) { // Check if the battery voltage is within the safe limit millisPassed = millis() - previousMillis; mA = current * 1000.0 ; Capacity = Capacity + (mA * (millisPassed / 3600000.0)); // 1 Hour = 3600000ms to convert it into mAh units previousMillis = millis(); delay(1000); lcd.clear(); } |
Повышение точности работы проекта
В нашем проекте для тестирования емкости аккумулятора мы используем определение тока и напряжения, но в наших условиях это «не совершенно». Дело здесь в том, что зависимость между действительным значением напряжения и его значением на выходе АЦП не является полностью линейной, и это обстоятельство и вносит небольшую погрешность в наши измерения.
Чтобы повысить точность получаемых результатов вы должны построить график зависимости значений на выходе АЦП от источника «точного» (калиброванного) напряжения и затем использовать любой метод, который на основе значений этих точек построит уравнение прямой, максимально близкой к этим точкам. Данное уравнение прямой (точнее ее наклон) и необходимо будет использовать в качестве множителя при преобразовании диапазона 0-1023 на выходе АЦП в диапазон 0-5 В.
Также MOSFET транзистору, использованному в нашем проекте, необходимо напряжение более 7V для того, чтобы его канал полностью открылся. А поскольку мы подаем на него только 5V, то это, соответственно, приводит к некоторой погрешности получаемых результатов. Выходом может стать использование MOSFET транзистора IRL520N с каналом N-типа – с его помощью отпадает необходимость в применении питающего напряжения 12V и мы можем непосредственно работать с логическими уровнями напряжения 5V, доступными в плате Arduino.
Сборка и тестирование проекта
После того, как вы протестировали работу всех частей проекта по отдельности и убедились в том, что они исправно работают, их можно спаять вместе на перфорированной плате. Вы можете, при желании, собрать данный проект на печатной плате. Плата Arduino Nano, ЖК дисплей 16×2 и операционный усилитель LM741 будут монтироваться в специальные колодки (Female Bergstik) чтобы их можно было легко изъять из конструкции проекта при необходимости.
Питающее напряжение 12V на схему мы подаем через разъем постоянного тока (DC Barrel Jack), далее оно с помощью регулятора напряжения LM7805 преобразуется в 5V для питания платы Arduino Nano и ЖК дисплея. После подачи питания на схему и регулировки контрастности ЖК дисплея с помощью потенциометра вы должны увидеть на его экране приветственное сообщение. После этого, если напряжение аккумулятора находится в рабочем диапазоне, на экране ЖК дисплея будут отображаться значения тока и напряжения.
После окончания процесса разряда на экране ЖК дисплея отобразится измеренная емкость аккумулятора. Более подробно все эти процессы вы можете посмотреть на видео, приведенном в конце статьи.
Улучшить проект можно если, к примеру, записывать измеряемые в процессе разряда значения тока и напряжения в Excel файл (пример этого можно посмотреть в статье про декодер инфракрасных сигналов на основе Arduino) и затем делать постобработку и визуализацию этих данных с помощью специальных приложений (LabVIEW, MATLAB Simulink и т.п.). В результате этого можно построить различные модели предсказания работы аккумулятора в различных условиях, при различной нагрузке.
Исходный код программы (скетча)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
#include <LiquidCrystal.h> //библиотека для работы с ЖК дисплеем const int rs = 3, en = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8; //контакты, к которым подключен ЖК дисплей LiquidCrystal lcd(rs, en, d4, d5, d6, d7); const float BAT_LOW = 3.0; //минимальная граница напряжения на аккумуляторе const float BAT_HIGH = 4.5; //максимальная граница напряжения на аккумуляторе const int MOSFET_Pin=9; const int PWM_VALUE=50 ; unsigned long previousMillis = 0; // предыдущее время в ms unsigned long millisPassed = 0; // текущее время в ms float Capacity=0; //переменная для хранения емкости аккумулятора float Resistor=2.2; // значение резистора нагрузки - 2.5ohms float mA; void setup() { // инициализируем последовательную связь со скоростью 9600 бод Serial.begin(9600); lcd.begin(16, 2); //инициализируем ЖК дисплей 16х2 lcd.setCursor(0, 0); // устанавливаем курсор на дисплее в 1-й столбец 1-й строки lcd.print("Battery Capacity"); lcd.setCursor(0,1); lcd.print("Tester Circuit"); delay(3000); lcd.clear(); } void loop() { analogWrite(MOSFET_Pin, PWM_VALUE); // считываем значение на аналоговом контакте 0: int sensorValue_voltage_Cell = analogRead(A0); // преобразуем считанное значение (в диапазоне 0 - 1023) в напряжение (в диапазоне 0 - 5V): float voltage = sensorValue_voltage_Cell * (5.12 / 1023.0)*1.2; Serial.print("VOLTAGE: "); Serial.println(voltage); // выводим значение напряжения в окно монитора последовательной связи lcd.setCursor(0, 0); // устанавливаем курсор на дисплее в 1-й столбец 1-й строки lcd.print("Voltage: "); // выводим на экран значение напряжения lcd.print(voltage); delay(100); int sensorValue_Shunt_Resistor= analogRead(A1); float voltage1= sensorValue_Shunt_Resistor *(5.00 / 1023.0); float current= voltage1/Resistor; Serial.print("Current: "); Serial.println(current); lcd.setCursor(0, 1); // устанавливаем курсор на дисплее в 1-й столбец 2-й строки lcd.print("Current: "); lcd.print(current); if ( voltage > BAT_HIGH) { digitalWrite(MOSFET_Pin, LOW); // выключаем MOSFET , аккумулятор не разряжается Serial.println( "Warning High-V! "); lcd.clear(); lcd.setCursor(0,0); lcd.print("HIGH VOLTAGE!!"); delay(2000); lcd.clear(); } else if(voltage < BAT_LOW) { digitalWrite(MOSFET_Pin, LOW); // выключаем MOSFET , аккумулятор не разряжается Serial.println( "Warning Low-V! "); lcd.clear(); lcd.setCursor(0,0); lcd.print("Low Voltage!!!"); delay(2000); lcd.clear(); lcd.setCursor(0,0); lcd.print("CAPACITY:"); lcd.setCursor(0,1); lcd.print(Capacity); delay(10000); } else if(voltage > BAT_LOW && voltage < BAT_HIGH ) { // проверяем находится ли напряжение аккумулятора в безопасных границах millisPassed = millis() - previousMillis; mA = current * 1000.0 ; Capacity = Capacity + (mA * (millisPassed / 3600000.0)); // 1 Hour = 3600000ms чтобы преобразовать в значения mAh (мАч) previousMillis = millis(); //Serial.print("DATA,TIME,"); Serial.print(voltage); Serial.print(","); Serial.println(Capacity); //раскомментируйте эту строку если хотите отображать результаты в окне монитора последовательной связи delay(1000); lcd.clear(); } } |
4 ответа к “Тестер емкости литиевых аккумуляторов 18650 на основе Arduino”
LM358 подойдет в качестве ОУ? Может взять полевик с сопротивлением канала поменьше ? Например IRF3205
Еще хотелось бы 2 в 1 — заряд/разряд, 3 цикла для достоверности
К сожалению, в подобных вопросах не силен, не могу подсказать точно. Если совмещать с зарядом, то посмотрите этот проект. Можно совместить эти 2 проекта, но у нас на сайте такого готового проекта нет
1. Ошибки в схеме, в том числе в подключении некоторых элементов.
2. Зачем весь этот огород, который еще фиг откалибруешь нормально, для АКБ до 5 В если можно тупо через резистор и analog read?
Вывод: устройство неэффективно и чрезмерно сложно в реализации.
Да разрядить то аккумулятор можно просто через резистор и именно этот метод разряда и используется в схеме, но смысл всех этих «наворотов» в ней заключается в том, чтобы на основании тока (а он будет изменяться) разрядки за весь цикл разряда определить реальную емкость аккумулятора и на основании этого сделать вывод о том исправен ли аккумулятор или нет