PDA

View Full Version : MPPT solar battery charger



iw2fvo
- 28th April 2014, 14:08
I have built up a solar battery charger to be used in my Radio Ham station. It is used to keep charge a 27 AH 12 V SLA battery.
The panel power is 50 watt for now. I am NOT a programmer or a software guy and so I wrote the program for the pic18f4523 using a picbasic pro in a very preliminary mode.
The Pic is running at 40 Mhz clock speed and controls the duty cycle of a buck converter at 75 khz frequency.
The whole charger works well : there is a small problem relevant to the status selection that appears when the sky is cloudy (but not always): it jumps between status 0 and status 3.
This is not really a problem but I would like to fix it and make it stable in all the sky condition.
I told before that I am not an expert in programming so I would like if someone could help to improve the software that I wrote: I also think that there could be a lot of simplifications, corrections and others to be improved.
I will try to attach the basic program here. I could post the schematics diagram too but it is hand drawn.
Thanks in advance for any assistance .
Beste regards,
Ambrogio

iw2fvo
- 30th April 2014, 14:04
Demon,
thanks for having respond to my msg.
here is the code.
I will re_draw the schematics ( by hand )in a decent way tonight. I will post it tomorrow.
thnks
Ambrogio



'************************************************* ***************
'* Name : pic 18f4523 *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 28/04/2014 *
'* Version : 1.0 *
'* Notes : modificare file 18f4523 nella cartella PBP *
'* : per il config ... oscillatore MCLR etc *
'* picbasic pro 2.6 : long used. 12294 BYTES USED. *
'* 50 WATT SOLAR PANEL, 27 AH 12 VDC SLA BATTERY *
'************************************************* ***************

' WARNING:
' HSPLL OSCILLATOR HAS BEEN DEFINED IN THE PBP FOLDER > 18F4523 FILE

DEFINE OSC 40 ' 10 MHz XTAL AND x4 PLL GIVES 40 MHz CLOCK SPEED.
INCLUDE "MODEDEFS.BAS"

'DEBUG DEFINITION> WITH_OUT MAX 232...USE INVERTED=1, 57600 BAUD 8N1

' Set Debug pin port ________________________________________
DEFINE DEBUG_REG PORTC
' Set Debug pin bit _________________________________________
DEFINE DEBUG_BIT 6
' Set Debug baud rate _________________________________________
DEFINE DEBUG_BAUD 57600
' Set Debug mode: 0 = true, 1 = inverted ______________________
DEFINE DEBUG_MODE 1


' LCD CONFIGURATION ...HD_4470 LIKE > 4 LINES BY 20 CHRS IS USED HERE

' Set LCD Data port _________________________________________
DEFINE LCD_DREG PORTD
' Set starting Data bit (0 or 4) if 4-bit bus ________
DEFINE LCD_DBIT 0
' Set LCD Register Select port (R/S) ________________________
DEFINE LCD_RSREG PORTD
' Set LCD Register Select bit _______________________________
DEFINE LCD_RSBIT 5
' Set LCD Enable port (EN_DCDC)__________________________________
DEFINE LCD_EREG PORTD
' Set LCD Enable bit ____________________________________
DEFINE LCD_EBIT 4
' Set LCD bus size (4 or 8 bits) _____________________________
'DEFINE LCD_BITS 4
' Set number of lines on LCD ______________________________
DEFINE LCD_LINES 4
' Set command delay time in us ______________________________
DEFINE LCD_COMMANDUS 2500
' Set data delay time in us _________________________________
DEFINE LCD_DATAUS 50
PAUSE 500

' SOME CONSTANTS TO CONTROL THE LCD.

INS CON 254 ' $FE: INSTRUCTION COMMAND MODE
CLR CON 1 ' CLEAR LCD , GOTO FIRST LINE, FIRST CHARACTER
DG CON 223 ' SIMBOLO DEL GRADO °
LINE1 CON 128 ' $80: GOTO LINE 1
LINE2 CON 192 ' $C0: GOTO LINE 2
LINE3 CON 148 ' $94: GOTO LINE 3
LINE4 CON 212 ' $D4: GOTO LINE 4
' eg.: LCDOUT INS, LINE1, "PIBPO TXT=",........

' ADC CONFIGURATION

ADCON1=%00001010 ' AN0,AN1,AN2,AN3,AN4 ENABLED.THE REMAINING PINS ARE DIGITAL
VB_ADC VAR WORD ' AN0 PIC_PIN 2 ' BATTERY VOLTAGE
VP_ADC VAR WORD ' AN1 PIC_PIN 3 ' PANEL VOLTAGE
IP_ADC VAR WORD ' AN2 PIC_PIN 4 ' PANEL CURRENT
IB_ADC VAR WORD ' AN3 PIC_PIN 5 ' BATTERY VOLTAGE
POT_ADC VAR WORD ' AN4 PIC_PIN 7 ' POT VOLTAGE FOR MANUAL DUTY INPUT...

' FILTERS '................................................. .......
IPT VAR WORD
VPT VAR WORD
VBT VAR WORD
IBT VAR WORD
AVG VAR BYTE
AVG=8 ' MAX AVG=16 4096*16=65536 IN A WORD ! PANEL data
AVG_B VAR BYTE
AVG_B=4 ' MAX AVG_B=16 4096*16=65536 IN A WORD ! BATTERY data
I VAR BYTE
Y VAR BIT
Y=0
Z VAR BYTE
Z=0
DLY_FLG VAR BIT
DLY_FLG =1
IPF_ADC VAR WORD
VPF_ADC VAR WORD
VBF_ADC VAR WORD
IBF_ADC VAR WORD
'...................................

VP VAR LONG
IP VAR LONG
VB VAR LONG
IB VAR LONG
WP VAR LONG
WB VAR LONG
IBSIGN VAR BYTE ' BATTERY CURRENT SIGN

