24VDC charger

●●●Flotulopex & Co.

 

| Home | What is it | Inside | Schema | Code| Use it |

 

 

 

 

Menu

 

 

Morse

REMI

SIMON

FairTime

24VDC Charger

T+T Tester

K2000

TZR Stop Light

PIC

T50 Code Lock

Clignotant

Buzzer "Deluxe"

OPTO-Coupler

SPI DOGM LCD

SPI DOGL GLCD

DCF77

GPS

Cook’s Timer

RF Ringer

Siren

Template

PCB Making

Tools

Miscellanous

 

Downloads

 

Contact

 

 

 

 

                        

 

 

 

 

 

 

What is it?

 

24VDC Charger is a 3 stage “intelligent” Lead-Acid cell charger.

 

The following description is based on these batteries specifications.

 

          

 

In a few words, here is how it works.

 

Stage 1 (BULK): charge the batteries at constant current (about 25-30% of CA1) until the voltage reaches 2,45 Volts per element. The time needed for this must be calculated and is called "t1". When this is achieved, the charger maintains the voltage at 2,45 Volts/element until the current drops to 0,07CA. By then, 80% of the overall charging is done.

 

Stage 2 (TOPPING): keep a constant voltage of 2,45 Volts/element during t1 x 0,5; this duration is called "t2". When this time has passed, the battery is fully charged.

 

Stage 3 (FLOAT): once t1 + t2 have elapsed, the charger applies and maintains a permanent 2,275 Volts/element. This way, the battery is kept in the best charging level upon use.

 

1 Capacity in Ah.

 

 

 

 

 

Inside

 

          

Wide tracks for up to 6 amps                    Top view                          Heat sinks are needed

 

 

    

Toroidal core transformer     Proto on breadboard, water cooled!

 

 

          

Everything fits in there                    Ventilated back pannel                    Close the box!

 

 

 

 

 

Schema

 

 

 

 

Code (PICBasic)

 

'****************************************************************

'*  Name    : 24V-LEAD_Batt_Charger_16F690_PWM-ADC_10bits       *

'*  Author  : FLOTUL                                            *

'*  Notice  : Copyright (c) 2007 Flotulopex & Co.               *

'*          : All Rights Reserved                               *

'*  Date    : 08.03.2008                                        *

'*  Version : 1.0                                               *

'*  Notes   : final prg version implemented in charger          *

'*          :                                                   *

'****************************************************************

 

' LCD circuitery (LCD pinout)

'PORTB.4       (11)DB4

'PORTB.5       (12)DB5

'PORTB.6       (13)DB6

'PORTB.7       (14)DB7

'PORTC.0       ( 4)RS

'PORTC.1       ( 6)E

'-       ( 1)Vss - GND

'-            ( 2)Vdd / Vcc +5V

'-            ( 3)Vee / Vo / Contrast adjust / Pot 4k7(1-2-W3) or R2k2 (GND-3)

'-            ( 5)R/W -> to Vss

 

'------------------------------------------------------------------------------- 

' PIC 16F690 Fuses

@ DEVICE FCMEN_OFF

@ DEVICE IESO_OFF

@ DEVICE BOD_ON

@ DEVICE CPD_OFF

@ DEVICE PROTECT_OFF

@ DEVICE MCLR_OFF

@ DEVICE PWRT_OFF

@ DEVICE WDT_OFF

@ DEVICE HS_OSC

 

'-------------------------------------------------------------------------------

' Registers   76543210

OPTION_REG = %10000101 'PORT A&B Pull-Ups disabled (look WPUA & WPUB)

ANSEL      = %00010100 'Select analog inputs Channels 0 to 7

ANSELH     = %00000000 'Select analog inputs Channels 8 to 11

ADCON0     = %10000001 'A/D Module is ON (Bit5:2 select channels 0:11)

ADCON1     = %00010000 'A/D control register

CM1CON0    = %00000000 'Comparator1 Module is OFF

CM2CON0    = %00000000 'Comparator2 Module is OFF

INTCON     = %10100000 'INTerrupts CONtrol (TMR0 ON)

TRISA      = %00000100 'Set Input/Output (0 to 5)

PORTA      = %00000000 'Ports High/Low (0 to 5)

TRISB      = %00000000 'Set Input/Output (4 to 7)

PORTB      = %00000000 'Ports High/Low (4 to 7)

