
Интернет-магазин «Неглупый Дом»
ACS712 измеряет ток разряда аккумулятора через нагрузочный резистор, а Arduino интегрирует ток по времени — на выходе получается реальная ёмкость в мА·ч, которая сохраняется в EEPROM по завершении теста.
Заявленная на этикетке ёмкость аккумулятора (например «3000 мА·ч») — это паспортное значение производителя, а не гарантия. У б/у аккумуляторов (из старых ноутбуков, шуруповёртов, павербанков) реальная ёмкость может быть в разы ниже заявленной из-за деградации со временем и циклами заряда-разряда. Единственный надёжный способ узнать настоящую ёмкость — разрядить аккумулятор контролируемым током через резистор и измерить, сколько миллиампер-часов он реально отдал.
ACS712 — датчик тока на эффекте Холла: он измеряет магнитное поле, создаваемое протекающим через него током, и выдаёт пропорциональное аналоговое напряжение, без необходимости разрывать цепь дополнительным шунтом. В состоянии нулевого тока датчик выдаёт примерно середину питающего напряжения (2.5В при питании 5В), а при протекании тока это напряжение отклоняется в одну или другую сторону в зависимости от направления тока.
Принцип расчёта ёмкости называется интегрированием тока по времени (или counting Кулонов): на каждой итерации цикла берётся текущий ток, умножается на прошедшее с прошлого измерения время (в часах) и переводится в миллиампер-часы, после чего прибавляется к накопленной сумме. Чем чаще происходят измерения — тем точнее итоговый результат, так как меньше теряется информации о колебаниях тока между замерами.
Так как реализации данного модуля бывают разные, если у вас на плате нет тех контактов, которые указаны ниже — сориентируйтесь по названиям контактов на своей плате.
// ВНИМАНИЕ: рекомендую отладить код через монитор порта, так как я языковая
// модель, а не специализированный кодер, и могу что-то упустить. Основу
// и идею я накидал, но проверьте под свою схему.
#include <Wire.h>
const int sensorPin = A0; // аналоговый выход датчика ACS712
const int EEPROM_ADDR = 0x50; // стандартный I2C-адрес микросхем серии AT24Cxx
float totalMah = 0; // накопленная ёмкость, миллиампер-часы
unsigned long lastSample = 0; // время последнего измерения, мс
// Записывает результат теста (целое число мА·ч) в первые два байта EEPROM
void saveResult(int mah) {
Wire.beginTransmission(EEPROM_ADDR);
Wire.write(0); Wire.write(0); // адрес ячейки памяти внутри EEPROM (0x0000)
Wire.write(mah >> 8); // старший байт числа
Wire.write(mah & 0xFF); // младший байт числа
Wire.endTransmission();
delay(5); // микросхеме нужно время на внутреннюю запись после каждой передачи
}
void setup() {
Wire.begin();
lastSample = millis();
}
void loop() {
int raw = analogRead(sensorPin);
float voltage = (raw / 1023.0) * 5.0;
// 0.066 В/А — чувствительность варианта ACS712-05A; у плат на 20А это 0.100,
// у плат на 30А — 0.185 (смотрите маркировку на своей плате)
float current = abs(voltage - 2.5) / 0.066; // ампер
unsigned long now = millis();
float hoursElapsed = (now - lastSample) / 3600000.0; // мс переводим в часы
totalMah += current * 1000 * hoursElapsed; // ампер*1000 = миллиампер, умножаем на часы
lastSample = now;
if (current < 0.02) { // аккумулятор разряжен или отключён — тест завершён
saveResult((int)totalMah);
Serial.print("Тест завершён, ёмкость: ");
Serial.print(totalMah);
Serial.println(" mAh");
}
delay(1000); // опрос раз в секунду — компромисс между точностью и простотой
}
Интегрирование `current * 1000 * hoursElapsed` на каждой итерации накапливает мА·ч — точность метода растёт с частотой измерений, здесь опрос идёт раз в секунду.
Ещё модули для Arduino: Электронные модули.
🎁 Купить весь комплект со скидкой 10%
Все 2 товара сразу в корзину: 235 ₽ 212 ₽ (экономия 23 ₽)
Скидка применяется автоматически при оформлении заказа, если в корзине именно этот комплект.
Остались вопросы? Проконсультируйтесь с ИИ-инженером — он уже в курсе темы статьи и сразу ответит, ничего вводить не нужно.