27
Low-Frequency Dynamic Impedance Matching for Maximum Power Point Tracking of Photovoltaic Cells Authors: Chris Poniatowski, Elizabeth Scalzetti, Kevin Xu Abstract This paper describes a maximum power point tracking (MPPT) system to extract power with low loss from a MotoMaster Eliminator 15W solar panel. We discuss, in detail, the technical aspects of the system— including our project objectives, solution, design rationale, results, and a discussion of these results. The design begins with a microcontroller that varies the duty cycle of a pulse width modulated (PWM) signal as input to a Buck converter. This variation is based on the characteristics from the solar panel at various points in time. The varying input to the Buck converter allows the solar panel to match the impedance of the load at all times, allowing the system to operate at the maximum power point (MPP) at every point in time. A model sun simulates the rising and setting of the sun throughout a day in ninety-six seconds, which changes the characteristic curves and the MPP of the panel. Introduction Solar panels cannot output power efficiently on their own. The solar panel’s output varies due to changing environmental conditions, such as light and temperature. At any point in time, the maximum power point (MPP) of the system can be reached by adjusting the system’s load resistance to match the panel resistance. Solar cells can be characterized by a current-voltage (IV) curve, which varies depending on the characteristics mentioned above. The MPP is achieved when the product of current and voltage is at a maximum. This can also be displayed by a power-voltage (PV) curve, where the MPP is at the highest point ( dP dV =0 ). To draw the maximum amount of power from the panel, an effective load resistance R = V MPP /I MPP must be connected. This matches the source impedance to the load impedances. The load impedance is controlled by the Buck converter. This system tracks the shifting characteristics of the solar panel and allows the system to always be operating at the MPP. Without this MPPT controller, the solar panel system just operates at point on the PV curve that is not the MPP. This leads to a loss of efficiency.

MPPT Final Report

Embed Size (px)

Citation preview

Page 1: MPPT Final Report

Low-Frequency Dynamic Impedance Matching for Maximum Power Point Tracking of Photovoltaic CellsAuthors: Chris Poniatowski, Elizabeth Scalzetti, Kevin Xu

AbstractThis paper describes a maximum power point tracking (MPPT) system to extract power with low loss from a MotoMaster Eliminator 15W solar panel. We discuss, in detail, the technical aspects of the system—including our project objectives, solution, design rationale, results, and a discussion of these results. The design begins with a microcontroller that varies the duty cycle of a pulse width modulated (PWM) signal as input to a Buck converter. This variation is based on the characteristics from the solar panel at various points in time. The varying input to the Buck converter allows the solar panel to match the impedance of the load at all times, allowing the system to operate at the maximum power point (MPP) at every point in time. A model sun simulates the rising and setting of the sun throughout a day in ninety-six seconds, which changes the characteristic curves and the MPP of the panel.

IntroductionSolar panels cannot output power efficiently on their own. The solar panel’s output varies due to changing environmental conditions, such as light and temperature. At any point in time, the maximum power point (MPP) of the system can be reached by adjusting the system’s load resistance to match the panel resistance. Solar cells can be characterized by a current-voltage (IV) curve, which varies depending on the characteristics mentioned above. The MPP is achieved when the product of current and voltage is at a maximum. This can also be displayed by a power-voltage (PV) curve, where the MPP is at the

highest point (dPdV

=0). To draw the maximum amount of power from the panel, an effective load

resistance R = VMPP/IMPP must be connected. This matches the source impedance to the load impedances. The load impedance is controlled by the Buck converter. This system tracks the shifting characteristics of the solar panel and allows the system to always be operating at the MPP. Without this MPPT controller, the solar panel system just operates at point on the PV curve that is not the MPP. This leads to a loss of efficiency.

A model sun simulates the action of the sun as time passes throughout a day. An AVR microcontroller then measures the voltage and current changes of the solar panel to track power over time. The microcontroller outputs a pulse width modulated (PWM) signal with a varying duty cycle that acts as a switch for a Buck converter. The converter adjusts the current across the load bringing the system to the point of maximum power and maximum efficiency.

Page 2: MPPT Final Report

(a) (b)Figure 1. Solar Panel Characteristics

MethodsMPPT controllers have been created in the past, so the first step that had to be taken for us to create one was to research what main components are typically included in the controller. We discovered that our best option would include a microcontroller, a current monitor, a voltage monitor, and a DC-DC converter. A model sun, solar panel, and load are necessary components to demonstrate the system as well, but would not be a part of the controller itself. Figure 2 shows how the parts fit together, while Figure 3 shows a more detailed version of this system block diagram. Once this was determined, the next step was to look into either acquiring the components or making them ourselves.

