re; any help mppt

Thread Starter

olusola

Joined May 21, 2007
74
HI,
attached is my circuit diagram, and my codes below.
i am working on a maximum powerpoint tracker for solar (PV) modules.
I want to use a MOSFET - being a voltage controlled device to control the resistance the pv module 'sees' as its load, by controlling the voltage to its gates.
I am using the FDA79N15 mosfet and i am using the ATmega16 with 10bit DAC AD7533(not labelled in diagram)
with a 5V reference.

Right now , i am not getting any resonable tracking and also the current through the circuit is very small.

Any ideas? is it the DAC? is the code ok (pretty much my first code in assembler ); is it the shunt resistor ? or the mosfet?

thanks for your advice in advance

olu

code
****************************************************

/*
--------------------------------------------------
Maximum Power Point Tracking
--------------------------------------------------
Olusola Osinowo
Ver 1.0
2007
--------------------------------------------------
ATmega16 Microcontroller
*/

//===========================================================================================
// Port and variable bit definitins:
;
; PortA:
; Bit 0 (ADC0): Voltage Input positive
; Bit 1 (ADC1): Current Input positive
;
; PortB:
; Bit0: Output to DAC LSB
; Bit1: Output to DAC
; Bit2: Output to DAC
; Bit3: Output to DAC
; Bit4: Output to DAC
; Bit5: Output to DAC
; Bit6: Output to DAC
; Bit7: Output to DAC
;
; PortD:
; Bit0: Output to DAC
; Bit1: Output to DAC MSB
;
;
; Move_Status:
; Bit0: Right (increasing Voltage) --> low; left (decreasing voltage) --> high

//===========================================================================================



// Inclued ATmega 16 definition
.include "m16def.inc"

// Variable definitions


// Outputs
// --> Power Output only

// Internal Calculation


.def Mul_H = r1; --> Multiplier MSB
.def Mul_L = r0; --> Multiplier LSB
.def Power_Old_H = r2;
.def Power_Old_M = r3
.def Power_Old_L = r4
.def Power_New_H = r5
.def Power_New_M = r6
.def Power_New_L = r7

.def Move_Status = r17
.def Voltage_H = r19
.def Voltage_L = r20
.def Current_H = r21
.def Current_L = r22
.def Temp = r23
.def DAC_out_H = r24
.def DAC_out_L = r25


//-----------------------------------------------------------------------------------------
// Interrupt definition
// Reset
.org $000 jmp Main;
// Interupt Timer 1
.org $00C jmp MPPT;
// -----------------------------------------------------------------------------------------


// Main function:
Main:

cli; //disabling interupts

// Clear Inputs

clr Voltage_H;
clr Voltage_L;
clr Current_H;
clr Current_L;
clr Power_New_H;
clr Power_New_M;
clr Power_New_L;
clr Power_Old_H;
clr Power_Old_M;
clr Power_Old_L;
clr Mul_H;
clr Mul_L;
clr Temp;
clr DAC_out_H;
clr DAC_out_L;
clr Move_Status;


// Initial Stack pointer
ldi Temp, LOW(RAMEND);
out SPL, Temp;
ldi Temp, HIGH(RAMEND);
out SPH, Temp;


// Initialise Timer 1
ldi Temp, 0b00010000;
out OCR1AH, Temp;
ldi Temp, 0b00000000;
out OCR1AL, Temp;
ldi Temp, 0b00000001;
out TCCR1B, Temp;
ldi Temp, 0b00010000;
out TIMSK, Temp;


// Initialise AD Converter
sbi ADCSRA, 7; set ADEN - enable AD converter
cbi ADCSRA, 2; set ADC clock prescaler
sbi ADCSRA, 1; set ADC clock prescaler
cbi ADCSRA, 0; set ADC clock prescaler

// Set input-output directions
ldi Temp, 0b00000000;
out DDRA, Temp; Port A Input
out PORTA, Temp;

ldi Temp, 0b11111111;
out DDRB, Temp; Port B Output

ldi Temp, 0b00000011;
out DDRD, Temp; Port D Output

// Enable Interupts
sei;

//***** First Conversion - Discard)
// Measure Voltage
ldi Temp, (1<<REFS1)|(1<<REFS0)|(0<<MUX0); set voltage meausurement channel and internal referece
out ADMUX, Temp;
sbi ADCSRA, ADSC; start A-D conversion

ADC_wait_K:; wait until A-D conversion finished
sbis ADCSRA, ADIF;
rjmp ADC_wait_K;

in Voltage_L, ADCL; Store Converted Low Bit value
in Voltage_H, ADCH; Store Converted High Bit value
//sbi ADCSRA, ADIF;





//=============================================================================
// Timer 1 interrupt routinte - MPPT
MPPT:

// Reset Timer 1 clock counter
clr Temp;
out TCNT1H, Temp;
out TCNT1L, Temp;


// Measure Voltage
ldi Temp, (1<<REFS1)|(1<<REFS0)|(0<<MUX0); set voltage meausurement channel and internal referece
out ADMUX, Temp;
sbi ADCSRA, ADSC; start A-D conversion

