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

main.cpp

Committer:
krzysiekf
Date:
2014-03-01
Revision:
1:822b4281ebbb
Parent:
0:763f2afa5e8b

File content as of revision 1:822b4281ebbb:

#include "mbed.h"

DigitalOut o5(p5);//o5 through o14 and o30 set as outputs to prevent any coupling of the external noise
DigitalOut o6(p6);
DigitalOut o7(p7);
DigitalOut o8(p8);
DigitalOut o9(p9);
DigitalOut o10(p10);
DigitalOut o11(p11);
DigitalOut o12(p12);
DigitalOut o13(p13);
DigitalOut o14(p14);
DigitalOut o30(p30);

PwmOut chrg(p21);//PWM output

AnalogIn vrsIn(p16);//rectified voltage measurement, high side of sense resistor
AnalogIn vrsOut(p17);//charged battery voltage measurement, low side of sense resistor
AnalogIn sens(p15);//sense Primary Cell voltage

DigitalIn s1(p22);//switch for togling START/STOP
DigitalIn s2(p23);//switch for togling between 8 and 25mA
DigitalIn s3(p19);//switch for togling PrimCell/ProgVolt

DigitalOut PrimCellInd(p20);//Primary Cell sensed voltage chosen as limit for HLC battery
DigitalOut ProgVoltInd(p18);//Programmed Voltage chosen as limit for HLC battery

DigitalOut chrgInd(p26);//indicates real time charging; only on when PWM was issued

DigitalOut Rs1EnInd(p25);//indicator for 8mA charge current
DigitalOut Rs1En(p27);//enable 8mA sense resistor

DigitalOut Rs2EnInd(p24);//indicator for 25mA charge current
DigitalOut Rs2En(p28);//enable 25mA sense resistor

DigitalOut hlcEn(p29);//enable HLC for charging

int main()
{
    hlcEn=0;
    Rs1En=0;
    Rs2En=0;
    wait(1);
    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
    float tempChrg=0.0;//temporary holding of the PWM Duty Cycle level
    float chrgIncr=0.0;//temporary holding of the PWM increment Duty Cycle

    o5=0;//o5 through o14 and o30 set to output "0" (GND)
    o6=0;
    o7=0;
    o8=0;
    o9=0;
    o10=0;
    o11=0;
    o12=0;
    o13=0;
    o14=0;
    o30=0;

    float k=3;//default scaling factor for Vrs measurements

    float Vmax=Vprog;//holding of, either, Primary Cell sensed voltage or Programmed Voltage
    float Vsens=0;//holding of Primary Cell sensed voltage

    chrg.period_ms(1);//PWM period

    char s1State=0;//the soft state of s1 switch; charging stopped as default
    char s2State=0;//the soft state of s2 switch; Rs1 enabled, Rs2 disabled as default
    char s3State=0;//the soft state of s3 switch; Vprog enabled as dafult

    float VrsIn=0;//measured voltage after rectification and filtering
    float VrsOut=0;//measured voltage on charged battery side
    float Vrs=3;
    float Vrsdrop=0;

    hlcEn=0;//turn off all externals

    Rs1En=1;//enable 8mA charge current as default
    wait_us(1);
    Rs1EnInd=Rs1En;//light up 8mA indicator

    Rs2En=0;//disable 25mA charge current as default
    wait_us(1);
    Rs2EnInd=Rs2En;//turn off 25mA indicator

    ProgVoltInd=1;//light up Programmed Voltage chosen indicator as a default
    PrimCellInd=0;//turn off the Primary Cell Sensed Voltage indicator as a default

    while(1) {
        chrg=0.0;//start conditions after reset
        chrgInd=0;
        chrgIncr=0.0;
        tempChrg=0.0;

        if(!s1) { //s1 being pressed; Start/Stop charging
            s1State=!s1State;//flip the soft state of s1
            wait_us(10);//delay to allow reading of the s1State after flip
            while(!s1)wait(0.3);
        }
        if(!s2) { //s2 being pressed; choose charge current level between 8mA and 25mA
            s2State=!s2State;//TRUE after first press
            wait_us(10);
            if(s2State) {//TRUE for Rs2:25mA
                wait_us(10);
                Rs1En=0;//disable Rs1:8mA
                Rs2En=1;//enable Rs2:25mA charging current
                Rs1EnInd=0;//turn off the Rs1 indicator
                Rs2EnInd=1;//turn on the Rs2 indicator
            } else {//TRUE for Rs1:8mA
                wait_us(10);
                Rs1En=1;//enable Rs1:8mA charging current
                Rs2En=0;//disable Rs2:25mA
                Rs1EnInd=1;//turn on the Rs1 indicator
                Rs2EnInd=0;//turn off the Rs2 indicator
            }
            while(!s2)wait(0.3);
        }
        if(!s3) {
            s3State=!s3State;//TRUE after first press
            wait_us(10);
            if(s3State) {//TRUE for Primary Cell sense
                Vsens=sens.read()*3.3;//read Primary Cell voltage
                wait_us(50);
                Vmax=Vsens;//use Primary Cell voltage as a limit for battery being charged
                PrimCellInd=1;//Turn on Primary Cell voltage indicator
                ProgVoltInd=0;//turn off Programmed Voltage indicator
            } else {
                Vmax=Vprog;//Programmed Voltage is being used as a limit for battery being charged
                PrimCellInd=0;//turn off Primary Cell indicator
                ProgVoltInd=1;//turn on Programmed Voltage indicator
            }
            wait(.3);
        }
        if(s1State) {//start charging process if soft state of s1 is TRUE
            do {
                if(!s1) {//stop charging if s1 is pressed during charging
                    chrgInd=0;
                    s1State=0;
                    hlcEn=0;
                    while(!s1)wait(0.3);
                    break;
                }
                hlcEn=1;
                chrgInd=0;
                tempChrg=chrg;
                chrg=0;
                hlcEn=0;
                Rs1En=0;
                Rs2En=0;
                wait_us(10);
                VrsOut=vrsOut.read()*3.3*k;//measure voltage of the charged battery
                VrsIn=vrsIn.read()*3.3*k;//measure the rectified voltage
                wait_us(10);
                Vrsdrop=VrsIn-VrsOut;
                chrg=tempChrg;//resume charging at current charging level
                if(s2State)Rs2En=1;
                if(!s2State)Rs1En=1;
                if(Vrsdrop<Vrs) {
                    hlcEn=1;
                    chrgInd=1;
                    chrgIncr=0.001;
                    wait_ms(10);
                    chrg=chrg+chrgIncr;
                }
            } while(VrsOut<Vmax);
            chrgInd=0;
            wait(0.5);
        }
    }
}