Figure 2. System Block Diagram

The solar panel that was used was the MotoMaster Eliminator (15 Watts, 1A), chosen for convenience. The solar panel was readily available in the adjacent lab and there was a model sun to use with it. Another alternative was a much smaller solar panel, which would not produce enough power to create the IV graph we wished to produce. The last alternative was the solar panel in the sub-basement of Link Hall which had a model sun already attached to it. We did not use this last alternative because it was in an inconvenient location and there were no added benefits over the first choice.

The DC-DC converter used was a Buck converter. This converter steps down the voltage of the solar panel to achieve the maximum power. The alternatives are using either a Boost converter or a Buck-Boost converter. A Boost converter steps up the voltage of the solar panel and would result in inefficient

Page 3: MPPT Final Report

use of solar power as well as produce a voltage too high for the load intended for 12V to handle. With a Boost converter, the output voltage would increase and the output current would decrease, resulting in an input impedance greater than the source impedance. This was unacceptable for our purpose. A Buck-Boost converter is able to step up and step down the solar panel voltage, but since it is unnecessarily complicated compared to a simple Buck converter, it was not the best option for our system. A synchronous Buck converter was built from scratch using parts that were in the lab or that were ordered online. A synchronous design was used instead of asynchronous, which involves using two n-channel MOSFETs instead of one, because it is more efficient. The asynchronous design works by having the PWM signal control whether a single MOSFET is on or off. When the signal is high, the MOSFET is on; when the signal is low, the MOSFET is off. This is necessary to control how much the voltage is stepped down. However it also means that the circuit is disconnected often from the load, whenever the MOSFET is off. This is the advantage of using the synchronous model. Since it has two MOSFETs, when one is off, the other is on and vice versa. This allows the load to always be connected to the rest of the circuit which works to increase the efficiency of the system. It is not much more difficult to construct a synchronous Buck converter instead of an asynchronous one, so it was decided that it the synchronous model would be used in our system design.

Figure 3 below shows the complete circuit schematic including the Buck converter, the current monitor, the voltage divider and the microcontroller.

Figure 3. Complete Circuit Schematic

The microcontroller was used to adjust the duty cycle of the input signal to the Buck converter in order to achieve the maximum power. The ATmega328P AVR microcontroller was chosen based on speed, availability, and difficulty to program. One alternative was an HC12 microcontroller. However, it would take longer to learn how to use. Another alternative was using a microcontroller designed specifically for MPPT purposes; however this would not be the best option because it was not beneficial enough to offset the additional complexity of learning to use such a component.

Page 4: MPPT Final Report

To measure voltage and current, the signal into the ADC port of the microcontroller must be between 0 and 5.5V, and less than 40mA. We used a voltage divider with 1.6kΩ and 5.6kΩ resistors so voltage is proportionally decreased such that 0V to 22.5V becomes 0V to 5V, or 2/9 of the actual voltage. The voltage was read by the ADC0 port of the microcontroller. To monitor the current going into the ADC1 port of the microcontroller, an AD8215 current sensor was used. A 0.5Ω shunt resistor was used and the voltage output of the monitor is calculated by the device as Vout = Iin*10 = Iin*Rshunt*20.

Figure 4. P&O Algorithm Diagram

The Perturb and Observe (P&O) algorithm is commonly used in MPPT systems. It works utilizing a guess and check method by making small changes to the duty cycle and comparing the new and previous power values to see which is larger. Based on the previous duty cycle change and the comparison of power readings, the algorithm will determine whether it needs to increase or decrease the duty cycle to get closer to the MPP as shown in Figure 4. See Appendix A-1 for the MPPT microcontroller code.

A lighting system built by Professor Duane Marcy has been set up to model the behavior of the sun. The Model Sun has thirty-one 54W T5 HO bulbs mounted in an arc and controlled by an MC9S12 microcontroller, which treats the bulbs as three sets of eight and one set of seven. It is programmed to receive four numbers from 0 to 255 via serial communication, where the binary value corresponds to the orientation of each bank of lights. For example, 11111111 means all the lights of that bank are on, and 11110000 means only the first four lights are on. Using MATLAB, a program was created to send values to the microcontroller in order to mimic the rising and setting of the sun. The program was set to take 96 seconds for full cycle to complete, allowing for much faster testing and demonstration than using the actual sun. In this paper, full sun means each bank was set to 11111111 (binary 255), half sun corresponds to 10101010 (binary 170) for each bank, and 0001001 (binary 9) was the input for each bank in the low sun case. See Appendices C-1 and C-2 for the MATLAB code used to control the sun. Figure 5 below shows the setup of the sun at full sunlight with the solar panel underneath the arc.