DUTY VAR WORD ' PIC PWM DUTY CYCLE CONTROL
DUTY=150 ' START AT MINIMUM DUTY
GOSUB SET_PWM
DUTY_S VAR BYTE ' DUTY CYCLE STEP for MPPT
DUTY_S=1 ' MUST BE WIDE ENOUGH TO OVERCOME PANEL DATA NOISE !
' IF MPP IS NOT FOUND USE 2, 3, 4 OR 5...
LD_EN VAR PORTC.1 ' PIC_PIN 16 LOAD POWER MOSFET CONTROL PIN
LOW LD_EN ' DISABLE LOAD POWER MOSFET


EN_DCDC VAR PORTC.3 ' PIC_pin 18 DC/DC CONVERTER ENABLE
low EN_DCDC ' DISABLE DC/DC CONVERTER

LOAD VAR BIT
LOAD=1

MODE VAR BYTE
MODE=0

STATE VAR BYTE
STATE=0
' STATE 0= OFF
' STATE 1= ON
' STATE 3= FLOAT
' STATE 4= BULK

DV VAR BIT ' PANEL DELTA VOLT USED FOR HILL CLIMBING
DP VAR BIT ' PANEL DELTA POWER
VP_OLD VAR LONG ' OLD PANEL VOLTAGE
WP_OLD VAR LONG ' OLD PANEL POWER

' SCAN FOR MPP ......................

WPMAX VAR LONG
WPMAX=0
VPMAX VAR LONG
VPMAX=0
IPMAX VAR LONG
IPMAX =0
VBMAX VAR LONG
IBMAX VAR LONG
WBMAX VAR LONG
DUTYMAX VAR BYTE
DUTYMAX=0


' BACK LIGHTING .................................................. ....

BCK_LT VAR PORTA.4 ' PIC_PIN 6
FOR I=3 TO 0 STEP -1 ' LCD BACK LIGHT TEST AT POWER ON
HIGH BCK_LT
pAUSE 100
LOW BCK_LT
PAUSE 100
NEXT I
HIGH BCK_LT ' LEAVE BACK LIGHT ON AT THE END ...


' EXTERNAL POWER .................................................. ......

EXT_PWR_RLY VAR PORTC.0 ' PIC_PIN 15 OUTPUT CONTROL FOR EXT_PWR SOURCE RELAY
HIGH EXT_PWR_RLY ' DISABLE EXT PWR_RELAY HIGH= DISABLE
EXTPWR_OK VAR PORTC.4 ' PIC_PIN 23 INPUT > POWER_LINE STATUS; 1=OK
U_VOLT VAR BIT ' EXT POWER MONITOR
U_VOLT=0 ' EXT POWER GOOD
U_FLG VAR BIT ' BATTERY UNDERVOLTAGE FLAG
U_FLG=1
EX VAR BIT
EX=0

' SPLASH SCREEN:

Lcdout INS,line1, "Ambrogio 06/04/2014 " ' LCD CHECK
Lcdout INS,line2, "PV PIC18F4523 "
debug 13,10,13,10
DEBUG " STARTING H E R E ! ! ! ! " ' SERIAL LINK CHECK
PAUSE 1000
LCDOUT INS,CLR ' TURN LCD OUT

' PUSH BUTTONS PIN ASSIGNEMENT

PB_1 VAR PORTE.0 'PIC_PIN 8 STEPS THROUGH THE MODES
PB_2 VAR PORTE.1 'PIC_PIN 9
PB_3 VAR PORTE.2 'PIC_PIN 10 TOGGLE LOAD MOSFET


'************************************************* *******************
MAIN: ' ************************************************** **********
'************************************************* *******************

' PB_1 SELECTS THE MODES ...
' mode =0 is THE normal OPERATING MODE
' mode =1 pot input controls the duty cycle
' mode =2 scan duty cycle to search for the MPP CONDITION
' mode =3 TOGGLES the duty cycle to see the system response caracteristics

' MODES SELECTION....................

IF PB_1=0 THEN ' MODE SELECTION...
MODE=MODE+1
IF MODE >=4 THEN
MODE=0
ENDIF

IF MODE=1 THEN
LCDOUT INS, CLR
HIGH EN_DCDC
ENDIF

IF MODE=2 THEN
LCDOUT INS, CLR
WPMAX=0 ' reset maximum registers
VPMAX=0
IPMAX=0
VBMAX=0
IPMAX=0
WBMAX=0
DUTYMAX=0
HIGH EN_DCDC
DUTY=150 ' THIS IS MY MINIMUM DUTY CYCLE
GOSUB SET_PWM
PAUSE 1000
ENDIF

IF MODE=3 THEN
LCDOUT INS, CLR
LCDOUT INS, LINE1, " DC STEP TEST "
ENDIF

WHILE PB_1=0: WEND
ENDIF


' LOW VOLTAGE PROTECTION ...and load control..................................

IF ( VB<11800 ) THEN ' BATT LOWER THAN 11.8 Vdc
U_VOLT=1 ' SET UNDER_VOLTAGE FLAG
LOW LD_EN ' DISABLE LOAD
LOAD=0
U_FLG=1
ELSE
IF ( VB>12600 ) THEN ' IF VBATT MORE THAN 12.6 Vdc
U_VOLT=0 ' RESET UNDER_VOLTAGE FLAG
IF U_FLG=1 THEN
HIGH LD_EN ' ENABLE LOAD
LOAD=1
U_FLG=0
ENDIF
ENDIF
ENDIF

IF (U_VOLT=1) AND (EXTPWR_OK=1) THEN
LOW EXT_PWR_RLY ' ACTIVATE EXT POWER RELAY
EX=1
ELSE
IF U_VOLT=0 THEN
HIGH EXT_PWR_RLY ' RELASE EXT POWER RELAY
EX=0
ENDIF
ENDIF

IF U_VOLT=0 THEN
IF PB_3=0 THEN
if LOAD=0 THEN
LOAD=1
ELSE
LOAD=0
ENDIF
IF LOAD=0 THEN
LOW LD_EN
ENDIF
IF LOAD=1 THEN
HIGH LD_EN
ENDIF
WHILE PB_3=0 : WEND
ENDIF
ENDIF


' MODES MANAGEMENT BY PUSH BUTTONS ...........................................

IF MODE=0 THEN ' NORMAL MODE ........................................
GOTO NORMAL_MODE
ENDIF