TRISC      = %00000001 'Set Input/Output (0 to 7)

PORTC      = %01001000 'Ports High/Low (0 to 7) - Set FAN to Lowest Speed

 

' HPWM registers (10 bits resolution settings)

T2CON      = %00000101 'Timer2 = ON (bit2), prescaler = 4

CCP1CON    = %00001100 'Select PWM Mode

CCPR1L     = 0         '8 bits (bits 9:2) of Duty Cycle final value

CCP1CON.5  = 0         '1 bit  (bit 1)    "    "    "    "     "

CCP1CON.4  = 0         '1 bit  (bit 0)    "    "    "    "     "

PR2        = 249       'sets a frequency to about 1kHz

 

'-------------------------------------------------------------------------------

' Defines

DEFINE LCD_DREG PORTB  'LCD data port

DEFINE LCD_DBIT 4      'LCD data starting bit 0 or 4 on µC

DEFINE LCD_EREG PORTC  'LCD enable port

DEFINE LCD_EBIT 1      'LCD enable bit

DEFINE LCD_RSREG PORTC 'LCD register select port

DEFINE LCD_RSBIT 2     'LCD register select bit

DEFINE LCD_BITS 4      'LCD bus size 4 or 8

DEFINE LCD_LINES 2     'Number lines on LCD

 

DEFINE ADC_BITS 10     'Number of bits in ADCIN result

'DEFINE ADC_CLOCK 3     'ADC clock source (rc = 3)

'DEFINE ADC_SAMPLEUS 50 'ADC sampling time in microseconds

 

' Initialise charging time history

'data @0, 0, 0

 

'-------------------------------------------------------------------------------

' Variables

DutyCl  VAR WORD 'Duty Cycle Set value

Ticks   VAR BYTE '61 Ticks needed to make 1 second

Second  VAR BYTE

Minute  VAR BYTE

Hour    VAR BYTE

Phase   VAR BYTE '1=Bulk, 2=Topping, 3=Float

VoltADC VAR WORD 'PORTC.0 - AN4

Voltage VAR WORD 'Voltage

Volt_U  VAR BYTE 'Voltage UNITS

Volt_D  VAR BYTE 'Voltage DECIMALS

AmpsADC VAR WORD 'PORTA.2 - AN2

Amps_U  VAR WORD 'Amps UNITS

Nrj_S   VAR WORD

Nrj_T   VAR WORD

IMax    CON 1400 'Max Amps value setting

Tempo   VAR WORD 'Temporary Var (for DIV32 calculation)

Update  VAR WORD 'General counter - Incremented every Tick

CChar_0 VAR BYTE 'Custom Character 0

CChar_1 VAR BYTE 'Custom Character 1

LED1    VAR PORTA.1 'Green

'FAN_C   var word 'FAN Lock

'DOut    var PORTA.4 'RS232 output port

 

' µC pinout (nn)

'PORTA.0 (19)ICSP Data

'PORTA.1 (18)LED1 + ICSP Clock

'PORTA.2 (17)ADC AN2 "Amps"

'PORTA.3 (4) MCLR

'PORTA.4 (3) Xtal

'PORTA.5 (2) Xtal

 

'PORTB.4 (13)LCD DB4

'PORTB.5 (12)LCD DB5

'PORTB.6 (11)LCD DB6

'PORTB.7 (10)LCD DB7

 

'PORTC.0 (16)ADC AN4 "Voltage"

'PORTC.1 (15)LCD Enable

'PORTC.2 (14)LCD Register

'PORTC.3 (7) FAN speed 1

'PORTC.4 (6)

'PORTC.5 (5) PWM

'PORTC.6 (8) FAN speed 2

'PORTC.7 (9) FAN lock alarm (not used in this version)

 

'-------------------------------------------------------------------------------

' Put subroutines on the top of program to save around 96 Words!!!

GOTO PROGRAM

 

PRINT_BULK_TIME:

    ' Elapsed time from the start of charging process

    'serout2 DOut, 49340,["t+ ", dec2 hour, ":", dec2 minute, ":", dec2 second, "  "]

    LCDOUT $FE, 2, "BULK    ", DEC2 Hour, ":", DEC2 Minute, ":", DEC2 Second

    RETURN

 