Page 5: MPPT Final Report

Figure 5. Model Sun & Solar Panel Setup

The AVR microcontroller was not able to display results or the values of its variables directly to the computer so indirect methods were used to determine what the values of certain variables were and how they changed with time. An oscilloscope was used to capture the voltage at the solar panel, the voltage at the output of the current monitor—which represented the current at the solar panel—and the PWM signal. In addition to this, the data that the microcontroller read from its ADC ports was exported to MATLAB via an FTDI board and a UART connection. The receive pin of the FTDI was connected to the transmit pin of the microcontroller and the FTDI was connected to a laptop via USB. The USB was registered in MATLAB as a serial port and the baud rate of that port was set so it matched that of the microcontroller transmission. The data was then used to plot the power, voltage, current and PV curve in real time. See Appendices B-1 and B-2 for the code used. The values MATLAB received were not the actual values of the voltage and current, but scaled values of them. Appendix B-3 displays the MATLAB program used to determine the scaling factors so the values read in could be converted back to the original data.

At times it was difficult to determine if the system was working correctly or not. A comparison was needed to verify that the results were correct so data was taken to create the PV curves for full, half, and low sun. The data was recorded in Excel and scatter plots were made to find which duty cycle was the correct one to be oscillating around for each of the three amounts of sunlight. Each point is based on the current and voltage values of the solar panel at different duty cycles in increments of 5% starting at 10% and increasing through 90%. See Figure 6 for the results of those tests.

Based on the PV curves obtained for full, half, and low sun, a PWM controller was designed with a duty cycle optimized for half sun. 45% was an average of the duty cycles that corresponded to MPPs so it was chosen as the duty cycle for the PWM controller. The PWM controller is an exact replica of the MPPT controller excluding the changing duty cycle. The P&O algorithm was removed from the microcontroller

Page 6: MPPT Final Report

code for this system and the duty cycle is set to a constant 45%. See Appendix A-2 for the PWM microcontroller code.

ResultsThe PV curves at three levels of sunlight were measured and plotted with the results shown in Figure 6.

Figure 6. Experimental PV Curve of Full Sunlight, Half Sunlight, and Low Sunlight

Based on the results from the above plots, the peak power value for each level of sunlight was used to compare to the level of power at each of those levels of sunlight using the PWM system. The efficiency of the solar panel was derived from these values and is displayed in the figure below.

Figure 7. Efficiency Comparison

At full and low sun, a 13% and 10% increase in power, respectively, are evident in the MPPT system compared to the PWM system. There is no added efficiency in using the MPPT system created over the PWM system created for half sun.

Figures 8, 9, and 10 display the MPPT controller performance. Part (a) of each figure shows the part of the PV curve that the system is oscillating around. It can be seen that they are oscillating around the MPP. The blue circle is the most recent data point and the red points are the previous 19 data points.

Page 7: MPPT Final Report

Part (b) of each figure shows the properly scaled, real time power, voltage, and current data being received from the microcontroller.

(a) (b)Figure 8. Low Sun, MPPT controller

(a) (b)Figure 9. Half Sun, MPPT Controller

(a) (b)

Figure 10. Full Sun, MPPT Controller

Figures 11, 12, and 13 display the PWM controller performance. Part (a) of each figure shows the part of the PV curve that the system is operating at. It can be seen that the operating point does not oscillate and that the power is not necessarily the maxim. The blue circle is the most recent data point and the red points are the previous 19 data points. Part (b) of each figure shows the properly scaled, real time power, voltage, and current data being received from the microcontroller.

Page 8: MPPT Final Report

(a) (b)Figure 11. Low Sun, PWM Controller

(a) (b)Figure 12. Half Sun, PWM Controller

(a) (b)Figure 13. Low Sun, PWM Controller