IF MODE=1 THEN ' POT CONTROLLED DUTY CYCLE............................

LCDOUT INS, LINE1,"POT CONTROLLED DUTY:"
GOSUB ACQ_POT ' ACQ TAKES ABOUT 2.3 mSEC
DUTY=((POT_ADC/39)+149) ' POT CONTROLS DUTY 0>4096 = 150 to 254
GOSUB SET_PWM
GOSUB GET_PANEL_DATA
GOSUB GET_BATTERY_DATA
LCDOUT INS, LINE3,DEC VP/1000,".",DEC1 VP/100," ",DEC IP/1000,_
".",DEC2 IP/10," ",DEC WP/1000,".",DEC1 WP/100," ", DEC DUTY," "
LCDOUT INS, LINE4,DEC VB/1000,".",DEC1 VB/100," ",IBSIGN,DEC IB/1000,_
".",DEC2 IB/10, " ",IBSIGN,DEC WB/1000,".",DEC1 WB/100," "
GOSUB SERIAL_OUT
GOTO MAIN
ENDIF

IF MODE=2 THEN ' SCAN DUTY CYCLE FOR MPP SEARCHING.................

DUTY=DUTY+1 ' INCREMENT DUTY CYCLE
GOSUB SET_PWM
PAUSE 10 ' NOT REALLY NEEDED .. LCDOUT PROVIDES TIME DLY
GOSUB GET_PANEL_DATA
GOSUB GET_BATTERY_DATA

IF WP> WPMAX THEN ' STORE MAX READINGS
WPMAX=WP
VPMAX=VP
IPMAX=IP
VBMAX=VB
IBMAX=IB
WBMAX=WB
DUTYMAX=DUTY
ENDIF

IF DUTY >= 254 THEN
LCDOUT INS, CLR
LCDOUT INS, LINE1, " MAX POWER : "
LCDOUT INS, LINE3,DEC VPMAX/1000,".",DEC1 VPMAX/100," ",_
DEC IPMAX/1000,".",DEC2 IPMAX/10," ",DEC WPMAX/1000,_
".",DEC1 WPMAX/100," ", DEC DUTYMAX
LCDOUT INS,LINE4,DEC VBMAX/1000,".",DEC1 VBMAX/100," ",_
DEC IBMAX/1000,".",DEC2 IBMAX/10," ",DEC WBMAX/1000,_
".",DEC1 WBMAX/100
DUTY=150
GOSUB SET_PWM
while PB_2=1 :wend ' WAIT FOR PB_2 TO BE PRESSED

ENDIF

lcdout ins, line1, "MAX PWR SEARCHING:"
LCDOUT INS, LINE3,DEC VP/1000,".",DEC1 VP/100," ",DEC IP/1000,_
".",DEC2 IP/10," ",DEC WP/1000,".",DEC1 WP/100," ", DEC DUTY," "
LCDOUT INS, LINE4,DEC VB/1000,".",DEC1 VB/100," ",IBSIGN,DEC IB/1000,_
".",DEC2 IB/10, " ",IBSIGN,DEC WB/1000,".",DEC1 WB/100," "

GOSUB SERIAL_OUT
GOTO MAIN

ENDIF

IF MODE=3 THEN 'DUTY STEP CHANGE RESPONSE TEST > SET TWO DUTY VALUES
'SET PAUSE FOR STEP TIME_WIDTH ,,,,,,,,,,,,,,,,,,,,,,,,,
' system response time to duty change is about 15 msec
' measured with a scope
STEP_DUTY:
IF Y=0 THEN
HIGH BCK_LT ' CONNECT TO SCOPE TRIGGER INPUT
DUTY=170 ' FIRST DUTY VALUE
GOSUB SET_PWM
Y=1
PAUSE 50 ' WIDTH
GOSUB GET_PANEL_DATA
GOSUB SERIAL_OUT
ENDIF

IF Y=1 THEN
low bck_lt
DUTY=175 ' SECOND DUTY VALUE > DUTY_step is 5 now
GOSUB SET_PWM
Y=0
PAUSE 50 ' step time WIDTH IS 50 MSEC
GOSUB GET_PANEL_DATA
GOSUB SERIAL_OUT
GOTO MAIN
ENDIF
ENDIF

NORMAL_MODE: '************************************************* ************

' BATTERY STATE CONTROL .................................................. ....

GOSUB GET_PANEL_DATA ' 2.3 msec x avg
GOSUB GET_BATTERY_DATA ' 2.3 msec x avg_b


SELECT CASE STATE ' MODIFIED TIM NOLAND PROGRAM IN c LANGUAGE... ( ! )

CASE 0 ' OFF *** * * * * * * * * * * * * * * * * * * * * * * * * * *

Z=Z+1
IF Z>=254 THEN ' wait sometime for the battery to settle down
DLY_FLG=0
ENDIF
DUTY=150 ' MINIMUM DUTY CYCLE.
low EN_DCDC ' DISABLE DC / DC CONVERTER
GOSUB SET_PWM
debug dec z,13,10
IF DLY_FLG=0 THEN
IF VP > VB+1500 THEN ' day light is coming ...
IF VB < 13800 THEN
DUTY=150
HIGH EN_DCDC
GOSUB SET_PWM
PAUSE 1000
STATE=1 ' >> ON
ENDIF
ENDIF
ENDIF

CASE 1 ' ON *** * * * * * * * * * * * * * * * * * * * * * * * * * *

HIGH EN_DCDC
IF (VP < VB) and ( IP<80 ) THEN ' it is dark
DLY_FLG=1 : Z=0
DUTY=150
GOSUB SET_PWM
STATE= 0 ' >> OFF
ENDIF

IF VB > 14800 THEN ' MAX BATTERY VOLTAGE IS 14.8 VDC
STATE=2 ' >> FLOAT
DUTY=150
GOSUB SET_PWM
ENDIF

IF ( WP < 5000 ) THEN
DUTY=254
GOSUB SET_PWM
ENDIF

IF WP> 5000 THEN
DUTY=240
GOSUB SET_PWM
STATE=3 ' >> BULK
ENDIF

