Печаль. Сдох аккумулятор, незаслуженно забытый зимой в гараже. Я его вынул из мотоцикла, то ли сигнализация сожрала всё, то ли не зарядился в прошлые покатушки. Напряжометр показывал 9В, что есть криминал.
Я принёс батарею домой, отогрел, подключил к заряднику. Зарядник через полчаса показал ОК. Врал. Ничего там не ок. Лампочка ближнего света горела примерно 10 минут и потом быстро перешла в состояние «слабо грею воздух». Аккумулятор 6Ач, лампочка 55Вт.
Не покупать же новый аккумулятор? Зима, время есть. Есть ардуина даже и коробка всяких чипсов из Китая. Зря пылятся там что ли?
В далёкой советской армии 30 лет назад я проходил курс ухода за аккумуляторами. Основное отличие его от инструкций 21 века было таким: батарея должна проходить серию циклов заряда и разряда. Без этого, сколько её в заряднике не держи, какой бы он ни был умный, она сдохнет.
Теория процесса нагугливается легко. Практически же надо разрядить небольшим током в несколько ампер до 10.8В, а потом зарядить до упора. И так несколько раз. Смотреть на лампочку быстро наскучило и я нарисовал схему прибора.
Так как я не профессиональный реаниматор батареек, я собрал всё кое-как. Ну, как положено любителю ардуины.
Так как я оказался в этой ситуации не один, я оформил проект на гитхабе, чтобы другие тоже могли пользоваться, и даже положил туда красивую схему, нарисовав её в easyeda.com
Аналоговые ноги считывали напряжение и ток, потенциометр делил напряжение аккумулятора примерно на три. При падении напряжения ниже 10.8В включался заряд, при превышении 14.5В разряд. И так три раза. Потом батарея заряжалась и разряд уже не включался.
#define POWERPIN 0
#define AMPERPIN 1
#define LIMIT 10.8f
#define UPLIMIT 14.5f
Запускался процесс кнопкой или автоматически после полного заряда. Самый дохлый из аккумуляторов заряжаться не хотел до упора и только зря грелся. Я его пинал кнопкой несколько раз, потом процесс пошёл.
Был в коробке амперметр, я применил его для подсчёта ёмкости батарейки при разряде. В процессе цикла в терминале было видно:
- Текущий заряд в Ач.
- Текущий разряд в Ач.
- Ток в А.
- Напряжение в В.
При переключении режима, соответственно было видно конечная величина Ач для предыдущего процесса. Так же выводилось время, затраченное на цикл.
/*
** Реле на пин 2
** Кнопка на пин 3
** Меряем напряжение на аналоговом пине 0
** Амперметр на аралоговый порт 1
** Переключаем на заряд при напряжении 10.8В
** Не хотим работать при напряжении меньше 5В
**
** При включении работает зарядка.
** Кнопка переключает режим заряд/разряд.
** Разряд завершается при достижении 10.8B и начинается заряд.
*/
/*
Todo:
Считать время заряда и разряда.
Если лампа перегорает -- на зарядку.
*/
#define RELAYPIN 2
#define BUTTONPIN 3
#define POWERPIN 0
#define AMPERPIN 1
#define LIMIT 10.8f
#define UPLIMIT 14.5f
#define BADPOWER 5.0f
#define CIRCLES 3
#define SWITCH_LAMP 0
#define SWITCH_CHARGER 1
// Секунд на вывод инфы
#define TICKS (60*5)
void setup() {
pinMode(RELAYPIN, OUTPUT);
pinMode(BUTTONPIN, INPUT_PULLUP);
digitalWrite(RELAYPIN, HIGH);
Serial.begin(9600);
Serial.println("Start...");
}
int mode = SWITCH_CHARGER;
int pressed = 0;
int tick = 0;
unsigned long start = 0;
int circle = 1;
float chargeAh = 0.0;
unsigned long chargeMs = 0;
float dischargeAh = 0.0;
unsigned long dischargeMs = 0;
void loop() {
// Закончили
if (circle > CIRCLES) return;
// Проверяем напряжение.
float v = analogRead(POWERPIN) / 1023.0f * 3.0f * 5.0f;
// Измеряем ток
float a = ((analogRead(AMPERPIN) * (5.0 / 1024.0)) - 2.5) / 0.1;
// Заряжаем, если что-то не так с зарядкой.
if (v > BADPOWER) {
// Идёт зарядка, ожидаем кнопку.
if (mode == SWITCH_CHARGER) {
chargeAh += a * (millis() - chargeMs) / 3600000.0;
chargeMs = millis();
if (digitalRead(BUTTONPIN) == LOW || v > UPLIMIT && circle <= CIRCLES) {
mode = SWITCH_LAMP;
digitalWrite(RELAYPIN, LOW); // Переключаем на лампочку.
dischargeMs = millis();
Serial.print("Try "); Serial.println(circle);
Serial.print("Charge was "); Serial.print(chargeAh); Serial.println("Ah");
dischargeAh = 0.0;
Serial.println("LETS LIGHT!");
delay(100);
pressed = 1;
circle++;
if (circle > CIRCLES) Serial.println("Thats enough!");
}
}
// Идёт разряд, ожидаем падение напряжения.
if (mode == SWITCH_LAMP) {
dischargeAh += a * (millis() - dischargeMs) / 3600000.0;
dischargeMs = millis();
// Достигли дна по напряжению.
if (v < LIMIT) {
mode = SWITCH_CHARGER;
digitalWrite(RELAYPIN, HIGH); // Переключаем на зарядник.
start = millis();
Serial.println("TIME TO SUCK ELECTRICITY!");
unsigned long msec = millis() - start;
Serial.print("Discharge time ");
Serial.print(msec / 3600000); Serial.print("h ");
Serial.print((msec % 3600000) / 60000); Serial.print("m ");
Serial.print((msec % 60000) / 1000); Serial.print("s ");
Serial.println();
Serial.print("Appoximate capacity "); Serial.print(55 / 12);
Serial.println("Ah");
Serial.print("Disharge was "); Serial.print(dischargeAh); Serial.println("Ah");
chargeAh = 0.0;
}
// Переключить на зарядку принудительно.
if (pressed == 0 && digitalRead(BUTTONPIN) == LOW) {
mode = SWITCH_CHARGER;
digitalWrite(RELAYPIN, HIGH); // Переключаем на зарядник.
chargeMs = millis();
Serial.println("SUCK THE ELECTRICITY!");
Serial.print("Disharge was "); Serial.print(-dischargeAh); Serial.println("Ah");
chargeAh = 0.0;
if (circle > CIRCLES) Serial.println("LAST CHARGING!");
delay(100);
}
}
} else {
Serial.println("BAD POWER!");
}
if (tick == 0) {
Serial.print(" Disharge = "); Serial.print(-dischargeAh);
Serial.print(" Charge = "); Serial.print(chargeAh);
Serial.print(" Current = "); Serial.print(a);
Serial.print(" Voltage = "); Serial.println(v);
}
pressed = 0;
tick = ++tick % TICKS;
delay(1000); // Не спешим
}
Всякие дисплеи я не прикручивал, наблюдал за процессом с терминала через usb/serial.
В итоге, оба аккумулятора ожили и показали приличные амперчасы примерно соответствующие своим номиналам, что было даже удивительно для их возраста.
Автор: nwwind