DiscussionIt can be seen that the maximum power is increasing when the amount of sunlight increases for each of the above situations. For the MPPT system, voltage of the MPP is always around 14V whereas in the PWM system it shifts all over the voltage axis. The maximum power of the PWM system is shown to be lower than that of the MPPT system though they still increase with respect to amount of sunlight. The MPPT system never lets the PV curve stray away from that MPP area that is shown in Figure 1(b).

Since the PWM controller operates at a fixed duty cycle, the optimal PWM controller must operate at a duty cycle that is a statistical average of all the duty cycles that correspond to MPPs across the varying levels of sunlight. This is so that efficiency is not compromised too much for any level of sunlight in the range that was able to be produced. To create an optimized PWM controller to compare our MPPT controller to, a duty cycle of 45% was used which is also the duty cycle that corresponds to the MPP of the system at half sun. That is why there is no added advantage to using the MPPT controller instead of the PWM controller when the sunlight is the equivalent of half sun. As soon as the amount of sunlight

Page 9: MPPT Final Report

drifts from half sun, however, there is an increase in power that the system can draw from the MPPT controller with respect to the PWM controller. The maximum increase in power drawn between the two controllers occurs at maximum sunlight with an extra 13% efficiency. There is no use to testing the added efficiency below low sunlight because both systems are the same in that range. Once the sunlight drops below a certain point the solar panel does not provide enough energy to power the Buck converter. This essentially deactivates and bypasses the controller so there will be no difference in the power outputs between the two systems at that input level. Theoretically, based off the data sheet of the driver used for the Buck converter, once the solar panel voltage drops below 10V the Buck converter will not work. However, in practice, we noticed that it was still working until about 9V. Once the panel voltage drops below that, there will be no efficiency gain between the two controllers.

There are ways to improve our current results. It must be understood that this is still a model system. While the controllers that were built work well, the components used to test the system are only rough models of what would actually be used. The model sun is able to show how the system can track and adjust when the amount of sunlight changes, but it was not tested outside or in a real time environment. Also, when the system is deployed it would use a different load than the one that was used to test the system. A 25Ω power resistor was used which dissipates power whereas a battery, a more typically used load, would have a nearly negligible resistance. It was noticed that as load resistance changes, allowed voltages from the panel change as well. A lower resistance allows for more current to flow, and thus lower voltages, which allow for more of the full PV curve to exist for the system. This will not be a problem in terms of finding the MPP because it will still be physically achievable, whereas shifting to the right can pose a problem in that there is no MPP. A battery was not tested with this system because it was out of scope for our project, which involved drawing power, not storing it. Also, the only 12V battery easily available was a lead-acid battery. The battery needed to be 12V because, for our solar panel, that is where the MPP usually lies. A lead-acid battery, however, is rather complicated to charge. Simply applying a 12.6V will not charge the battery properly and there are stages that need to be followed. It was determined that trying to charge the available battery would be out of scope for this version of the controller.

The algorithm used for the microcontroller could also be modified to maximize efficiency. The model sun was controlled to change its amount of light every three seconds. Unless clouds come and go often and quickly, the sunlight will not usually change that quickly. The microcontroller code could be changed to oscillate less drastically or less often. This would mean that it would sit at the MPP, or closer to it, longer. One issue with decreasing the duty cycle adjustments to less than 4% is that sometimes that is too small of a change to notice an accurate change in power. If there is ever an uncharacteristic jump or decrease in the voltage or current, it will give an inaccurate reading for the power. This could be an issue if, instead of showing as a decrease in power like it should be, it will show as an increase in power and therefore will cause the algorithm to move in the wrong direction. Initially the duty cycle was adjusted in increments of 2% but it was too fine of a scale to give accurate results. It was increased to increments of 4% with successful results. Not having the duty cycle oscillate is out of the question. It is the oscillation that allows it to notice when the sunlight changes and adjust accordingly. It cannot just find the MPP and lock onto it. This does leave some time where the system is actually just slightly off from the MPP which is not optimal for efficiency, but the goal is to have it oscillate fast enough and fine enough that any variation from the MPP is negligible. For instances where the amount of sunlight changes slowly, this is an appropriate method. There is always a tradeoff and disadvantage, though. The downside to having the algorithm adjust often is that the microcontroller uses more power. The disadvantage to having a fine duty cycle increment is that, if there is ever a drastic change in the amount of sunlight that the solar panel sees, it will take longer for the controller to move to the new MPP. A situation where this

Page 10: MPPT Final Report

would have a significant impact is highly unlikely or impossible, though, so it was not a large factor in the decision making.

