This charger will charge battery or super-cap to either pre-programmed voltage or to the voltage of the cell that we want to match (<3.3V). The charged cell/super-cap can be charged up to 4V. Charge current can be chosen to be either 8mA or 25mA. These are max charging current for Tadiran HLC batteries of 2 sizes (hybrid rechargeable cell and super-cap). This was just a project to learn; no use in production settings, maybe usefull for R&D.

Dependencies:   mbed

Committer:
krzysiekf
Date:
Sat Mar 01 20:03:11 2014 +0000
Revision:
1:822b4281ebbb
Parent:
0:763f2afa5e8b
this one has improved "Charging" work. Steady when controlling current, blinking with low frequency when topping off.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
krzysiekf 0:763f2afa5e8b 1 #include "mbed.h"
krzysiekf 0:763f2afa5e8b 2
krzysiekf 0:763f2afa5e8b 3 DigitalOut o5(p5);//o5 through o14 and o30 set as outputs to prevent any coupling of the external noise
krzysiekf 0:763f2afa5e8b 4 DigitalOut o6(p6);
krzysiekf 0:763f2afa5e8b 5 DigitalOut o7(p7);
krzysiekf 0:763f2afa5e8b 6 DigitalOut o8(p8);
krzysiekf 0:763f2afa5e8b 7 DigitalOut o9(p9);
krzysiekf 0:763f2afa5e8b 8 DigitalOut o10(p10);
krzysiekf 0:763f2afa5e8b 9 DigitalOut o11(p11);
krzysiekf 0:763f2afa5e8b 10 DigitalOut o12(p12);
krzysiekf 0:763f2afa5e8b 11 DigitalOut o13(p13);
krzysiekf 0:763f2afa5e8b 12 DigitalOut o14(p14);
krzysiekf 0:763f2afa5e8b 13 DigitalOut o30(p30);
krzysiekf 0:763f2afa5e8b 14
krzysiekf 0:763f2afa5e8b 15 PwmOut chrg(p21);//PWM output
krzysiekf 0:763f2afa5e8b 16
krzysiekf 0:763f2afa5e8b 17 AnalogIn vrsIn(p16);//rectified voltage measurement, high side of sense resistor
krzysiekf 0:763f2afa5e8b 18 AnalogIn vrsOut(p17);//charged battery voltage measurement, low side of sense resistor
krzysiekf 0:763f2afa5e8b 19 AnalogIn sens(p15);//sense Primary Cell voltage
krzysiekf 0:763f2afa5e8b 20
krzysiekf 0:763f2afa5e8b 21 DigitalIn s1(p22);//switch for togling START/STOP
krzysiekf 0:763f2afa5e8b 22 DigitalIn s2(p23);//switch for togling between 8 and 25mA
krzysiekf 0:763f2afa5e8b 23 DigitalIn s3(p19);//switch for togling PrimCell/ProgVolt
krzysiekf 0:763f2afa5e8b 24
krzysiekf 0:763f2afa5e8b 25 DigitalOut PrimCellInd(p20);//Primary Cell sensed voltage chosen as limit for HLC battery
krzysiekf 0:763f2afa5e8b 26 DigitalOut ProgVoltInd(p18);//Programmed Voltage chosen as limit for HLC battery
krzysiekf 0:763f2afa5e8b 27
krzysiekf 0:763f2afa5e8b 28 DigitalOut chrgInd(p26);//indicates real time charging; only on when PWM was issued
krzysiekf 0:763f2afa5e8b 29
krzysiekf 0:763f2afa5e8b 30 DigitalOut Rs1EnInd(p25);//indicator for 8mA charge current
krzysiekf 0:763f2afa5e8b 31 DigitalOut Rs1En(p27);//enable 8mA sense resistor
krzysiekf 0:763f2afa5e8b 32
krzysiekf 0:763f2afa5e8b 33 DigitalOut Rs2EnInd(p24);//indicator for 25mA charge current
krzysiekf 0:763f2afa5e8b 34 DigitalOut Rs2En(p28);//enable 25mA sense resistor
krzysiekf 0:763f2afa5e8b 35
krzysiekf 0:763f2afa5e8b 36 DigitalOut hlcEn(p29);//enable HLC for charging
krzysiekf 0:763f2afa5e8b 37
krzysiekf 0:763f2afa5e8b 38 int main()
krzysiekf 0:763f2afa5e8b 39 {
krzysiekf 0:763f2afa5e8b 40 hlcEn=0;
krzysiekf 0:763f2afa5e8b 41 Rs1En=0;
krzysiekf 0:763f2afa5e8b 42 Rs2En=0;
krzysiekf 0:763f2afa5e8b 43 wait(1);
krzysiekf 0:763f2afa5e8b 44 float Vprog=3.65;//arbitrary voltage chosen for testing purposes; this is the voltage of the battery to be charged that should be never exceeded
krzysiekf 0:763f2afa5e8b 45 float tempChrg=0.0;//temporary holding of the PWM Duty Cycle level
krzysiekf 0:763f2afa5e8b 46 float chrgIncr=0.0;//temporary holding of the PWM increment Duty Cycle
krzysiekf 0:763f2afa5e8b 47
krzysiekf 0:763f2afa5e8b 48 o5=0;//o5 through o14 and o30 set to output "0" (GND)
krzysiekf 0:763f2afa5e8b 49 o6=0;
krzysiekf 0:763f2afa5e8b 50 o7=0;
krzysiekf 0:763f2afa5e8b 51 o8=0;
krzysiekf 0:763f2afa5e8b 52 o9=0;
krzysiekf 0:763f2afa5e8b 53 o10=0;
krzysiekf 0:763f2afa5e8b 54 o11=0;
krzysiekf 0:763f2afa5e8b 55 o12=0;
krzysiekf 0:763f2afa5e8b 56 o13=0;
krzysiekf 0:763f2afa5e8b 57 o14=0;
krzysiekf 0:763f2afa5e8b 58 o30=0;
krzysiekf 0:763f2afa5e8b 59
krzysiekf 0:763f2afa5e8b 60 float k=3;//default scaling factor for Vrs measurements
krzysiekf 0:763f2afa5e8b 61
krzysiekf 0:763f2afa5e8b 62 float Vmax=Vprog;//holding of, either, Primary Cell sensed voltage or Programmed Voltage
krzysiekf 0:763f2afa5e8b 63 float Vsens=0;//holding of Primary Cell sensed voltage
krzysiekf 0:763f2afa5e8b 64
krzysiekf 0:763f2afa5e8b 65 chrg.period_ms(1);//PWM period
krzysiekf 0:763f2afa5e8b 66
krzysiekf 0:763f2afa5e8b 67 char s1State=0;//the soft state of s1 switch; charging stopped as default
krzysiekf 0:763f2afa5e8b 68 char s2State=0;//the soft state of s2 switch; Rs1 enabled, Rs2 disabled as default
krzysiekf 0:763f2afa5e8b 69 char s3State=0;//the soft state of s3 switch; Vprog enabled as dafult
krzysiekf 0:763f2afa5e8b 70
krzysiekf 0:763f2afa5e8b 71 float VrsIn=0;//measured voltage after rectification and filtering
krzysiekf 0:763f2afa5e8b 72 float VrsOut=0;//measured voltage on charged battery side
krzysiekf 0:763f2afa5e8b 73 float Vrs=3;
krzysiekf 0:763f2afa5e8b 74 float Vrsdrop=0;
krzysiekf 0:763f2afa5e8b 75
krzysiekf 0:763f2afa5e8b 76 hlcEn=0;//turn off all externals
krzysiekf 0:763f2afa5e8b 77
krzysiekf 0:763f2afa5e8b 78 Rs1En=1;//enable 8mA charge current as default
krzysiekf 0:763f2afa5e8b 79 wait_us(1);
krzysiekf 0:763f2afa5e8b 80 Rs1EnInd=Rs1En;//light up 8mA indicator
krzysiekf 0:763f2afa5e8b 81
krzysiekf 0:763f2afa5e8b 82 Rs2En=0;//disable 25mA charge current as default
krzysiekf 0:763f2afa5e8b 83 wait_us(1);
krzysiekf 0:763f2afa5e8b 84 Rs2EnInd=Rs2En;//turn off 25mA indicator
krzysiekf 0:763f2afa5e8b 85
krzysiekf 0:763f2afa5e8b 86 ProgVoltInd=1;//light up Programmed Voltage chosen indicator as a default
krzysiekf 0:763f2afa5e8b 87 PrimCellInd=0;//turn off the Primary Cell Sensed Voltage indicator as a default
krzysiekf 0:763f2afa5e8b 88
krzysiekf 0:763f2afa5e8b 89 while(1) {
krzysiekf 0:763f2afa5e8b 90 chrg=0.0;//start conditions after reset
krzysiekf 0:763f2afa5e8b 91 chrgInd=0;
krzysiekf 0:763f2afa5e8b 92 chrgIncr=0.0;
krzysiekf 0:763f2afa5e8b 93 tempChrg=0.0;
krzysiekf 0:763f2afa5e8b 94
krzysiekf 0:763f2afa5e8b 95 if(!s1) { //s1 being pressed; Start/Stop charging
krzysiekf 0:763f2afa5e8b 96 s1State=!s1State;//flip the soft state of s1
krzysiekf 0:763f2afa5e8b 97 wait_us(10);//delay to allow reading of the s1State after flip
krzysiekf 0:763f2afa5e8b 98 while(!s1)wait(0.3);
krzysiekf 0:763f2afa5e8b 99 }
krzysiekf 0:763f2afa5e8b 100 if(!s2) { //s2 being pressed; choose charge current level between 8mA and 25mA
krzysiekf 0:763f2afa5e8b 101 s2State=!s2State;//TRUE after first press
krzysiekf 0:763f2afa5e8b 102 wait_us(10);
krzysiekf 0:763f2afa5e8b 103 if(s2State) {//TRUE for Rs2:25mA
krzysiekf 0:763f2afa5e8b 104 wait_us(10);
krzysiekf 0:763f2afa5e8b 105 Rs1En=0;//disable Rs1:8mA
krzysiekf 0:763f2afa5e8b 106 Rs2En=1;//enable Rs2:25mA charging current
krzysiekf 0:763f2afa5e8b 107 Rs1EnInd=0;//turn off the Rs1 indicator
krzysiekf 0:763f2afa5e8b 108 Rs2EnInd=1;//turn on the Rs2 indicator
krzysiekf 0:763f2afa5e8b 109 } else {//TRUE for Rs1:8mA
krzysiekf 0:763f2afa5e8b 110 wait_us(10);
krzysiekf 0:763f2afa5e8b 111 Rs1En=1;//enable Rs1:8mA charging current
krzysiekf 0:763f2afa5e8b 112 Rs2En=0;//disable Rs2:25mA
krzysiekf 0:763f2afa5e8b 113 Rs1EnInd=1;//turn on the Rs1 indicator
krzysiekf 0:763f2afa5e8b 114 Rs2EnInd=0;//turn off the Rs2 indicator
krzysiekf 0:763f2afa5e8b 115 }
krzysiekf 0:763f2afa5e8b 116 while(!s2)wait(0.3);
krzysiekf 0:763f2afa5e8b 117 }
krzysiekf 0:763f2afa5e8b 118 if(!s3) {
krzysiekf 0:763f2afa5e8b 119 s3State=!s3State;//TRUE after first press
krzysiekf 0:763f2afa5e8b 120 wait_us(10);
krzysiekf 0:763f2afa5e8b 121 if(s3State) {//TRUE for Primary Cell sense
krzysiekf 0:763f2afa5e8b 122 Vsens=sens.read()*3.3;//read Primary Cell voltage
krzysiekf 0:763f2afa5e8b 123 wait_us(50);
krzysiekf 0:763f2afa5e8b 124 Vmax=Vsens;//use Primary Cell voltage as a limit for battery being charged
krzysiekf 0:763f2afa5e8b 125 PrimCellInd=1;//Turn on Primary Cell voltage indicator
krzysiekf 0:763f2afa5e8b 126 ProgVoltInd=0;//turn off Programmed Voltage indicator
krzysiekf 0:763f2afa5e8b 127 } else {
krzysiekf 0:763f2afa5e8b 128 Vmax=Vprog;//Programmed Voltage is being used as a limit for battery being charged
krzysiekf 0:763f2afa5e8b 129 PrimCellInd=0;//turn off Primary Cell indicator
krzysiekf 0:763f2afa5e8b 130 ProgVoltInd=1;//turn on Programmed Voltage indicator
krzysiekf 0:763f2afa5e8b 131 }
krzysiekf 0:763f2afa5e8b 132 wait(.3);
krzysiekf 0:763f2afa5e8b 133 }
krzysiekf 0:763f2afa5e8b 134 if(s1State) {//start charging process if soft state of s1 is TRUE
krzysiekf 0:763f2afa5e8b 135 do {
krzysiekf 0:763f2afa5e8b 136 if(!s1) {//stop charging if s1 is pressed during charging
krzysiekf 0:763f2afa5e8b 137 chrgInd=0;
krzysiekf 0:763f2afa5e8b 138 s1State=0;
krzysiekf 0:763f2afa5e8b 139 hlcEn=0;
krzysiekf 0:763f2afa5e8b 140 while(!s1)wait(0.3);
krzysiekf 0:763f2afa5e8b 141 break;
krzysiekf 0:763f2afa5e8b 142 }
krzysiekf 0:763f2afa5e8b 143 hlcEn=1;
krzysiekf 0:763f2afa5e8b 144 chrgInd=0;
krzysiekf 0:763f2afa5e8b 145 tempChrg=chrg;
krzysiekf 0:763f2afa5e8b 146 chrg=0;
krzysiekf 0:763f2afa5e8b 147 hlcEn=0;
krzysiekf 0:763f2afa5e8b 148 Rs1En=0;
krzysiekf 0:763f2afa5e8b 149 Rs2En=0;
krzysiekf 0:763f2afa5e8b 150 wait_us(10);
krzysiekf 0:763f2afa5e8b 151 VrsOut=vrsOut.read()*3.3*k;//measure voltage of the charged battery
krzysiekf 0:763f2afa5e8b 152 VrsIn=vrsIn.read()*3.3*k;//measure the rectified voltage
krzysiekf 0:763f2afa5e8b 153 wait_us(10);
krzysiekf 0:763f2afa5e8b 154 Vrsdrop=VrsIn-VrsOut;
krzysiekf 0:763f2afa5e8b 155 chrg=tempChrg;//resume charging at current charging level
krzysiekf 0:763f2afa5e8b 156 if(s2State)Rs2En=1;
krzysiekf 0:763f2afa5e8b 157 if(!s2State)Rs1En=1;
krzysiekf 0:763f2afa5e8b 158 if(Vrsdrop<Vrs) {
krzysiekf 0:763f2afa5e8b 159 hlcEn=1;
krzysiekf 1:822b4281ebbb 160 chrgInd=1;
krzysiekf 0:763f2afa5e8b 161 chrgIncr=0.001;
krzysiekf 0:763f2afa5e8b 162 wait_ms(10);
krzysiekf 0:763f2afa5e8b 163 chrg=chrg+chrgIncr;
krzysiekf 0:763f2afa5e8b 164 }
krzysiekf 0:763f2afa5e8b 165 } while(VrsOut<Vmax);
krzysiekf 1:822b4281ebbb 166 chrgInd=0;
krzysiekf 0:763f2afa5e8b 167 wait(0.5);
krzysiekf 0:763f2afa5e8b 168 }
krzysiekf 0:763f2afa5e8b 169 }
krzysiekf 0:763f2afa5e8b 170 }