CASE 2 ' FLOAT *** * * * * * * * * * * * * * * * * * * * * * * * * *

HIGH EN_DCDC
IF VB > 14200 THEN ' KEEP FLOAT VOLTAGE @ 13.8 TO 14.2 VDC
DUTY=DUTY-1 ' DECREASE DUTY
GOSUB SET_PWM
ENDIF
IF VB < 13800 THEN
DUTY=DUTY+1 ' INCREASE DUTY
GOSUB SET_PWM
ENDIF

IF DUTY >= 254 THEN
DUTY=200
GOSUB SET_PWM
STATE=3 ' >> BULK
ENDIF

IF (VP < VB) and ( IP<80 ) THEN
DLY_FLG=1 : Z=0
DUTY=150
GOSUB SET_PWM
STATE=0 ' >> OFF
ENDIF

CASE 3 ' BULK

HIGH EN_DCDC
IF (WP < 5000) THEN
STATE= 1 ' >> ON
ENDIF

IF WP >= 5000 THEN
GOSUB MPPT
ENDIF

IF (VP < VB) and ( IP<80 ) THEN
DLY_FLG=1 : Z=0
DUTY=150
GOSUB SET_PWM
STATE=0 ' >> OFF
ENDIF

IF VB > 14800 THEN
DUTY=150
GOSUB SET_PWM
STATE=2 ' >> FLOAT
ENDIF

END SELECT


' DATA OUTPUT TO LCD, SERIAL AND RADIO.......................................

GOSUB DIS_LCD ' execution time is 15 msec

GOSUB SERIAL_OUT ' execution time is 25 msec

GOTO MAIN ' main loop execution time is 65 msec if avg=8 and
' avg_b=4

'================================================= ===========================
'======================== SUBROUTINES =====================================
'================================================= ===========================


ACQ_PV: 'ACQUIRE PV ANALOG DATA ... 2.3 msec ........................

' READ ANALOG 0 VP .........................
ADCON0=%00000000 ' SELECT AN0, VP
ADCON2=%10100110 ' ACQ TIME AND FOSC SELECTION
ADCON0=%00000001 ' ON, ACCESO
PAUSE 1 ' INPUT RESISTANCE AND CAP FOR DC ACQISISTION
ADCON0=%00000011 ' ON + GO
WHILE ADCON0.1=1 ' WAIT FOR CONVERSION COMPLETED , DONE
WEND
VP_ADC=(ADRESH<<8) + ADRESL ' ADC RESULT 12 BIT
ADCON0=%00000000 ' TURN OFF,

'READ ANALOG 2 IP ........................
ADCON0=%00001000 ' SELECT AN0, IP
ADCON2=%10100110 ' ACQ TIME AND FOSC SELECTION
ADCON0=%00001001 ' ON, ACCESO
PAUSE 1 ' INPUT RESISTANCE AND CAP FOR DC ACQISISTION
ADCON0=%00001011 ' ON + GO
WHILE ADCON0.1=1 ' WAIT FOR CONVERSION COMPLETED , DONE
WEND
IP_ADC=(ADRESH<<8)+ ADRESL ' ADC RESULT 12 BIT
ADCON0=%00000000 ' TURN OFF,

RETURN

ACQ_BATT: ' ACQUIRE BATTERY ANALOG DATA ........ 2.3 msec ................

' READ ANALOG 1 VB ..........................
ADCON0=%00000100 ' SELECT AN0, VB
ADCON2=%10100110 ' ACQ TIME AND FOSC SELECTION
ADCON0=%00000101 ' ON, ACCESO
PAUSE 1 ' INPUT RESISTANCE AND CAP FOR DC ACQISISTION
ADCON0=%00000111 ' ON + GO
WHILE ADCON0.1=1 ' WAIT FOR CONVERSION COMPLETED , DONE
WEND
VB_ADC=(ADRESH<<8) + ADRESL ' ADC RESULT 12 BIT
ADCON0=%00000000 ' TURN OFF,


'READ ANALOG 3 IB ........................
ADCON0=%00001100 ' SELECT AN0, IB
ADCON2=%10100110 ' ACQ TIME AND FOSC SELECTION
ADCON0=%00001101 ' ON, ACCESO
PAUSE 1 ' INPUT RESISTANCE AND CAP FOR DC ACQISISTION
ADCON0=%00001111 ' ON + GO
WHILE ADCON0.1=1 ' WAIT FOR CONVERSION COMPLETED , DONE
WEND
IB_ADC=(ADRESH<<8)+ ADRESL ' ADC RESULT 12 BIT
ADCON0=%00000000 ' TURN OFF,

RETURN

ACQ_POT: 'ACQUIRE POT ANALOG VOLTAGE ....................................

'READ ANALOG 4 POT
ADCON0=%00010000 ' SELECT AN0, VPOT
ADCON2=%10100110 ' ACQ TIME AND FOSC SELECTION
ADCON0=%00010001 ' ON, ACCESO
PAUSE 1 ' INPUT RESISTANCE AND CAP FOR DC ACQISISTION
ADCON0=%00010011 ' ON + GO
WHILE ADCON0.1=1 ' WAIT FOR CONVERSION COMPLETED , DONE
WEND
POT_ADC=(ADRESH<<8)+ ADRESL ' ADC RESULT 12 BIT
ADCON0=%00000000 ' TURN OFF,

RETURN

DIS_LCD: '.................... 15 msec ...................................