PRINT_TOPPING_TIME:

    ' Remaining time until full charge is achieved

    'serout2 DOut, 49340,["t- ", dec2 hour, ":", dec2 minute, ":", dec2 second, "  "]

    LCDOUT $FE, 2, "TOPPING ", DEC2 Hour, ":", DEC2 Minute, ":", DEC2 Second

    RETURN

 

PRINT_FLOAT_TIME:

    ' Elapsed time since FLOAT start

    'serout2 DOut, 49340,["t- ", dec2 hour, ":", dec2 minute, ":", dec2 second, "  "]

    LCDOUT $FE, 2, "FLOAT   ", DEC2 Hour, ":", DEC2 Minute, ":", DEC2 Second

    RETURN

 

PRINT_VA:

    ' Battery's charging voltage & current

    'serout2 DOut, 49340,["Ib: ", dec3 Amps, 13]

    LCDOUT $FE, $C0, CChar_0, DEC2 Volt_U, ",", DEC1 Volt_D, "V   ",_

        CChar_1, DEC4 Amps_U, "mA"

    RETURN

 

PRINT_ENERGY:

    ' Battery's given total Energy

    LCDOUT $FE, $C0," Total: ", DEC4 Nrj_T, "mAh "

    RETURN

 

'FAN_STOP:

'    CCPR1L = 0

'    CCP1CON.5 = 0

'    CCP1CON.4 = 0

'    LED1   = 0

'    lcdout $FE, 2,   " !! ABORTED !!  "

'    lcdout $FE, $C0, "   CHECK FAN    "

'    end

 

'-------------------------------------------------------------------------------

' Program

PROGRAM:

PAUSE 2000

 

'Initialize LCD display - Custom characters

LCDOUT $FE, $40, $00, $00, $0E, $06, $0A, $10, $00, $00'Char #0 = arrow "Up"

LCDOUT $FE, $48, $00, $00, $10, $0A, $06, $0E, $00, $00'Char #1 = arrow "Down"

LCDOUT $FE, $50, $00, $04, $02, $1F, $02, $04, $00, $00'Char #2 = arrow "Right"

 

ON INTERRUPT GOTO TICK_INT

 

' Initialise

INIT:

    Hour    = 0

    Minute  = 0

    Second  = 0

    Update  = 0

    Phase   = 1

    LED1    = 1

    CChar_0 = 0

    CChar_1 = 0

    DutyCl  = 700 '600=21,5V / 650=23,5V / 700=25,4V / 750=27,3V

    Volt_U  = 0

    Amps_U  = 0

    Nrj_S   = 0

    Nrj_T   = 0

    PORTC.3=1:PORTC.6=1 'FAN LOWEST Speed

    'PORTC.3=0:PORTC.6=1 'FAN LOW Speed

    'PORTC.3=1:PORTC.6=0 'FAN MEDIUM Speed

    'PORTC.3=0:PORTC.6=0 'FAN HIGH Speed

 