The system that was designed also includes a recalibration technique for the assurance of the correct MPP being reached. There were times when the system would get stuck at a certain duty cycle and not be able to detect any new changes. This was mainly an issue when the lights from the sun were off. Once the duty cycle got that low, there were many tiny variations in power within a small range of duty cycles. The algorithm would recognize a local maximum instead of the global maximum and get stuck on a very low duty cycle even if the lights turned back on and the duty cycle was supposed to increase. A counter was added to the microcontroller code so that every 1000 cycles the duty cycle will be forced to reset at 20%. This will allow the system to free itself from any minor local maximums that may be hindering the algorithm from recognizing the actual MPP. This does not have a noticeable impact on the efficiency because the microcontroller is operating at a fast enough speed that it is able to recover from the recalibration and move back to the duty cycle corresponding to the MPP extremely quickly. If this system was being used with the actual sun, this recalibration could be done much less frequently assuming the light from the sun changes more slowly than the lights from our model sun change.

ReferencesChoudhary, Dhananhay, and Anmol Ratna Saxena. “DC-DC Buck Converter for MPPT of PV System.”

International Journal of Emerging Technology and Advanced Engineering 4.7 (2008): 813-821. Web. 2 March 2016.

Milea, Petru, Adrian Zafiu, Orest Oltu, and Monica Dascalu. “Theory, Algorithms and Applications for Solar Panel MPP Tracking”. Solar Collectors and Panels, Theory and Applications. Ed. Reccab Manyala.187-210. Sciyo, 2010. Print.

Rosu-Hamzescu, Mihnea, Sergiu Oprea, and Microchip Technology Inc. “Practical Guide to Implementing Solar Panel MPPT Algorithms.” Microchip. Microchip Technology, 29 November 2012. Web. 2 March 2016.

Page 11: MPPT Final Report

Appendix A

A-1. MPPT Microcontroller Code

/* * MPPT.cpp * * Created: 3/16/2016 12:02:04 PM * Author : escalzet */ #define F_CPU 16000000#define BAUD 9600#define BAUD_TOL 3 #include <avr/io.h>#include <util/setbaud.h>#include <stdlib.h>#include <util/delay.h>#include <avr/common.h> void initialize_regs();void start_cycle(int &prev_voltage, long int &prev_pwr, int &updated_voltage, long int &updated_pwr);void update_readings(int &prev_voltage, long int &prev_pwr, int &updated_voltage, long int &updated_pwr);void read_ADC(int &voltage, int &current);void USART_Init();void USART_Transmit(unsigned char transData); int main(void){ // declare variables int updated_voltage, prev_voltage, duty = 50, count = 0; long int updated_pwr, prev_pwr;

initialize_regs(); start_cycle(prev_voltage, prev_pwr, updated_voltage, updated_pwr); // find power at 50% and 48% duty cycle // done initializing /* Infinite loop to make sure program is always checking */ while (1) { // P&O Algorithm if (updated_pwr > prev_pwr) { if (updated_voltage > prev_voltage) { if (duty > 4) duty -= 4; } else { if (duty < 96) duty += 4; } }

Page 12: MPPT Final Report

else if (updated_pwr < prev_pwr) { if (updated_voltage > prev_voltage) { if (duty < 96) duty += 4; } else { if (duty > 4) duty -= 4; } }

// update duty cycle if (count != 1000) { OCR2B = duty; count++; } else { duty = 20; // allow for recalibration every so often so PWM never gets stuck in wrong place OCR2B = duty; count = 0; } _delay_ms(100); // update power readings update_readings(prev_voltage, prev_pwr, updated_voltage, updated_pwr); }} void initialize_regs() { /* initialize registers */ DDRD = 0x08; // D port used to output PWM with correct duty cycle (just need pin D3 as OC2 output) // use ADCs for the two inputs DDRC = 0x00; // need Port C, pins 0 and 1 for inputs /* initializes ADC registers */ ADMUX |= (1 << REFS0) | (1 << ADLAR); // set reference (max in) to AVcc = 5V and set ADLAR to 1 - ADLAR left adjusts // need to set (1 << MUX0) if using ADC1, otherwise (0 << MUX0) if using ADC0 input ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // enables ADC and prescales to 64 (divides 16MHz by 64 -> input 250kHz clock) DIDR0 = 0b00111100; // disables pins 2-5 to save power, only allows input from pins 0/1, pins 6/7 cannot be enabled/disabled but must be 0 /* initializes timer/counter PWM registers */ OCR2A = 99; OCR2B = 50; TCCR2A |= (1 << COM2A1) | (1 << COM2B1) | (1 << WGM21) | (1 << WGM20); // timer/counter control register A chooses fast non-inverted PWM to output at OC2A