ADC_wait_V:; wait until A-D conversion finished
sbis ADCSRA, ADIF;
rjmp ADC_wait_V;

in Voltage_L, ADCL; Store Converted Low Bit value
in Voltage_H, ADCH; Store Converted High Bit value
//sbi ADCSRA, ADIF;

// Measure Current
ldi Temp, (1<<REFS1)|(1<<REFS0)|(1<<MUX0); set voltage meausurement channel and internal referece
out ADMUX, Temp;
sbi ADCSRA, ADSC; start A-D conversion

ADC_wait_C:; wait until A-D conversion finished
sbis ADCSRA, ADIF;
rjmp ADC_wait_C;

in Current_L, ADCL; Store Converted Low Bit value
in Current_H, ADCH; Store Converted High Bit value
//sbi ADCSRA, ADIF;

// Calculate Power Performing 10bit x 10bit = 24bit multiplication
mul Voltage_H, Current_H; AH*BH
mov Power_New_H, Mul_L;
mul Voltage_L, Current_L; AL*BL
mov Power_New_M, Mul_H;
mov Power_New_L, Mul_L;
mul Voltage_H, Current_L; AH*BL
add Power_New_H, Mul_H;
add Power_New_M, Mul_L;
mul Current_H, Voltage_L; BH*AL
add Power_New_H, Mul_H;
add Power_New_M, Mul_L;


// Control Output - Perturb Algorithm

cp Power_New_H, Power_Old_H;
breq Equal_H;
brlo Lower;
rjmp Higher;

Equal_H:
cp Power_New_M, Power_Old_M;
breq Equal_M;
brlo Lower;
rjmp Higher;

Equal_M:
cp Power_New_L, Power_Old_L;
breq Equal_L;
brlo Lower;
rjmp Higher;

Lower:; move Voltage in oposite direction
sbrc Move_Status, 0;
rjmp Lower_Increase;
rjmp Lower_Decrease;

Lower_Decrease:;
sbr Move_Status, 0;
dec DAC_out_L;
cpi DAC_out_L, 255;
brne Finish;
dec DAC_out_H;
rjmp Finish;

Lower_Increase:;
cbr Move_Status, 0;
inc DAC_out_L;
brcc Finish;
inc DAC_out_H;
rjmp Finish;

Higher:; move Voltage same direction as before
sbrc Move_Status, 0
rjmp Higher_Decrease;
rjmp Higher_Increase;

Higher_Decrease:;
dec DAC_out_L;
cpi DAC_out_L, 255;
brne Finish;
dec DAC_out_H;
rjmp Finish;

Higher_Increase:;
inc DAC_out_L;
brcc Finish;
inc DAC_out_H;
rjmp Finish;

Equal_L:; equal value --> do nothing


Finish:; set outputs

out PORTB, DAC_out_L;
out PORTD, DAC_out_H;


// Set New power to old power
mov Power_Old_H, Power_New_H;
mov Power_Old_M, Power_New_M;
mov Power_Old_L, Power_New_L;

// return from interrupt
reti;
 

Attachments

hgmjr

Joined Jan 28, 2005
9,029
I withdraw the question.

Sorry, my bad. I mixed up the DAC and the ADC. I see you are using the ADC in the ATMEGA16 afterall.

hgmjr
 

Thread Starter

olusola

Joined May 21, 2007
74
yes i am using avrstudio4 for software development.
i have done some c programming.
yes i am using the ADC in the ATMega16, while i have a DAC AD7533 also to connect to the mosfet.
thanks
 

hgmjr

Joined Jan 28, 2005
9,029
Are you aware that there is a free C-compiler for the AVR microcontroller series?

It is called WINAVR.

hgmjr
 

hgmjr

Joined Jan 28, 2005
9,029
HI,
...........

Right now , i am not getting any resonable tracking and also the current through the circuit is very small.

.....

olu
Can you expand on this description of your problem?

Have you tested the DAC to make sure that it is producing the output voltage change that is both the range you need as well as the range you expect to obtain based on the digital value you are inputting from PORTB of the microcontroller?

hgmjr
 

hgmjr

Joined Jan 28, 2005
9,029
I see a possible problem with the hookup of the two opamps you are using with the DAC.

I think you may want to disconnect pin 16 of the DAC from pin 1 of the second opamp and reconnect pin 16 to pin 7 of the first opamp stage.

The way it is hooked up right now you have two inversion in the feedback path which means you will end up with positive feedback when what you need in negative feedback.

hgmjr
 

hgmjr

Joined Jan 28, 2005
9,029
I'm not sure what you were trying to accomplish with the use of two opamps with the DAC. Can you explain what you were attempting to do?

hgmjr
 

hgmjr

Joined Jan 28, 2005
9,029
I was successful in cutting and pasting your assembly language program into AVRSTUDIO4 and it compiled with no errors. That's a milestone.

hgmjr
 

Thread Starter

olusola

Joined May 21, 2007
74
DAC and Op Amps
on testing, i noticed the voltage from the first op-amp being inveted, so i'm using the 2nd op-amp to invert it .