IF STATE=0 THEN LCDOUT INS, LINE1,"OFF "
IF STATE=1 THEN LCDOUT INS, LINE1,"ON "
IF STATE=2 THEN LCDOUT INS, LINE1,"FLOAT"
iF STATE=3 THEN LCDOUT INS, LINE1,"BULK "
IF U_VOLT=1 THEN LCDOUT LINE1,"LOAD> OFF > UV"
IF LOAD=0 THEN LCDOUT LINE1,"LOAD> OFF "
IF LOAD=1 THEN LCDOUT LINE1,"LOAD> ON "
IF EXTPWR_OK=1 THEN LCDOUT INS,LINE2,"LINE> AVL "
IF EXTPWR_OK=0 THEN LCDOUT INS,LINE2,"LINE> NOT AVL"
IF EX=1 THEN LCDOUT INS,LINE2+14,"EXT_PWR"
IF EX=0 THEN LCDOUT INS,LINE2+14," "
LCDOUT INS, LINE3,DEC VP/1000,".",DEC1 VP/100," ",DEC IP/1000,_
".",DEC2 IP/10," ",DEC2 WP/1000,".",DEC1 WP/100," ", DEC DUTY
LCDOUT INS, LINE4,DEC VB/1000,".",DEC1 VB/100," ",IBSIGN,DEC IB/1000,_
".",DEC2 IB/10, " ",IBSIGN,DEC2 WB/1000,".",DEC1 WB/100," "



RETURN

SERIAL_OUT: ' .................. 25 msec.....................................

DEBUG "VP ",DEC VP/1000,".",DEC1 VP/100," IP ",DEC IP/1000,_
".",DEC2 IP/10, " WP ", DEC WP/1000,".",DEC1 WP/100,_
" DC ", DEC DUTY, " VB ",DEC VB/1000,".",DEC1 VB/100,_
" IB ",IBSIGN,DEC IB/1000,".",DEC2 IB/10, " WB ",IBSIGN,_
DEC WB/1000,".",DEC1 WB/100," M ",DEC MODE," S ",DEC STATE,13,10

RETURN


MPPT: '................................................. ..............

' PANEL DATA CHANGE

IF WP>WP_OLD THEN ' POWER INCREASES
DP=1
ELSE
IF WP<WP_OLD THEN ' POWER DECREASES
DP=0
ENDIF
ENDIF

if wp=WP_OLD THEN RETURN

IF VP>VP_OLD THEN ' VOLTAGE INCREASES
DV=1
ELSE
IF VP<VP_OLD THEN ' VOLTAGE DECREASES
DV=0
ENDIF
ENDIF

' HILL CLIMBING.... FOR MPP SEARCH

' CLIMBING FROM LEFT

IF DV=1 AND DP=1 THEN
DUTY=DUTY-DUTY_S ' DECREASE LOAD TO INCREASE P_VOLTAGE
ENDIF

'DESCEND TO THE RIGHT

IF DV=1 AND DP=0 THEN
DUTY=DUTY+DUTY_S ' INCREASE LOAD TO REDUCE P_VOLTAGE
ENDIF

' CLIMBING FROM RIGHT

IF DV=0 AND DP=1 THEN
DUTY=DUTY+DUTY_S ' INCREASE LOAD TO REDUCE P_VOLTAGE
ENDIF

' DESCEND TO THE LEFT

IF DV=0 AND DP=0 THEN
DUTY=DUTY-DUTY_S ' DECREASE LOAD TO INCREASE P_VOLTAGE
ENDIF

GOSUB SET_PWM

WP_OLD=WP
VP_OLD=VP

RETURN


SET_PWM: '................................................. ..................

IF DUTY >= 254 THEN ' MAX DUTY FOR IR2104
DUTY=254
ENDIF

if DUTY <=150 THEN ' CONSIDERING ABOUT 12 VDC OUTPUT..
DUTY=150
ENDIF

HPWM 1,DUTY,75000 ' 75 KHz CLOCK FREQUENCY @ DUTY....

RETURN


GET_PANEL_DATA: ' .................................................. ......

' GET PANEL DATA

FOR I=1 TO AVG ' VP AND IP FILTERING LOOP
GOSUB ACQ_PV ' ACQ_PV TAKES ABOUT 2.3 mSEC...
IPT=IPT+IP_ADC
VPT=VPT+VP_ADC
NEXT I

IPF_ADC=IPT/AVG
VPF_ADC=VPT/AVG
IPT=0 : VPT=0
VP=(VPF_ADC*7200)/1000 ' MILLIVOLTS

IF IPF_ADC>2052 THEN ' ACS_712 BIAS IS ABOUT 2.5 VDC... 12 BIT adc
IPF_ADC=IPF_ADC-2052
ELSE
IF IPF_ADC =< 2052 THEN
IPF_ADC=2052-IPF_ADC
ENDIF
ENDIF
IP=(IPF_ADC*6790)/1000 ' MILLIAMPS
WP=(IP*VP)/1000 ' MILLIWATT
RETURN


GET_BATTERY_DATA: '................................................. .......

' GET BATTERY DATA
FOR I=1 TO AVG_B
GOSUB ACQ_BATT ' ACQ_BATT TAKES ABOUT 2.3 mSEC
VBT=VBT+VB_ADC
IBT=IBT+IB_ADC
NEXT I

VBF_ADC=VBT/AVG_B
IBF_ADC=IBT/AVG_B
IBT=0 :VBT=0
IF IBF_ADC>2053 THEN
IBF_ADC=IBF_ADC-2053
IBSIGN="-"
ELSE
IF IBF_ADC=<2053 THEN
IBF_ADC=2053-IBF_ADC
IBSIGN="+"
ENDIF
ENDIF
VB=(VBF_ADC*7000)/1000 ' MILLIVOLTS
IB=(IBF_ADC*6790)/1000 ' MILLIAMPS
WB=(IB*VB)/1000 ' MILLIWATT

RETURN

Demon
- 30th April 2014, 14:46
... there is a small problem relevant to the status selection that appears when the sky is cloudy (but not always): it jumps between status 0 and status 3...

Are you sure it isn't a debounce issue?

Maybe add 1 second PAUSE to rule that out?

Robert

iw2fvo
- 30th April 2014, 21:29
Thanks Robert,
I will put a delay ( 1 sec or more ) when changing status.
Need to wait for next cloudy days to check if OK .
Do you see any other area om the program that could be improved ?
Ambrogio

Demon
- 30th April 2014, 22:47
Honestly I have trouble concentrating so it's kinda easy for me to lose track of logic.

I try to help with the simple things.

Robert

Edit: your program is huge, have you considered breaking it down?

I'd make a copy, reduce all the subroutines to only display a status on LCD, then add logic one section at a time.