Page 13: MPPT Final Report

TCCR2B |= (1 << WGM22) | (1 << CS20); // timer/counter control register B chooses fast PWM mode, decide not to scale PWM freq since already divided internally by 256 USART_Init();} void start_cycle(int &prev_voltage, long int &prev_pwr, int &updated_voltage, long int &updated_pwr) { int current; /* find power at 50% duty cycle */ read_ADC(prev_voltage, current); // input voltage and current through ADC prev_pwr = prev_voltage*current; /* find power at 48% duty cycle */ OCR2B = 48; // update duty read_ADC(updated_voltage, current); // input voltage and current through ADC updated_pwr = updated_voltage*current; // I = V / ( Rshunt * 20 ) } void update_readings(int &prev_voltage, long int &prev_pwr, int &updated_voltage, long int &updated_pwr) { int current; char Txvolt[5] = {' ', ' ', ' ', ' ', ' '}, Txcurr[5]= {' ', ' ', ' ', ' ', ' '}; unsigned char carriage = '\r'; unsigned char newline = '\n'; /* update power readings */ prev_pwr = updated_pwr; prev_voltage = updated_voltage; /* input voltage and current through ADC */ read_ADC(updated_voltage, current); updated_pwr = updated_voltage*current; /* UART - send voltage and current to MATLAB */ itoa(updated_voltage, Txvolt, 10); for(int loop = 0; loop < 5; loop++) USART_Transmit((unsigned char) Txvolt[loop]); itoa(current, Txcurr, 10); for(int loop = 0; loop < 5; loop++) USART_Transmit((unsigned char) Txcurr[loop]); USART_Transmit(carriage); USART_Transmit(newline);

