Arduino Solar Current Sink

Solar panel current sink.

Characterization of a solar panel, for the purposes of this project, means to graph the voltage vs. current for a range of currents, with an assumed even illumination. It may seem a little simple to expect that to tell us anything standard about the panels, but I don't want to know anything standard. I want to know how this particular panel behaves in this particular backyard. How much load can I give it before the voltage drops to a point that it can't be used?

The point we are looking for is called the maximum power point (MPP). On the graph below, the yellow line is the total power being generated by the panel. Power increases, but then falls off. It is not exactly coincident with the sharp voltage falloff, but is somewhere just above that point. In order to harvest the maximum power, you need to find that point. For this panel, it is 7.061V @ 76mA.

Solar panel output graph
Solar panel output graph

A high-power rheostat could be used, but it isn't going to be nearly as easy to the control the current. With this circuit the Arduino just ramps the set point linearly, and measures the values of voltage and current. The accuracy is based on the precision of the current sensing resistor, R1. In my application, the total power generated by a single panel was about 0.534W, but a larger panel could be tested, with an output up to 450mA. A resistor with less resistance could be used for larger panels. A 1Ω resistor would be good for up to 5A. These values are more than the 2W rating of the resistor, so if you are going to measure more than 450mA, you need to increase the power rating of the resistor.

Solar panel current sink
Solar panel current sink

The Arduino sketch sets the setpoint on pin D9, waits 50mS for things to settle, and reads the voltage and current on A0 and A1. Then it writes it to the uSD card, for use later. The panel voltage is (5/1024)*ADU*2. (5/1024) is the voltage per ADU, and times 2 because the voltage divider cuts the voltage in half. The current in amps is (5/1024)*ADU/10. (5/1024) for the same reason, and divided by 10 because the resistor R1 is 10 ohms. The Arduino increments the PWM duty cycle from 0 to 100% in 256 intervals, causing the current to increase from 0mA to a maximum of 500mA in 1.95mA increments. There is a point at which the panel gives up, and its output voltage drops to nearly zero. The Arduino does not care - it goes on about its business of increasing the current flow, which of course it can't do, so the data is no good after the voltage falls.


/*
 * Solar Panel Characterization
 * 
 * This app uses a voltage controlled current sink circuit to
 * characterize solar panel performance with increasing load.
 */

#include <SPI.h>
#include <SD.h>

const int chipSelect = 8;

int pwmValue;
int currentPin = A1;
int voltagePin = A0;
int currentSink = 9;

File dataFile;

void setup() 
{
  
  Serial.begin(9600);

  pinMode(chipSelect, OUTPUT);
  if (!SD.begin(chipSelect)) {
    Serial.println("Card not present.");
    
    // Halt!
    while(1);
  }
  Serial.println("Card initialized.");

  dataFile = SD.open("solar.csv", FILE_WRITE);
  if (!dataFile) {
    Serial.println("Error opening file on SD card.");
    
    // Halt!
    while(1);
  }
  
  String output = "PWM,VOLTAGE,CURRENT";
  dataFile.println(output);

  pwmValue = 0;
  analogWrite(currentSink, pwmValue);
}

void loop() 
{

  // Set the current sink to the next level.
  analogWrite(currentSink, pwmValue);

  // Give it 50 milliseconds to stabilize.
  delay(50);

  // Read the voltage.
  int ADU = analogRead(voltagePin);
  float voltage = (5.0/1024.0)*ADU*2.0;

  // Read the current.
  ADU = analogRead(currentPin);
  float current = (5.0/1024.0)*ADU/10;

  // Make a csv string.
  String output = String(pwmValue) + "," + String(voltage,2) + "," + String(current,3);
  
  // Store the data on the SD card.

  // if the file is available, write to it:
  dataFile.println(output);

  // Adjust to the next level. Halt if > 255.
  if (++pwmValue == 256)
  {
    // Shutdown the current sink (the transistor could get very hot).
    analogWrite(currentSink, 0);

    // Close the file on the SD card.
    dataFile.close();

    // Let the user know it is finished.
    Serial.println("Done.");

    // Loop forever.
    while(1);
  }
}
			

The result is a CSV file containing all 256 pairs of values:


PWM,VOLTAGE,CURRENT
0,4.23,0.000
1,4.23,0.002
2,4.21,0.004
3,4.19,0.005
4,4.19,0.007
5,3.18,0.008
    .
    .
    .
			
Arduino Board Logo

 

Arduino-Board is the go-to source for information on many available Arduino and Arduino-like boards, tutorials and projects.

Help and Support

Arduino-Board

Stay updated

Sign up if you would like to receive our once monthly newsletter.