iw2fvo
- 1st May 2014, 10:41
Robert,
I am attaching the schematics digram for the charger and two captures.
I am sorry : it is hand drawn. I am not an electronics expert nor a software man !
This morning I have activated the delay as suggested, I am waiting to see the results in the next days.
The whole device works well and the MPPT is tracked well too.
Thanks for all.
regards,
Ambrogio

Demon
- 1st May 2014, 14:42
Wow!

Wish I could contribute something.

Now you're making me think of adding a solar panel to my alarm project.

Robert

iw2fvo
- 1st May 2014, 15:56
Robert,
i woluld like to attach a photo of the LCD and a screen shot of the output.
I am not able to attach any .jpeg : any direction for me ?
Thanks
Ambrogio

Demon
- 1st May 2014, 16:30
Test attachment using picture icon on posting toolbar:

...

iw2fvo
- 1st May 2014, 17:07
Robert,
they are here.
Ambrogio

Demon
- 1st May 2014, 19:17
Thanks Robert,
I will put a delay ( 1 sec or more ) when changing status.
...

I'd put it here temporarily:


IF MODE=3 THEN
LCDOUT INS, CLR
LCDOUT INS, LINE1, " DC STEP TEST "
ENDIF

PAUSE 1000 ' Test if problem is debounce issue

' Not necessary during test ... WHILE PB_1=0: WEND

ENDIF

Robert

Demon
- 1st May 2014, 19:22
... there is a small problem relevant to the status selection that appears when the sky is cloudy (but not always): it jumps between status 0 and status 3...

Oh great, I misread. I thought it was jumping between MODEs. Aaargh, sorry.

Gonna look through logic later. I have errands to do during the day.

Robert

iw2fvo
- 1st May 2014, 21:24
Robert,
i think it ias a problem related to panel power wp, panel voltage vp and duty cycle when switching among the various status...
It needs to find out the proper values that controls the switching...
tnks,
Ambrogio

Demon
- 2nd May 2014, 18:37
Robert,
i think it ias a problem related to panel power wp, panel voltage vp and duty cycle when switching among the various status...
It needs to find out the proper values that controls the switching...
tnks,
Ambrogio

Yup. I can't see bad GOSUB structure, nothing that stands out anyways.

The STATE can evolve from 0 to 3 in a single pass of that SELECT CASE. I can only assume the readings from your hardware makes it jump unexpectedly.

Are you able to debug in real time and step thru your code?

It's about the only way I can think of the visualize what is going on. I see you dump a lot of information but I'm unable to follow that manually through your logic.

I prefer to dump like this:

MAIN --------------------------------------------------
STEP 1, list of variables.
SUBROUTINE XYZ ----------------------------------------
STEP 1, list of variables.
STEP 2, list of variables.
SUBROUTINE ABC ----------------------------------------
STEP 1, list of variables.
...etc...

I find it easier to follow in the code this way. I place the STEPS in relevant places, like before & after IFs, etc.

Robert

iw2fvo
- 3rd May 2014, 12:53
Robert ,
I agree with you.
The point is the data input to the state machine.
In particular sun condition it plays back and forth between the two status because of the data input.
I have to change / find out some different duty / panel power / panel voltage to be used to control the staus and avoid oscillations.
It does not happen frequently: just in some particular case and in a cloudy day.
The delay applied to the program as stated reduce the oscillation frequency.
Anyway it is not a real problem since it happens when the charging current is already low because of the low sun condition.
Thanks for all.
regards,
Ambrogio

EarlyBird2
- 4th May 2014, 09:05
A very impressive piece of code! I have been programing for over 40 years and never seen a novice produce such elegant code before.

The issue is in your select case section. If case =0 then within this code case is set to 1 then case 1 code is run and again Case is set to 2 then Case is set to 3. Here is the main issue Case 3 is bulk charging because the battery is low as you would want but if a cloud comes over then Panel Voltage is less than Battery Voltage and Case is set to 0. Once the cloud goes then the Case will again revert to 3 bulk charge until the next cloud. Obviously depending on how dark the cloud is there is a possibility that the Panel Voltage can be above Battery Voltage changing to below Battery Voltage and then above as the cloud passes.

This explains what is happening. My only question is why are you switching the Panel on and off?

All my solar panels are permanently connected to the battery regulator. The panels do have a diode in line.

If you do not switch the panels on and off you can take out all of the switching code and solve the problem.

theFob
- 4th May 2014, 12:14
Hi iw,
I'm impressed of your work.
I played once with mppt converters and i know how crazy is.
the attachments show dc simulation of 21V@8A photovoltaic. May be will be useful for you. I have dozens simulations of buck, boost and sepic converters, but i didn't finish the work because the 'client' give up. Now i have 3kg prototype but no panel to play :(
Allow me to ask you what mppt algorithm you use ?
Some of them are:
* perturb and observe (P&O - sign dP)
* incremental conductance (dP/dV=0)
* constant voltage or current (CV,CI)

May be i'm too lazy to read all your code and find out, sorry.

I suggest reading of this:

Comparative Study of
Maximum Power Point
Tracking Algorithms
D. P. Hohm and M. E. Ropp*,y
Electrical Engineering Department, South Dakota State University, Brookings, SD 5700-2220, USA

It helps me a lot, amazing study.

iw2fvo
- 4th May 2014, 17:37
Thanks EarlyBird2,
Yes , the system works as you described.
The point is that sometime it jumps or oscillates around OFF state. I think your suggestion to do not turn off the converter ( see EN_DCDC ) could solve the problem.
I will try it durnig next week. I will post the results.
Thanks again
Regards,
Ambrogio

iw2fvo
- 4th May 2014, 17:49
Thanks TheFob,
I think that the trick to get a stable MPP tracking is that the "Perturbation" must generate a delta power that is greater than the " noise Power ".
If the VP and IP acquisistion by the PIC ADC has some noise, then the power has a noise too. The perturbation created by " DUTY_step" must generate a delta power response bigger than the noise power.
If the hardware is good then and the noise low we could use a duty_step=1 . If you have a sensible noise you could increase it to 2, 3 , 4 ...
The piece of program is this:

MPPT: '................................................. ..............

' PANEL DATA CHANGE

IF WP>WP_OLD THEN ' POWER INCREASES
DP=1
ELSE
IF WP<WP_OLD THEN ' POWER DECREASES
DP=0
ENDIF
ENDIF

if wp=WP_OLD THEN RETURN

IF VP>VP_OLD THEN ' VOLTAGE INCREASES
DV=1
ELSE
IF VP<VP_OLD THEN ' VOLTAGE DECREASES
DV=0
ENDIF
ENDIF

' HILL CLIMBING.... FOR MPP SEARCH

' CLIMBING FROM LEFT

IF DV=1 AND DP=1 THEN
DUTY=DUTY-DUTY_S ' DECREASE LOAD TO INCREASE P_VOLTAGE
ENDIF

'DESCEND TO THE RIGHT

IF DV=1 AND DP=0 THEN
DUTY=DUTY+DUTY_S ' INCREASE LOAD TO REDUCE P_VOLTAGE
ENDIF

' CLIMBING FROM RIGHT

IF DV=0 AND DP=1 THEN
DUTY=DUTY+DUTY_S ' INCREASE LOAD TO REDUCE P_VOLTAGE
ENDIF

' DESCEND TO THE LEFT

IF DV=0 AND DP=0 THEN
DUTY=DUTY-DUTY_S ' DECREASE LOAD TO INCREASE P_VOLTAGE
ENDIF

GOSUB SET_PWM

WP_OLD=WP
VP_OLD=VP

RETURN

Thanks for the interest,
Regards,
Ambrogio
IW2FVO
North Italy

theFob
- 4th May 2014, 23:34
Thanks iw,
I suppose the first chart explains your code. I found it in the net. But i'm still out of focus.
Why is the measurement of dV? As is shown on the simulation, the voltage of the panel
is almost constant up to 90% of available current. So there is "constant voltage" and "constant current" methods. The voltage remain the same even at night, of course with almost no load. The photons flow become electrons flow, i.e. available current. So the panel is kind of current generator.
And of course, measured dV will be small and inaccurate, may be the noise is from there.
I used hardware circuit similar as algorithm in second chart. So i'm interested of your work. I will try to find my circuits, but unfortunately they are on almost dead HDD ...

Regards

theFob
- 5th May 2014, 09:34
ok, i answered myself. I did simulation again.
The voltage have little change indeed and can be used to determine the direction of duty. But this can be done without this too.
Iw, if i find some time i will make Proteus simulation with your code.
Will be nice to check some other algorithms before the fire of soldering iron :)

73407341

PS I don't know how to resize the images, sorry

iw2fvo
- 5th May 2014, 22:43
Thanks theFob,
I am interested in seeing the simulation of my program when you have time .
The mpp_tracking code I am using works well . My program allow to find out the MPP manually using the potentiometer. It also allows to scan the duty cycle to search the MPP : this is automatic.
The normal mode of the program continuously tracks the MPP. There is a very minor difference among them.
Thanks again,
regards,
Ambrogio
IW2FVO
North Italy

theFob
- 6th May 2014, 07:37
Hi iw,
I'll be glad to do this :) Had no such fun from long time.
I need the nominal voltage and maximum current values of the panel or just the model.
I noticed the lack of general decoupling diode in your circuit. Is needed for reverse current protection. May be the panel have such internally.
Also a small input filter will be good idea, because the input current of the buck is trapezoidal and is very stressful for the panel.
So the preferred converters are boost (when is possible) or sepic. The input currents there are triangle in continuous mode.
I allowed myself to check your CQ on the net. How far you've come with SG3525 inverter ? I guess it will work with this converter .... ?

Regards

iw2fvo
- 6th May 2014, 08:26
TheFob:
panel data are:
max power 50 w
open circuit volt: 21.6 Vdc
short circuit current : 3.04 A
Max pp volt: 17.6 Vdc
Max pp current : 2.84 A
There is a reverse protection diode ( see D1 on buck converter schematics ).
There is 220 uF at the buck input . Could it be too small ?
The panel keeps the SLA battery charged and so I do not have any inverter to produce line alternate power. I just need 12 VDC nominal.
CQ: >> I have a fully working homemade SDR rx tx for the HF. I have to re_install the antenna that went out completely during the last windy thunderstorm.
I plan to do that at the beginning of the next month.
Thanks.
73, IW2FVO.
Ambrogio

theFob
- 6th May 2014, 10:17
No, you have no panel protection diode. there must be a diode right after the panel, before the point C. It is essential.
If the sun goes down and you have no load at the moment, the input capacitor will return current which can destroy the junctions in the panel.
Diode D1 protect only the buck from the battery. Also the input capacitor is good to be bigger. At least 2200uF in my opinion.
Plus ~1uH inductance after the diode - will help a lot against noise. Few turns on the fly.
SDR sounds interesting, it is something new for me.

iw2fvo
- 6th May 2014, 12:54
Thanks.
I have learn now the need for a panel diode. I will move D1 to the panel input. I will also install a 2200 uF low ESR at panel input and after the diode.
The RF choke is a good idea too.
Ambrogio

EarlyBird2
- 7th May 2014, 09:00
Thanks Ambrogio for this very interesting and informative thread.

When I first read this thread I wondered why make your own Solar Regulator when I buy them for 20€ but obviously now I realise the models I use are not MPPT. The MPPT version costs 250€ so making your own is not only an interesting project but saves lots of cash.

I also realise that your design allows for Solar or Mains power which makes it even more interesting but I could not work out how the program/micro does the switching between the two power sources.

iw2fvo
- 7th May 2014, 17:17
Steve,
the program controls both the load disconnection and the external power .
You can set the voltages at your choice.
Here is the piece of code. The whole code is not optimized : I am not a software expert as I told at the beginning. There are a lot of comments on the program.
I think that a software guy could improve the code in a significant way. BTW it is still working at my home.
regards,
Ambrogio
iw2fvo

' LOW VOLTAGE PROTECTION ...and load control..................................