MAIN:

    'Automatic start - Wait until a battery is connected and detected

    IF (Update // 60 = 30) THEN 'Detect battery every 1/2 seconds (30 ticks)

        IF Amps_U > 10 THEN

            Update  = 0

            Hour    = 0

            Minute  = 0

            Second  = 0

            CChar_1 = 2

            PORTC.3=0 : PORTC.6=0 ' FAN HIGH Speed

            Phase = 1

            GOTO BULK_CHARGE_1 'Let's start the charging process

        ENDIF

    ENDIF

 

    ' Startup display sequence

    IF Update = 1    THEN LCDOUT $FE, 2, "Cathy's Scooter ":LCDOUT $FE, $C0, " Battery Charger"

    IF Update = 180  THEN LCDOUT $FE, 2, "Connect Battery ":LCDOUT $FE, $C0, "LeadAcid 24V-4Ah"

    IF Update = 360  THEN LCDOUT $FE, 2, "3 Phases Charger":LCDOUT $FE, $C0, 34, "Bulk-Top-Float", 34

    IF Update = 540  THEN LCDOUT $FE, 2, "Bulk: charge up ":LCDOUT $FE, $C0, " to 80% of capa "

    IF Update = 720  THEN LCDOUT $FE, 2, "Topping: charge ":LCDOUT $FE, $C0, "from 80% to 100%"

    IF Update = 900  THEN LCDOUT $FE, 2, "Float: keep the ":LCDOUT $FE, $C0, " batt. 100% full"

    IF Update = 1080 THEN LCDOUT $FE, 2, "   Thanks To    ":LCDOUT $FE, $C0, " Mr DEWARRAT Sr "

    IF Update > 1260 THEN Update = 0

 

GOTO MAIN

 

BULK_CHARGE_1:' Rise voltage up to 30V until load reaches 1200mA

    IF (Update // 60 = 0) THEN LED1 = 1

    IF (Update // 180 = 0) THEN LED1 = 0

   

    IF (Update // 60 = 0) THEN 'do it every second

 

        ' Rise Voltage

        IF Amps_U < 1200 THEN

            IF Volt_U < 30 THEN DutyCl = DutyCl + 1

        ENDIF

 

        ' Drop Amps_U if a little too high

        IF Amps_U >= 1250 THEN DutyCl = DutyCl - 1

 

        ' Check if battery is still connected

        IF Amps_U < 10 THEN INIT

 

    ENDIF

 

    ' 30V at 1200mA reached - Go to BULK_CHARGE_2

    IF Amps_U < 1200 THEN

        IF Volt_U >= 30 THEN

            Update = 0

            CChar_0 = 2

            CChar_1 = 1

            LED1 = 0

            GOTO BULK_CHARGE_2

        ENDIF

    ENDIF

 

    ' Refresh display

    IF (Update // 60 = 0) THEN GOSUB PRINT_BULK_TIME

    IF Update = 0   THEN GOSUB PRINT_VA

    IF Update = 180 THEN GOSUB PRINT_ENERGY

 

    IF Update > 360 THEN Update = 0 ' Make sure Update is cleared

 

GOTO BULK_CHARGE_1

   

   

BULK_CHARGE_2:' Stay at 30V until load drops down to 280mA

    IF (Update // 60 = 0) THEN LED1 = 1

    IF (Update // 180 = 0) THEN LED1 = 0

 

    IF (Update // 60 = 0) THEN 'do it every second

 

        ' Adjust FAN Speed according to Amps_U level

        IF Amps_U <= 800 THEN PORTC.3=1 : PORTC.6=0 'MEDIUM

 

        ' Keep Voltage at 30V

        IF Volt_U > 30 THEN DutyCl = DutyCl - 1

        IF Volt_U < 30 THEN DutyCl = DutyCl + 1

       

        ' Check if battery is still connected

        IF Amps_U < 10 THEN INIT

 

        ' Ready to go to TOPPING charge

        IF Volt_U >= 30 THEN

            IF Amps_U <= 280 THEN 'Calculate t2 (= 1/2 of t1)

                ' Calculate time for TOPPING (t2)

                Hour = Hour * 60 'convert hours in minutes

                Minute = Hour + Minute 'cumulate minutes

                Tempo  = Minute / 2 'divide by 2 since TOPPING must be half as long as t1

                Hour   = Tempo / 60 'find-out Hours

                Minute = Tempo // 60'find-out Minutes

                Second = 0

                CChar_0 = 2

                CChar_1 = 2               

                PORTC.3=0 : PORTC.6=1 'FAN LOW Speed

                Phase = 2

                Update = 0

                GOTO TOPPING_CHARGE

            ENDIF

        ENDIF    

       

    ENDIF

 

    ' Refresh display

    IF (Update // 60 = 0) THEN GOSUB PRINT_BULK_TIME

    IF Update = 0   THEN GOSUB PRINT_VA

    IF Update = 180 THEN GOSUB PRINT_ENERGY

 

    IF Update > 360 THEN Update = 0 ' Make sure Update is cleared

   

GOTO BULK_CHARGE_2

 

 

TOPPING_CHARGE: ' Charge during t2 at 12x2,5V=30V

    IF (Update // 60 = 0) THEN LED1 = 1

    IF (Update // 120 = 0) THEN LED1 = 0

 

    IF (Update // 60 = 0) THEN 'do it every second

 

        ' Keep Voltage at 30V

        IF Volt_U > 30 THEN DutyCl = DutyCl - 1

        IF Volt_U < 30 THEN DutyCl = DutyCl + 1

 

        ' Check if battery is still connected

        IF Amps_U < 10 THEN INIT

 

    ENDIF       

 

    ' If TOPPING (countdown) done, go to FLOAT

    IF Second = 0 THEN           

        IF Minute = 0 THEN

            IF Hour = 0 THEN

                PORTC.3=1 : PORTC.6=1 'FAN LOWEST Speed

                Phase = 3

                Update = 0

                LED1 = 1 ' Led steady ON

                GOTO FLOAT_CHARGE

            ENDIF

        ENDIF

    ENDIF

   

    ' Refresh display

    IF (Update // 60 = 0) THEN GOSUB PRINT_TOPPING_TIME

    IF Update = 0   THEN GOSUB PRINT_VA

    IF Update = 180 THEN GOSUB PRINT_ENERGY   

 

    IF Update > 360 THEN Update = 0 ' Make sure Update is cleared

   

GOTO TOPPING_CHARGE

 

 

FLOAT_CHARGE: 'Charge (or "Trickle") at 12 x 2,275V = 27,3V

    ' Adjust Voltage every second

    IF (Update // 60 = 0) THEN

        IF Voltage > 274 THEN DutyCl = DutyCl - 1

        IF Voltage < 272 THEN DutyCl = DutyCl + 1

    ENDIF   

   

    IF (Update // 60 = 0) THEN GOSUB PRINT_FLOAT_TIME

    IF Update = 0 THEN GOSUB PRINT_VA

    IF Update = 120 THEN LCDOUT $FE, $C0,"Battery Charged "

    IF Update = 240 THEN LCDOUT $FE, $C0," Ready For Use! "

    IF Update = 360 THEN GOSUB PRINT_ENERGY

    IF Update > 540 THEN Update = 0

 

GOTO FLOAT_CHARGE

 

END

 

'-------------------------------------------------------------------------------

DISABLE

TICK_INT:

    Ticks = Ticks + 1   'Count pieces of seconds

    Update = Update + 1 'Counter for updating screens and operations

   

    ' Alternate Voltage and Amps_U measurements

    IF (Ticks & %00000001) = 0 THEN   'Read Bit 0

        ADCIN 4, VoltADC

    ELSE       

        ADCIN 2, AmpsADC

    ENDIF   

   

    IF Ticks < 61 THEN TICK_INT_RESET 'if not 61, continue count!

   

    Ticks = 0 ' One second past - do the following steps

 

''    ' FAN check

''    adcin 9, fan_c

''    if fan_c > 20000 then FAN_STOP

 

    ' DIV32 Must be used within DISABLE

    ' Convert Voltage in displayable value "UU.D"

    Tempo   = VoltADC * 100

    Voltage = DIV32 273   

    Volt_U = Voltage / 10

    Volt_D = Voltage // 10

    ' Convert Amps in displayable value "nnnn"

    Tempo = AmpsADC * 10000

    Amps_U = DIV32 5359                  

 

    ' Count UP - Phase 1 and 3 only

    IF Phase <> 2 THEN 'if phase = 1 or phase = 3

        Nrj_S = Nrj_S + ((Amps_U * 20)/ 36) 'comes from (Amps_U * 20 * 100) / 3600

        Second = Second + 1

        IF Second = 60 THEN   

            Second = 0

            Minute = Minute + 1

            Nrj_T = Nrj_T + (Nrj_S / 2000)'Adds to total Energy EVERY MINUTE!!!

            Nrj_S = 0

            IF Minute = 60 THEN

                Minute = 0

                Hour = Hour + 1

            ENDIF

        ENDIF

    ELSE

        ' Count DOWN - Phase 2 only

        IF Second = 0 THEN

            Second = 60

            IF Minute = 0 THEN

                IF Hour > 0 THEN

                    Minute = 60

                    Hour = Hour - 1

                ENDIF

            ENDIF

            Minute = Minute - 1

            Nrj_T = Nrj_T + (Nrj_S / 2000)

            Nrj_S = 0

        ENDIF

        Second = Second - 1

        Nrj_S = Nrj_S + ((Amps_U * 20)/ 36)

    ENDIF   

 

    IF Amps_U >= IMax THEN DutyCl = DutyCl - 1 'Sink Voltage if Amps_U is too high

 

    TICK_INT_RESET:

        INTCON.2 = 0   'Reset timer interrupt flag and continue de Ticks count

 

    ' Set voltage (dutycycle)

    CCPR1L    = DutyCl >> 2

    CCP1CON.5 = DutyCl.1

    CCP1CON.4 = DutyCl.0

 

RESUME

ENABLE

 

 

 

 

Use it

 

Connect de battery to the charger and forget it until you need it!

 

See what displays you’ll get using it: