Это устройство сконструировано для контроля зарядного процесса. В качестве источника может использоваться любой блок питания с регулируемым напряжением и способным дать достаточный ток для зарядки. Я, например, использовал переделанный блок питания от компьютера. (На фотографии светодиод заклеил бумажкой: уж очень яркий)
Авотерм (так было названо устройство),измеряет напряжение на клеммах, ток заряда и температуру батареи.Показывает на индикаторе общее время заряда и переданную емкость в АмперЧасах.
Программа прекращает зарядку, в случае если хотя бы один из параметров превысит допустимые пределы. С помощью кнопок меню можно самостоятельно задавать максимальные значения и петлю гистерезиса.
Напряжение и ток измеряется до десятых. Температура - только целые и положительные величины.
Во время заряда горит зеленый светодиод, после отключения загорается красный.
Конструктивно плата разделена с ЖКИ. ЖКИ выбран самый распространенный 16х2. Главным элементом является микроконтроллер pic16F877a. Датчик температуры DS18B20. Силовое реле на пять вольт, ток обещает коммутировать до 10 А.
Подстроечные резисторы позволяют очень точно откалибровать вольтметр и амперметр. Имеется разъём для ICSP.
В качестве усилителя тока используется LM358, это позволяет применить шунт с минимальным сопротивлением. Я у себя поставил кусок провода длиной около 3-4 см. Вполне хватает. Желательно развести питание реле и питание контроллера. Кварц на 4 Мгц.
последовательно опрашивает уровень напряжения, температуры и тока. При достижении заданного напряжения, источник отключится от батареи и включится только при падении на величину гистерезиса. Аналогична работа по температуре .Аккумуляторам очень вредно перегреваться.А вот отключение по току несколько отличается. При большом токе, превышающем максимальный уровень, реле отключается и включится только по истечении заданного промежутка времени.Общее время заряда выводится на ЖК индикатор.Имея ток заряда и время заряда можно с легкостью посчитать ампер-часы.Если есть необходимость, то можно вывести на экран и переданное батарее значение Ватт-часов.
DEFINE LCD_DREG PORTB ' для данных на ЖКИ
DEFINE LCD_DBIT 0 ' первый вывод порта PORTB, DB4 ЖКИ
DEFINE LCD_RSREG PORTD ' RS
DEFINE LCD_RSBIT 4 ' вывод порта PORTд, RS на ЖКИ
DEFINE LCD_EREG PORTD ' сигнал E на ЖКИ
DEFINE LCD_EBIT 6 ' вывод порта PORTд, E на ЖКИ
DEFINE LCD_BITS 4 ' Задать 4-битный режим обмена информацией для ЖКИ
DEFINE LCD_LINES 2 'опред тип ЖКИ'
define lcd_commandus 2000 'время задержки между командами на ЖКИ'
define lcd_dataus 50 'время задержки между посылками данных'
ADCON1 = %00000010
define adc_bits 8
define adc_clock 3
define adc_sampleus 50
TRISA=%11111111
trisb=0
trise= %00000110
PAUSE 1000
OPTION_REG=0 ' включаем подтягивающие резисторв
lcdout $fe,1
lcdout $fe,$c0
symbol ledzel =portd.7 ' зел диод
symbol ledkras=portb.5
symbol kn0 =portc.0 'кнопки входа в меню
symbol kn1 =porte.1 'кнопка прибавления
symbol kn2 =porte.2 'кнопка убавления
symbol rele =porte.0'
i var byte ' для подсчета обращений к неисправному дтч Т
x var word: x=0 ' номер подменю в меню
s var word : z var word 'циклы для времени ожидания откл Тока
ZamerI var word ' данные Тока с ацп мах з,7вольта-190 едениц
ZI var word 'промежуточное значение
ZamerU var word 'данные Напряжения с ацп мах 255
ZamerT var word 'замеренная температура (целая и дробная часть)
Itogid var byte 'вермя ожидания при отключении по току
Uvkl var word ' напряжение возвратного включенич (для петли гстрезиса)
Tvkl var word ' температ возвратного включения ( для петли гистерезиса)
q1 var portC.2 'датчик температуры DQ
busy var bit 'буси из датчика темературы
Tcel var word ' температура целое значение
Tmax var byte:Umax var byte: Imax VAR byte ' макс значения отключения
Qprmg var byte ' промежуточное значение для всех макс знач откл и включ
V var word ' емкость в А/часах
tau var word 'время заряда
data @0, 80,150,27,5,130,25,0,0 ' запишем в память при програмиров
Так как в picbasic нет десятичных значений , то для упрощения программы используются промежуточные значения , большие в 10 раз реальных значений.
t con 8 ' коэфициент для получения 1ой секунды таймера(зависит от длины пргрм)
main:
read 0,Imax,Umax,Tmax,Itogid,Uvkl,Tvkl,tau,V ' считаем из памяти
zamerNapr: ' замерим напряжение
adcin 0,ZamerU '
if ZamerU>=Umax then 'сравним с мах значением Напр (можем сами менять)
rele=0:ledzel=0:ledkras=1
Uvisok: ' подпрограмка откл источника по напряж
adcin 0,ZamerU ' сравним с напр возвратного включения оно
if ZamerU>=Uvkl then ' у нас может задаваться в меню(петля гестерезиса)
lcdout $fe,1,"U>!"," Umax=",#Umax/10,".",dec1 Umax//10 '
lcdout $fe,$c0,"U=",#ZamerU/10,".",dec1 ZamerU//10," Uvkl=",#Uvkl/10,".",dec1 Uvkl//10 '
pause 100 ' вывели на экран , что откл по напряжению
if kn0 = 0 then ' на всякий случай проверим
x=0 ' нажата ли кнопка программирования и
goto menu ' если да, то шуруем в меню
endif
goto Uvisok ' возвращаемся что бы сравнить с Увкл
endif : endif
zamerTerm:
i=0 ' задаем переменные обращения
owout q1,1,[$cc,$44] ' перепрыгнуть ROM поиск и делать темп конверсион
wait_up1: ' подпрограмма ожидания ответа
owin q1,4,[busy] ' считать буси бит
i=i+1 ' инкриминировать
if (i<>3) and (busy<>1) then wait_up1 'проверяем три раза
owout q1, 1, [$cc,$be] ' перепрыгнуть ROM поиск 'читать scratchpad
owin q1,2, [ZamerT.lowbyte,ZamerT.highbyte] ' считать 2 бита из q1
Tcel=ZamerT/16 ' вычислить целое значение из q1
if Tcel>=Tmax then ' сравним с мах значением и замерим
Tvisok : ' еще раз в подрпрограмке
i=0 ' задаем переменные обращения
owout q1,1,[$cc,$44] ' перепрыгнуть ROM поиск и делать темп конверсион
wait_up2: ' подпрограмма ожидания ответа
owin q1,4,[busy] ' считать буси бит
i=i+1 ' инкриминировать
if (i<>3) and (busy<>1) then wait_up2 'провер 3 раза,есть ли датчик
owout q1, 1, [$cc,$be] ' перепрыгнуть ROM поиск 'читать scratchpad
owin q1,2, [ZamerT.lowbyte,ZamerT.highbyte] ' считать 2 бита из q1
Tcel=ZamerT/16
if Tcel>=Tvkl then ' сравниваем с Твкл (гестерезис)
rele=0:ledzel=0:ledkras=1
lcdout $fe,1,"T>!"," Tmax=",#Tmax
lcdout $fe,$c0, "T=",#Tcel, " Tvkl=",#Tvkl
pause 100
if kn0 = 0 then ' на всякий случай проверим
x=0 ' нажата ли кнопка программирования и
goto menu ' если да, то шуруем в меню
endif
goto Tvisok 'вернемся проверить температуру
endif
endif
ZamerToka:
rele=1:ledzel=1:ledkras=0
adcin 1,ZamerI
ZI=ZamerI*10/19
if ZI>=Imax then
lcdout $fe,1,"I>!"," Imax=",#(Imax dig 1) ,".",#(Imax dig 0)
'lcdout $fe,$c0, "I=",#(ZI dig 1),".",dec1 ZI
rele=0:ledzel=0:ledkras=1
for s=0 to Itogid-1 ' цикл в цикле отсчитываем секунды и минуты перед
for z=0 to 59 ' возвратным включением по току
if kn0 = 0 then ' тут проверяем на всякий случай
x=0 :goto menu ' нажата ли кнопка программирования
endif
lcdout $fe,$c0,"I=",#(ZI dig 1),".",dec1 ZI ," " ,dec2 s,":" ,dec2 z
if kn2 = 0 then ' тут сбрасываем нашего счетчика времени
goto ZamerToka ' и отправляем мерять ток
endif
pause 100 'здесь мы задаем одну секунду,сравнивая по
next z ' хронометру , должно быт чуть меньше 1000
next s
goto ZamerToka 'вкл источник и сразу проверим на превышение тока
endif
x=x+1
if x>=t then 'считаем каждый цикл программы и как будет 1 сек
x=0
z=z+1
endif
if z >=60 then ' прибавляем на таймере
z=0
tau=tau+1 ' а это уже время в минутах
v=v+zamerI/1140 ' здесь определяется емкость умножением тока и минут
endif 'и делением (19*60)минуты на коэф замера
if kn1=0 then
tau=0
z=0
v=0
endif
write 6,tau
write 7,V
lcdout $fe,1 ,"U=",#ZamerU/10,".",dec1 ZamerU,"I=",#(ZI dig 1),".",dec1 ZI,"T=",#Tcel
lcdout $fe,$c0, " ",dec2 tau,":",dec2 z ," V=",#v/1140
pause 100
if kn0 = 0 then ' нажата ли кнопка программирования
x=0
goto menu ' начинаем обрабатывать большое меню
else
goto m7 ' иначе уходим даже чай не попив
endif
menu: ' вот оно большое меню
if x>6 then ' у нас 6 подменю и один выход
x=0 ' что бы устранить путаницу с подменю
endif
x=x+1 ' добавим 1 и начнем перебирать с М1
while kn0=0 ' ОТПУСТИ КНОПКУ!!!!
wend ' наконец-то .пошли дальше
branchl x,[m0,m1,m2,m3,m4,m5,m6,m7] ' дорога разшестеряется
m1: read 0,Qprmg : lcdout $fe,1,"PRGRM!Imax/10" :goto me
m2: read 1,Qprmg : lcdout $fe,1,"PRGRM!Umax/10" :goto me
m3: read 2,Qprmg : lcdout $fe,1,"PRGRM!Tmax" :goto me
m4: read 3,Qprmg : lcdout $fe,1,"PRGRM!ITogid" :goto me
m5: read 4,Qprmg : lcdout $fe,1,"PRGRM!Uvkl/10" :goto me
m6: read 5,Qprmg : lcdout $fe,1,"PRGRM!Tvkl"
me: ' подменю прибавления и убавления
lcdout $fe,$c0," =",dec3 Qprmg '
if kn1=0 then ' проверяем кнопку на инкремент
Qprmg=Qprmg+1 ' если да,то инкриминируем
lcdout $fe,$c0," =",dec3 Qprmg :pause 50 ' показываем,что увеличилось на 1
endif '
if kn2=0 then ' так же проверяем кнопку на уменьшение
Qprmg=Qprmg-1 ' все тоже самое
lcdout $fe,$c0," =",dec3 Qprmg :pause 50 ' только вниз
endif '
write x-1,Qprmg :pause 50 ' запишем в нестираемую память наши изменения
if kn0=0 then ' и опять проверяем кнопку выбора меню
goto menu ' возврат в большое меню
else
goto me ' возврат в ПОДменю
endif '
m0: m7: ' никуда не идем ,опять опрашиваем датчики
goto main
Плата
разработана в Eagle layout.
На плате видно,что некоторые связи не разведены -не стоит обращать на это внимание, т.к. они соединены в самом микроконтроллере.
Схема, плата и программа проекта находятся в архиве и скачать можно по
ссылке
Схема будет совершенствоваться, основное направление - это введение обратной связи в управление ШИМ 494-ый микросхемы блока питания компьютера. Это позволит избавиться от реле и управлять током и напряжением в автомате.