IF ( VB<11800 ) THEN ' BATT LOWER THAN 11.8 Vdc
U_VOLT=1 ' SET UNDER_VOLTAGE FLAG
LOW LD_EN ' DISABLE LOAD
LOAD=0
U_FLG=1
ELSE
IF ( VB>12600 ) THEN ' IF VBATT MORE THAN 12.6 Vdc
U_VOLT=0 ' RESET UNDER_VOLTAGE FLAG
IF U_FLG=1 THEN
HIGH LD_EN ' ENABLE LOAD
LOAD=1
U_FLG=0
ENDIF
ENDIF
ENDIF

IF (U_VOLT=1) AND (EXTPWR_OK=1) THEN
LOW EXT_PWR_RLY ' ACTIVATE EXT POWER RELAY
EX=1
ELSE
IF U_VOLT=0 THEN
HIGH EXT_PWR_RLY ' RELASE EXT POWER RELAY
EX=0
ENDIF
ENDIF

IF U_VOLT=0 THEN
IF PB_3=0 THEN
if LOAD=0 THEN
LOAD=1
ELSE
LOAD=0
ENDIF
IF LOAD=0 THEN
LOW LD_EN
ENDIF
IF LOAD=1 THEN
HIGH LD_EN
ENDIF
WHILE PB_3=0 : WEND
ENDIF
ENDIF

EarlyBird2
- 8th May 2014, 08:50
My rules for programming in order of importance.

1 It works
2 It is easy to follow
3 It is easy to modify

My definition of a good program is

It works

Which yours does except for one minor detail. So the question is whether to rewrite the program or not to solve this cloud issue? Personally I would rewrite the program because I would learn by doing so. I only wish I had the hardware.

iw2fvo
- 8th May 2014, 15:39
As far as the cloud issue I wikll modify the program to improve stability.
I will do the modification to the code tomorrow and I will then test it for some days expecially when cloudy.
If ok I will post the mod later on. The mod will involve the ON STATE code only.
Thanks
Ambrogio
IW2FVO
North Italy

iw2fvo
- 13th May 2014, 17:47
I am posting the picbasic program B_4523 mainly modified to avoid oscillation among the ON state in particulary cloud sky condition.
I did minor changes as reported in the .txt program headlines.
Thanks to all of you for the suggestions provided.
Regards,
Ambrogio
IW2FVO
North Italy

iw2fvo
- 2nd June 2014, 20:50
Good day,

I connected my charger to the PV and I left it for about 10 days having good results in all the sun conditions available in that period of time.
The final code together with the photo of the prototype implementation is attached to the present mail .
Regards,
Ambrogio
IW2FVO
North Italy

Demon
- 2nd June 2014, 21:21
Congratulations!

Robert

iw2fvo
- 15th October 2014, 08:19
Hi to all of you in the forum.
My MPPT charger is working since last June with no problem.
In this period I have no possibility to go on with my electronics hobbies.
I would like to know if someone has reproduced this project and has introduce some improvements.
Just to know !
Thanks
Regards,
Ambrogio

harryweb
- 2nd December 2014, 21:08
HI IW2FVO,
I plan to use your schematics and parts of your code for my project (just ordered 2x100w PV, now need battery)
I would like to know what do you mean (schematics) replace D1 with ideal diode ?
It could take some times to make my project because of the season.
Congratulation for your work
Regards - 73'
F1SLU
Herve

iw2fvo
- 3rd December 2014, 07:21
Hi Herve,
D1 introduce a voltage drop that impact on the whole system efficiency. This loss can be calculated an depends on current and diode performance in terms od forward voltage drop.
I used an ideal diode circuit to replace D1 during my last test at the bench only. I have not introduce it on my final circuit because of the space on the board.
You could find out a lot of these circuits here :
https://www.google.it/search?q=ideal+diode+solar&espv=2&biw=1680&bih=925&tbm=isch&tbo=u&source=univ&sa=X&ei=orR-VJOqMJLPaMqdgtgL&ved=0CCAQsAQ
You can also google " ideal diode solar " for additional info.
I do suggest to calculate the power saved and evaluate if really worth. It is up to you !
I will really start without it.
Best regards,
iw2fvo, Ambrogio

harryweb
- 25th March 2016, 16:31
Hi Ambrogio,

I just finished to install my solar panels 2 weeks ago. (Yes... I'm a turtle...)
As I doesn't make any charger I bought a cheap MPPT solar charger from Ebay (china) and it's a fake MPPT (just PWM).
So I've made the PCB for my real MPPT solar charger. Using most same parts as your schematics (just using other equivalent parts and not ACS712 but a maxim current sensor)
I have to modify your source program. :-)
I just would like to ask you, if you're happy with your charger/program, or did you make any changes ?
I have 220W solar panels.
I will give some news about the MPPT charger asap, I just received 5 PCB from... china today.... Have to solder now.

regards and 73
F1SLU Hervé
Best regards

iw2fvo
- 27th March 2016, 08:24
HI Herve,
It is still working well and no additional modification was introduced to the program.
I introduced an IDEAL DIODE found on the Ebay in place of the diode: it is OK.
I think the state machine portion of the program could be improved sometime...
My system has no PCB: do you have a spare one for me ?
All the best,
73, Ambrogio

harryweb
- 27th March 2016, 16:54
Hi Ambrogio,

My schematic is a bit different, so my PCB too ! As I have 220W panels some choice have to be done, and I also want to use serial to log on my computer. I think to make a python script to do that. I will upload picture of the schematics and PCB here but next week because I have it at work.
OK for the ideal diode. May be I will buy some of them ...
73, Hervé

iw2fvo
- 27th March 2016, 17:22
Thanks,
I will like to see it .
73, Ambrogio

hisham545
- 22nd April 2016, 15:55
hi
help
the code dosenot work on pic18f4520 nothing is appear on lcd only pwm is working.
when i change lcd cofig in code and wiring lcd working and only see this on lcd :

Ambrogio 06/04/2014
PV PIC18F4523

then i added the line3 and line4 to the
Ambrogio 06/04/2014
PV PIC18F4523

then i see only zeros,adc is not working


i have only pic 18f4550,pic18f4520,pic16f877a.