One of the nice things about a microprocessor is you can build little tests into them. In my house program I have a number of screens I can enter with a keyboard command to display charging, fridge, heating, resets, etc. operations and display variable values. I've had some bad experiences with solar panels and this routine is a convenient way to check them. The water heater elements serve as the dump load. I just wait for a quiet time in the system when batteries are nearly charged and the fridge isn't running to do the test. It is a straight forward process where I turn everything off that is used by the 36V string. Then I record that open circuit voltage and start ramping up the PWM numbers till it reaches the end or the lowest test voltage I want, in my system that is about 47V. The resistance is known so the maximum amperage is calculated based on the voltage. That current is multiplied by the duty cycle percentage to get average current. The average current is then multiplied by the voltage at that time to get power. The power is compared with the previous power. If higher, it is stored along with the variables at that time giving the power point of the panel. All integer math. Not super accurate, but repeatable. It tells you basically what you want to know. A large capacitor must be used on the panel power so the current averages. Could be a useful addition to your program with some minor changes. Half the value (aprox) of the divisor is added before any division to round up numbers. At the end, keyboard stores the last key pressed. Most screens keep displaying new data and are part of the program delay. Dis a screen that only has a delay so the power point data stays till another key is pressed.
// *********************************************************************
// H, HIGH POWER POINT SCREEN HEATERS #1 2000W & #2 1500W
if (kbd == 'H' || kbd == 'h') // if H or h, send out POWER POINT
{
analogWrite (11, 0); // Turn off 36V charging
analogWrite (3, 0); // Turn off heater #1
analogWrite (10, 0); // Turn off heater #2
pmax = 0; // reset pmax value
Serial.println(" ");
Serial.println(" HIGH POWER POINT SCREEN HEATER #1 & #2 ");
Serial.println(" ");
delay (200); // delay before reading voltage
AI1 = analogRead(1); // read OPEN 36V PANEL VOLTAGE
Serial.print((float) AI1 * 8 / 100); // calculate voltage
Serial.println(" initial voltage ");
// after initial voltage reading test each PWM value starting with
for (int i=5; i <= 255; i++) // TEST EACH PWM LEVEL starting at 5
{
analogWrite (3, i); // Turn on heater #1 7.81 ohms 2000W @ 125V
analogWrite (10, i); // Turn on heater #2 10.4 ohms 1500W @ 125V
// Turn on BOTH heaters 4.13 ohms
delay (500); // delay before reading voltage
long VOLTS = 0; // reset VOLTS and declare as long first time
AI1 = analogRead(1);
//AI1 = 1023; // TEST ONLY at max value
VOLTS = AI1 * 4; // add first value
AI1 = analogRead(1);
//AI1 = 1023; // TEST ONLY at max value
VOLTS = VOLTS + AI1 * 4; // add second value
Serial.print((float) VOLTS / 100); // voltage value at PWM value
Serial.print(" voltage @ ");
Serial.print(i); // PWM value
Serial.print(" ");
// calculate max possible Amps
// multiply by 10 so resistance is integer number
//long Amax = (VOLTS * 100 + 550) / 1040; // max possible w/ HEATER #2 10.4 ohms (SMALL)
//long Amax = (VOLTS * 100 + 400) / 781; // max possible w/ HEATER #1 7.81 ohms (MEDIUM)
long Amax = (VOLTS * 100 + 220) / 413; // max possible BOTH HEATERS 4.13 ohms (LARGEST)
// add 220 for round up, about half of divisor
Serial.print((float) (Amax + 50) / 100);
Serial.print("A max ");
long AMPS = (Amax * i + 150) / 255; // actual amps from % PWM
Serial.print((float) (AMPS + 55) / 100); // add 55 for round up
Serial.print("A ");
VOLTS = (VOLTS + 6)/ 10; // add 6 for round up
long POWER = AMPS * VOLTS;
Serial.print((POWER + 550) / 1000); // add 550 for round up
Serial.println(" power ");
POWER = POWER / 100; // divide down to whole watts
if (pmax < POWER) // record maximum power points if bigger
{
PWX = i; // record maximum PWM
pmax = POWER; // record maximum voltage
VPP = VOLTS; // record maximum voltage
}
// look at raw A/D panel and
if (AI1 < 590) i = 255; // end if under voltage condition
} // end for loop
// display power point conditions & return to normal operations
Serial.println(" ");
Serial.println(" end of test ");
Serial.print((pmax + 6) / 10); // maximum value of power
Serial.print(" max power @ ");
Serial.print(PWX);
Serial.print(" PWM ");
Serial.print((float)VPP / 10);
Serial.println("V");
analogWrite (3, 0); // Turn off all heater #1
analogWrite (10, 0); // Turn off heater #2
delay (100);
keyboard = 'D'; // go to DELAY to maintain screen timing
// next and return to normal program
} // end of this screen
// *****************************************************************