Page 14: MPPT Final Report

} void read_ADC(int &voltage, int &current) { /* input voltage through ADC */ ADMUX = 0b01100000; // set input to ADC0 ADCSRA |= (1 << ADSC); // set ADSC to start conversion while ( !(ADCSRA & (1 << ADIF) ) ) // Wait until flag is tripped { } ADCSRA |= (1 << ADIF); // Reset flag voltage = ADCH; // outputs ADC /* done inputting voltage */ /* input current through ADC */ ADMUX |= (1 << MUX0); // set input to ADC1 ADCSRA |= (1 << ADSC); // set ADSC to start conversion while ( !(ADCSRA & (1 << ADIF) ) ) // Wait until flag is tripped { } ADCSRA |= (1 << ADIF); // Reset flag current = ADCH; // outputs ADC /* done inputting current */ } void USART_Init(){ DDRD |= (1 << DDD1); // Pin D1 as backup output UBRR0 = UBRR_VALUE; // Baud rate if(USE_2X) UCSR0A |= (1 << U2X0); // set double speed if needed else UCSR0A &= ~(1 << U2X0); UCSR0B |= (1 << TXEN0); //Tx Enable UCSR0C |= (1 << UCSZ00)|(1 << UCSZ01); //Falling Edge} void USART_Transmit(unsigned char transData){ // sends 1 byte of data over UART while( !(UCSR0A & (1 << UDRE0)) ); // check status register for any error flags and that the transmit buffer is clear before writing to transmit buffer UDR0 = transData; // write the data to the transmit buffer}

Page 15: MPPT Final Report

A-2. PWM Microcontroller Code

/* * PWM.cpp * * Created: 4/22/2016 6:28:54 PM * Author : Computer */ #define F_CPU 16000000#define BAUD 9600#define BAUD_TOL 3 #include <avr/io.h>#include <util/setbaud.h>#include <stdlib.h>#include <util/delay.h>#include <avr/common.h> void initialize_regs();void update_readings(int &prev_voltage, long int &prev_pwr, int &updated_voltage, long int &updated_pwr);void read_ADC(int &voltage, int &current);void USART_Init();void USART_Transmit(unsigned char transData); int main(void){ // declare variables int updated_voltage, prev_voltage; long int updated_pwr, prev_pwr; initialize_regs(); /* Infinite loop to make sure program is always checking */ while (1) { // update power readings update_readings(prev_voltage, prev_pwr, updated_voltage, updated_pwr); }} void initialize_regs() { /* initialize registers */ DDRD = 0x08; // D port used to output PWM with correct duty cycle (just need pin D3 as OC2 output) // use ADCs for the two inputs DDRC = 0x00; // need Port C, pins 0 and 1 for inputs /* initializes ADC registers */ ADMUX |= (1 << REFS0) | (1 << ADLAR); // set reference (max in) to AVcc = 5V and set ADLAR to 1 - ADLAR left adjusts // need to set (1 << MUX0) if using ADC1, otherwise (0 << MUX0) if using ADC0 input

Page 16: MPPT Final Report

ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // enables ADC and prescales to 64 (divides 16MHz by 64 -> input 250kHz clock) DIDR0 = 0b00111100; // disables pins 2-5 to save power, only allows input from pins 0/1, pins 6/7 cannot be enabled/disabled but must be 0 /* initializes timer/counter PWM registers */ OCR2A = 99; OCR2B = 44; TCCR2A |= (1 << COM2A1) | (1 << COM2B1) | (1 << WGM21) | (1 << WGM20); // timer/counter control register A chooses fast non-inverted PWM to output at OC2A TCCR2B |= (1 << WGM22) | (1 << CS20); // timer/counter control register B chooses fast PWM mode, decide not to scale PWM freq since already divided internally by 256 USART_Init();} void update_readings(int &prev_voltage, long int &prev_pwr, int &updated_voltage, long int &updated_pwr) { int current; char Txvolt[5] = {' ', ' ', ' ', ' ', ' '}, Txcurr[5]= {' ', ' ', ' ', ' ', ' '}; unsigned char carriage = '\r'; unsigned char newline = '\n'; /* update power readings */ prev_pwr = updated_pwr; prev_voltage = updated_voltage; /* input voltage and current through ADC */ read_ADC(updated_voltage, current); updated_pwr = updated_voltage*current; /* UART - send voltage and current to MATLAB */ itoa(updated_voltage, Txvolt, 10); for(int loop = 0; loop < 5; loop++) USART_Transmit((unsigned char) Txvolt[loop]); itoa(current, Txcurr, 10); for(int loop = 0; loop < 5; loop++) USART_Transmit((unsigned char) Txcurr[loop]); USART_Transmit(carriage); USART_Transmit(newline); } void read_ADC(int &voltage, int &current) { /* input voltage through ADC */ ADMUX = 0b01100000; // set input to ADC0 ADCSRA |= (1 << ADSC); // set ADSC to start conversion

Page 17: MPPT Final Report

while ( !(ADCSRA & (1 << ADIF) ) ) // Wait until flag is tripped { } ADCSRA |= (1 << ADIF); // Reset flag voltage = ADCH; // outputs ADC /* done inputting voltage */ /* input current through ADC */ ADMUX |= (1 << MUX0); // set input to ADC1 ADCSRA |= (1 << ADSC); // set ADSC to start conversion while ( !(ADCSRA & (1 << ADIF) ) ) // Wait until flag is tripped { } ADCSRA |= (1 << ADIF); // Reset flag current = ADCH; // outputs ADC /* done inputting current */ } void USART_Init(){ DDRD |= (1 << DDD1); // Pin D1 as backup output UBRR0 = UBRR_VALUE; // Baud rate if(USE_2X) UCSR0A |= (1 << U2X0); // set double speed if needed else UCSR0A &= ~(1 << U2X0); UCSR0B |= (1 << TXEN0); //Tx Enable UCSR0C |= (1 << UCSZ00)|(1 << UCSZ01); //Falling Edge} void USART_Transmit(unsigned char transData){ // sends 1 byte of data over UART while( !(UCSR0A & (1 << UDRE0)) ); // check status register for any error flags and that the transmit buffer is clear before writing to transmit buffer UDR0 = transData; // write the data to the transmit buffer}

Page 18: MPPT Final Report

Appendix B

B-1. Display Power, Voltage, Current in MATLAB in Real Time

m.ReadAsyncMode = 'manual';

pts = 1000;

t=nan([1,pts]); t(1)=0;pwr=nan([1,pts]);vlt=nan([1,pts]);cur=nan([1,pts]);

figure;whitebg('white');

ax1=subplot(3,1,1);power=plot(NaN,'r');grid on;title('Power');ylabel('Power [W]'); xlabel('Time [seconds]');ylim(ax1,[0 4])

ax2=subplot(3,1,2);voltage=plot(NaN,'b');grid on;title('Voltage');ylabel('Voltage [V]'); xlabel('Time [seconds]');ylim(ax2,[0 20])

ax3=subplot(3,1,3);current=plot(NaN,'g');grid on;title('Current');ylabel('Current [mA]'); xlabel('Time [seconds]');ylim(ax3,[0 300])

for i=1:pts tic; stuff=0; %make numel(stuff)~=2 while numel(stuff)~=2 || stuff(1)>274 || stuff(2)>571 %(max 25V 2A) %updated 4/21/16 5:16PM stuff = str2num(fgets(m)); end vlt(i)=stuff(1)/10.9861; cur(i)=stuff(2)/0.4893; %updated 4/21/16 10:00PM pwr(i) = vlt(i)*cur(i)/1000; set(power,'XData',t,'YData',pwr); xlim(ax1,[t(i)-4 t(i)+1]) set(voltage,'XData',t,'YData',vlt); xlim(ax2,[t(i)-4 t(i)+1]) set(current,'XData',t,'YData',cur); xlim(ax3,[t(i)-4 t(i)+1])

Page 19: MPPT Final Report

drawnow %pause(.1); t(i+1)=t(i)+toc; end

B-2. Display PV Curve in MATLAB in Real Time

m.ReadAsyncMode = 'manual';

pts = 2000;len = 20;j = 1;

pwr=nan([1,len]);vlt=nan([1,len]);

figure;%whitebg('black');

pv=scatter(NaN,NaN,'r');grid on;title('PV Characteristic');ylabel('Power [W]'); xlabel('Voltage [V]');axis([0 20 0 4]);

hold;newpv=scatter(NaN,NaN,'b');

for i=1:pts stuff=0; %make numel(stuff)~=2 while numel(stuff)~=2 || stuff(1)>274 || stuff(2)>571 %(max 25V 2A) %updated 4/21/16 5:16PM stuff = str2num(fgets(m)); end vlt(j)=stuff(1)/10.9861; cur(j)=stuff(2)/0.4893; %updated 4/21/16 10:00PM pwr(j) = vlt(j)*cur(j)/1000; set(pv,'XData',vlt,'YData',pwr) set(newpv,'XData',vlt(j),'YData',pwr(j)) drawnow if j == len j = 1; else j = j+1; end end

B-3. Find Scaling Factors for MATLAB

Page 20: MPPT Final Report

m.ReadAsyncMode = 'manual';

pts=20;

vlt=nan([1,pts]);cur=nan([1,pts]);stuff=0;

for i=1:pts stuff=0; %make numel(stuff)~=2 while numel(stuff)~=2 || stuff(1)>274 || stuff(2)>571 %(max 25V 2A) %updated 4/21/16 5:16PM stuff = str2num(fgets(m)); end vlt(i)=stuff(1)/10.9861; cur(i)=stuff(2)/0.4893; %updated 4/21/16 10:00PM endmean(vlt)mean(cur)

Appendix C

Page 21: MPPT Final Report

C-1. Set Each Light in Model Sun

function [ ] = setlights(s, bank)%SETLIGHTS Configures lighting of sun to desired on/off values% sends 's' character followed by four numbers (0-255)% specified by matrix BANK, and ends with sending the LF% (Line Feed) control character (ASCII Code 10)% to serial port associated with serial port object s.fwrite(s,'s');fwrite(s,bank(1));fwrite(s,bank(2)); fwrite(s,bank(3)); fwrite(s,bank(4)); fprintf(s,'');end

C-2. Have Lights Incrementally Turn On/Off

%% NOTE: BANK(2)=128 DOES NOT EXIST%% (8th light of bank 2 or top/center light)delay=3; % make sure delay>1 to give bulb enough time to turn on

%Connect to serial port%s = serial('COM3', 'BaudRate', 9600);%fopen(s);

%initialize each bank as offbank = [0 0 0 0];setlights(s,bank);pause(1);

%double lights moving back and forth: (ctrl+C to stop execution)while 1 %forward for i = 1:4 for j=0:2:6 %0 2 4 6 bank(i)=bank(i)+2^j+2^(j+1); setlights(s,bank); pause(delay); end end %backward for i = 4:-1:1 for j=6:-2:0 %6 4 2 0 bank(i)=bank(i)-2^j-2^(j+1); setlights(s,bank); pause(delay); end end end