I tested the DAC, on its own and it worked, but i am trying to test it now with the microcontroller .

Reasonable tracking:
well on connceting the system, i can see the value varying slightly, but i am also running a parallel system with a fixed load(resistance), and there seems to be lots of differences.

i also connected a multimeter into the circuit to check the current in the circuit, and it is quite low.

On the C-compilier, are u recommending doing this in C?

thanks

Olu
 

hgmjr

Joined Jan 28, 2005
9,029
Rich (BB code):
// Initialise Timer 1
 
      ldi Temp, 0b00010000;
      out OCR1AH, Temp;
 
      ldi Temp, 0b00000000;
      out OCR1AL, Temp;
 
 
     ldi Temp, 0b00000001; // 0b00001001 (0x09) ????
     out TCCR1B, Temp;
 
     ldi Temp, 0b00010000;
     out TIMSK, Temp;
Since you have initialized OCR1AH, OCR1AL, and placed you interrupt service routine at the COMPA interrupt service vector location, I am assuming that you are planning to use the reload timer1 on match with COMPARE A. If that is the case, then it appears that you have selected waveform generator mode 0 when I think you might need to select waveform generator mode 4 (see red text in the code inset above).

Have I missed something?

hgmjr
 

Thread Starter

olusola

Joined May 21, 2007
74
oh i must say ,
there is a mistake on the 2nd op-amp after the DAC. its a 1K resistor between legs 4 and 1 and not a capacitor .
thanks

olu
 

hgmjr

Joined Jan 28, 2005
9,029
The choice of coding language is strictly up to you. I just wanted to make sure that you were aware that WINAVR is out there for you to use.

There are advantages and disadvantages to either choice. The one major advantage of C is that is much easier for another programmer to determine what your code is doing.

For now, I would stick with your assembly language program and if you have the time and the inclination you can always port the program over to C at a later date.

hgmjr
 

Thread Starter

olusola

Joined May 21, 2007
74
ah, well please can you help me understand this better?
I am quite new to this, and just followed an example to initialise the timer, as i really did not understand the different timer operations. i am trying to understand it now though.

thanks




Rich (BB code):
// Initialise Timer 1
 
      ldi Temp, 0b00010000;
      out OCR1AH, Temp;
 
      ldi Temp, 0b00000000;
      out OCR1AL, Temp;
 
 
     ldi Temp, 0b00000001; // 0b00001001 (0x09) ????
     out TCCR1B, Temp;
 
     ldi Temp, 0b00010000;
     out TIMSK, Temp;
Since you have initialized OCR1AH, OCR1AL, and placed you interrupt service routine at the COMPA interrupt service vector location, I am assuming that you are planning to use the reload timer1 on match with COMPARE A. If that is the case, then it appears that you have selected waveform generator mode 0 when I think you might need to select waveform generator mode 4 (see red text in the code inset above).

Have I missed something?

hgmjr
 

hgmjr

Joined Jan 28, 2005
9,029
oh i must say ,
there is a mistake on the 2nd op-amp after the DAC. its a 1K resistor between legs 4 and 1 and not a capacitor .
thanks

olu
Did you mean to say legs 2 and 1? Leg 4 is the negative power pin and your schematic shows no capacitor attached to leg 4.

hgmjr
 

Thread Starter

olusola

Joined May 21, 2007
74
do you think i need some rest? cos i think i do . lol.
well yes thanks . oh, thanks so much .
it is btw legs 2 and 1
cheers

olu
 

hgmjr

Joined Jan 28, 2005
9,029
ah, well please can you help me understand this better?
I am quite new to this, and just followed an example to initialise the timer, as i really did not understand the different timer operations. i am trying to understand it now though.

thanks
Sure. I will try to help any way I can.

Timer1 is a very flexible timer and can therefore be configured in numerous ways.

In the standard operating mode (MODE 0), TCNT1H and TCNT1L together make up the 16-bit register that contains the value to be loaded into the timer1 counter with each interrupt. The interrupt occurs at the MAX count of 65,535.

The timer clock frequency is based on the system clock divided by the prescaler which can be set to one of several preset divide-by values.

There is another mode that timer1 can be set to that uses OCR1AH and OCR1AL to set the value that is compared with each value of timer1's counter as it is incremented. Whenever the contents of the timer1 counter is equal to the value in OCR1A then the counter is loaded with zero and the counter begins incrementing from 0 toward the value in OCR1A again.

I recommend you read the ATMEGA16 datasheet as it describes this operation in great detail.

hgmjr
 

Thread Starter

olusola

Joined May 21, 2007
74
ok. thanks. looking at the datasheet.
thanks once again. please if you come up with anything ot help pls let me know. (i'm not that much of a sleeper .. lol) but yea also, so what do you now recommend for the timer?

Olu
 

hgmjr

Joined Jan 28, 2005
9,029
Another thing that I have noticed is that your solarcell is not connected to any ground nor is your mosfet. You will need to connect these to ground to provide a reference and complete the measurement path.

hgmjr
 
Top