Using MOSFET and Arduino for PV IV curve tracer.

Thread Starter

JohanEricson

Joined Aug 30, 2017
36
I've been thinking of making a quick and dirty IV-curve tracer for solar panels, and I finally got the time.
It consists of an IRF520 MOSFET to function as a VCR, an INA260 breakout board to take the measurements and an Arduino to generate a PWM and gather the data onto an SD card.

Everything is working as it should, the data is neatly collected and there's no magic smoke. Success!

Or so I thought until I started to look at the data and plotting the actual IV curve...
It looks awfully linear and not at all how I expected, and I can't for the life of me figure out why.

I've been doing some reading on MOSFET and logic level PWM and I've come to the conclusion that the IRF520 is not the best match for the Arduino. But I've measured currents up to around 3A, which seems to be about what I can expect from the IRF520 with Vgs at 5V.

I have also included a reference PV cell to calculate the irradiance in w/m2.

The graph is based on these circumstances:
* Panel data: Voc = 21.5, Isc = 3.92, Vmp = 17.3, Imp = 3.56, Pmp = 60W
* about 800w/m2 irradiance 90 degrees to the panel. Not all over the panel tough, this might explain the low Isc.
* Vgs is a 980Hz PWM, that is stepping duty cycle from 0 to 255 bits 1 bit at a time.
* The light source is a bunch of 250W lights.
IV curve.png



So Voc seems to be as stated by the panel datasheet.
Isc is low, but I've confirmed with a multimeter that with the setup I used it actually was about 1.6 A.

So now, let's get to my qeustion: Why is the current decreasing linearly ? I have a hard time telling if it's related to the MOSFET and/or the INA260 or the fact that i don't have the full 1000w/m2 irradiance or something else...

Any thoughts on this would be really helpful!
I guess my knowledge is lacking, and I don't even know I don't know. So I hope to learn something new!

Thank you for reading!
 

AlbertHall

Joined Jun 4, 2014
12,120
My guess for what it's worth:
(For a better guess, give us a full schematic.)
If you are using the PWM to turn the MOSFET on and off then the panel won't see other than maximum or minimum current, it won't ever be seeing a current in between them.
Now the PWM is just changing the proportion of time you're getting maximum current so I would expect the average of that to be linear with the PWM.

I think you're going to need a load resistance which you can vary smoothly over a range. A MOSFET could do that if you feed the gate with a smoothly changing voltage but it's going to generate a lot more heat and need a big heatsink.
 

Irving

Joined Jan 30, 2016
2,993
You're not really loading the PV panel with that setup as previously stated. You need an electronic load. For under 200W look at the cheap e-loads available on eBay /Amazon/AliExpress eg https://m.aliexpress.com/item/1005001413586633.html as a basis or roll your own, search YouTube for "e-load", there are plenty of examples.

A better device for this purpose are the Linear L2 range of MOSFETs from LittelFuse/IXYS, eg the IXTH64N10L2 that will, on the right heatsink, dump 200W for under $5.
 

Thread Starter

JohanEricson

Joined Aug 30, 2017
36
My guess for what it's worth:
(For a better guess, give us a full schematic.)
If you are using the PWM to turn the MOSFET on and off then the panel won't see other than maximum or minimum current, it won't ever be seeing a current in between them.
Now the PWM is just changing the proportion of time you're getting maximum current so I would expect the average of that to be linear with the PWM.

I think you're going to need a load resistance which you can vary smoothly over a range. A MOSFET could do that if you feed the gate with a smoothly changing voltage but it's going to generate a lot more heat and need a big heatsink.
Ah, seems to make sense!
I've read this paper that uses an LP filter on the gate, and it looks like they are getting pretty good results. So I guess I'll try that to start with. In the video I linked below an LP filter is used on the PWM together with a TC4420 MOSFET driver. What is the purpose of the driver, can I use say a voltage OP-amp voltage follower or something instead?

You're not really loading the PV panel with that setup as previously stated. You need an electronic load. For under 200W look at the cheap e-loads available on eBay /Amazon/AliExpress eg https://m.aliexpress.com/item/1005001413586633.html as a basis or roll your own, search YouTube for "e-load", there are plenty of examples.

A better device for this purpose are the Linear L2 range of MOSFETs from LittelFuse/IXYS, eg the IXTH64N10L2 that will, on the right heatsink, dump 200W for under $5.
Thank you! I watched this video and it's given me some enlightenment. It's a bit more evolved than what I have the need for at the moment but I can use it as a guide. I'm wondering what's the purpose of the TC4420 MOSFET driver before the RC-filter?

I also found this video that have a lot of really useful information! I'll leave it here is anyone wanting to build one is ending up on this thread.
 

Irving

Joined Jan 30, 2016
2,993
I like this video, he's using a proper Linear MOSFET, the right device for the job... the others are using standard MOSFETs which have a very small ohmic region.

GreatScott's design is OK but his explanation is back to front... the saturation region is where you are when switching for minimal losses...

I'm wondering what's the purpose of the TC4420 MOSFET driver before the RC-filter?
His use of PWM with the driver is to get enough drive power after the losses in the LPF. The design is flawed IMHO because of the PWM which generates quantization noise in the load.

The ElectroNoobs version is a better explanation and design, with analog op-amp feedback & control, though his 1ohm current sense resistor is too large and limits his lowest working voltage (though there are ways round that).

I use a proper 14bit DAC driving a high-power op-amp in my 1500W e-load, and a 14bit ADC to measure both voltage and current, with a 100A 75mV shunt for current sensing.
 

Thread Starter

JohanEricson

Joined Aug 30, 2017
36
Ha!
At least now it looks correct!
I changed the IRF520 to one with more compatible characteristics and added a simple RC filter on Vgs.
Still quick and dirty but seems to do the job. I will have to look into the values of R and C in the filter to be able to decrease the sampling frequency and still get correct readings. egen iv.jpg

And I will definitely more proper one with a DAC in the future.
 

Thread Starter

JohanEricson

Joined Aug 30, 2017
36
So i think i have it working about as well as i need it to at the moment, i have written a python program to take the data from the serial port to plot and do some analysis on.
And since I do not really know how precise the measurements are i decided to also to do 3 rounds of measuring, i.e make 3 IV curves to see if they differ and make a mean curve. But i get some weird results in curve no. 2 and 3...

The duty cycle for the MOSFET gate is starting at 130 and stepping up 1 bit at a time till it reaches 255. (i have not yet looked more into what range is actually required), making the voltage start av Voc and current at 0 A. And the first time it's working very well! But the second and third time the first 3 or 4 values gives a current at about Isc (about same as the last values in the previous measuring round)

I have tried to see if it's the python code that's behaving strangely, but the data looks to be wrong directly from the Arduino.
I've tried to add a long delay between the 3 measuring rounds but no luck...

Adding some pictures and the Arduino code in hopes that someone can spot some mistake that i do not know is a mistake.
Arduino Main:
#include <Adafruit_INA260.h> // Bibliotek för ina260

Adafruit_INA260 ina260 = Adafruit_INA260();

//Variabler för ina260
int sampleTime = 10;
float current;
float voltage;
float power;

// Variabler för referenscell
int refCellPin = A1;
float refCellVoltage = 0;


// Variabler för IV-tracer
int PWMPin = 6;
int dutyCycle = 130;
int dutyStep = 1;
int i = 0;

void setup() {
  Serial.begin(115200);
  while (!Serial) { delay(10); } // Wait until serial port is opened
  ina260Setup();
  refCellSetUp();
  IVSetUp();
}

void loop() {
  while(i<3){
    Serial.println("Current,Voltage,Power,dutyCycle,Irradiance");
    IV();
    i++;
    dutyCycle=130;
    delay(5000);
  }
}
IV Function:
void IV(){
  dutyCycle = 130;
  while(dutyCycle <= 255){
      analogWrite(PWMPin, dutyCycle);
    getElectric();
    refCell();
    printSerial();
      dutyCycle = dutyCycle+dutyStep;
    delay(sampleTime);
  }
}
serial print function:
void printSerial(){
  Serial.print(current);
  Serial.print(",");

  Serial.print(voltage);
  Serial.print(",");

  Serial.print(power);
  Serial.print(",");

  Serial.print(dutyCycle);
  Serial.print(",");
 
  Serial.println(refCellVoltage * 12.8535, 4);
 
}
Measuring 1

CurrentVoltagePowerdutyCycle
0​
19832.5080.00
130​
0​
19835.0080.00
131​
0​
19835.0050.00
132​
7.5019827.50150.00
133​
51.2519802.501010.00
134​
103.7519763.752050.00
135​
153.7519731.253030.00
136​
216.2519693.754260.00
137​


Measuring 2
CurrentVoltagePowerdutyCycle
3737.5055.00200.00
130​
3738.7565.00240.00
131​
3378.7512258.7553990.00
132​
992.5019212.5019070.00
133​
420.0019535.008220.00
134​
333.7519606.256540.00
135​
338.7519602.506640.00
136​

Measuring 3
CurrentVoltagePowerdutyCycle
3737.5055.00200.00
130​
3738.7565.00240.00
131​
3390.0012978.7555260.00
132​
996.2519195.0019120.00
133​
500.0019500.009750.00
134​
396.2519566.257760.00
135​
378.7519576.257410.00
136​
 

Irving

Joined Jan 30, 2016
2,993
Need to see the code for the other subroutines. Are you artificially rounding the numbers? Zero current shouldn't produce a non-zero power?

There's also something odd about your current in runs 2 and 3 in that increasing duty cycle should increase current but it seems to be going down, which suggests this isn't working the way you think it is...

Have you verified the ina260 readings with a multimeter, both V and I?
 

Thread Starter

JohanEricson

Joined Aug 30, 2017
36
Need to see the code for the other subroutines. Are you artificially rounding the numbers? Zero current shouldn't produce a non-zero power?

There's also something odd about your current in runs 2 and 3 in that increasing duty cycle should increase current but it seems to be going down, which suggests this isn't working the way you think it is...

Have you verified the ina260 readings with a multimeter, both V and I?
The zero values for the current were changed manually in excel, they are actually negative coming from the INA260. The values are all in mili-whatever.
CurrentVoltagePowerdutyCycle
-3,75​
19832,5​
80​
130​
-3,75​
19835​
80​
131​
-2,5​
19835​
50​
132​
7,5​
19827,5​
150​
133​
51,25​
19802,5​
1010​
134​
103,75​
19763,8​
2050​
135​

So the power seems to be |current| * voltage and rounded up directly from the INA260.

Yeah, those strange values in run 2 and 3 are what is confusing me, they are starting high for a couple of points in the beginning, then dropping down to values that i expect them to and follow the expected values til the end.

Reference PV cell:
void refCell(){
  refCellVoltage = analogRead(refCellPin)*(1.1/1023)*1000;
}
Get electric values:
void getElectric(){
  current = ina260.readCurrent();
  voltage = ina260.readBusVoltage();
  power = ina260.readPower();
}
The thing that is confusing me is that it seems to be working very well for the first run and then not so well for the second and third run...

I guess I would have to measure with a multimeter to figure out if the strange values are the actual values or something lagging in the serial communication. Not really sure at the moment how to write a code that would "simulate" the same conditions but slow enough to be able to measure with a multimeter?

Attaching a picture of the plots also, might make it easier to know what I mean about the data being strange.
Figure_1.png

Thank you so much Irving!
 

Irving

Joined Jan 30, 2016
2,993
Add this at the top of the loop...


C:
While(!Serial.available()){ };
char ch = Serial.read();
This will stall the loop and progress it each time you send a key press to the Arduino from the serial monitor.

Or you could do it with a push button wired to ground from a GPIO pin... If you prefer I could post the code for that..
 

Thread Starter

JohanEricson

Joined Aug 30, 2017
36
Hi Again!
As I indicated earlier in this thread I have now tried to build a "real" electronic load with some extra nifty tools specifically for use with PV panels and cells.
It is largely based upon the design by electronoobs but uses the adafruit INA260 breakout board instead of the voltage divider and ADC used in the original project.

I have been struggling a bit to know what MOSFET to use, I know that I should use a linear one. But at the moment I don't have access to one so bear with me...
I decided upon the IRLZ44N based upon some other designs that i looked at. It is controlled by an arduino uno via a MCP4725 DAC with 12bit resolution for a maximum Vgs of 5V.

I have built it and it seems to be working fine until a specific Vgs is applied on the MOSFET. I wrote a code just to sweep Vgs and log the current flowing through. I did this for different levels of Vds and different maximum currents. And all of them show a strange behavior starting around 1530 and 15454 bits which would be about 1,8V Vgs given that we have 4096 bits and 5 volts. The graph shows the current Ids on the y-axis and DAC bits on the x-axis.
Then when the current bumps up to maximum around the expected Vgs.

Can someone give me a hint on what to check, I have exhausted my knowledge unfortunately.

Just let me know if there's any other information you need to be able to say something!

Thank you so much for your time!
 

Attachments

Irving

Joined Jan 30, 2016
2,993
Ah yes, not sure of the mechanism, but see this thread where the op is experiencing a similar issue on a slow Vgs ramp. Apparently a small capacitor drain-source may help.

I'm still of the opinion that the onset of Id raises the source voltage due to resistance/inductance in the source lead, which reduces Vgs and induces some random oscillatory behaviour. Try attaching the ground/source side of the Vgs feed as close to the MOSFET body as possible to eliminate any cross-talk here.

Is there any value/combo of Id & Vds it doesn't happen at?

Are you using the INA260 high side or low side?
 

Thread Starter

JohanEricson

Joined Aug 30, 2017
36
Ah yes, not sure of the mechanism, but see this thread where the op is experiencing a similar issue on a slow Vgs ramp. Apparently a small capacitor drain-source may help.

I'm still of the opinion that the onset of Id raises the source voltage due to resistance/inductance in the source lead, which reduces Vgs and induces some random oscillatory behaviour. Try attaching the ground/source side of the Vgs feed as close to the MOSFET body as possible to eliminate any cross-talk here.

Is there any value/combo of Id & Vds it doesn't happen at?

Are you using the INA260 high side or low side?
Thank you Irving, I might try to put a capacitor drain to source.
Okay, physically close to shorten cable length?

Would it help to get scope pictures of Vgs?

The problem seems to be not as significant for smaller Vds. The graph attached is for 0.6V Vds and 1A max Id.

The INA260 is used for high isde.
 

Attachments

Thread Starter

JohanEricson

Joined Aug 30, 2017
36
It would be highly advisable to post a schematic diagram of your setup.

So many assumptions are being made here.
Of course, i just have to make sure it actually represents what was actually built in the end..

After doing some reading up on signal interference it's pretty clear that my grounding is let's say... sub-optimal. I thought about it when i was putting it together and decided just to ignore it and hope for the best. Turns out, once again, that this maybe not was such a good idea.

So at the moment I'm trying to make some improvements without having to rip the whole thing apart to see if that might make any difference.
 

Thread Starter

JohanEricson

Joined Aug 30, 2017
36
Ha..! after fiddling around with the various ground connections for a while without result I decided to put a capacitor across drain-source of the MOSFET.
I suspect that this doesn't really fix the real problem, only hiding it? Anyway, the sweep works, and I'm happy!

And now the electronic load also works!
The INA260 values are jumping around a bit, so will spend some time on tuning that.

I will still post a schematic as soon as I have revised it, so you can point out my flaws and i can learn something!

Thank you so much for your help!
 

Attachments

Irving

Joined Jan 30, 2016
2,993
A BJT might be better for linear operation. The advantages of MOSFETs are mostly in switching applications.
Unless you use a Linear MOSFET designed for the task, in which case they are as good as BJT if not better. No thermal runaway, easier parallel matching and simpler drive characteristics. I use 8 off IXTX200N10L2 at 250W (25v/10A) each for a 2000W (25v/80A) active load for testing LiFePO4 battery packs. The only difficulty was finding a cost-effective 0.1degC/W heatsink to keep case temp at 75degC - I rolled my own water-cooled slab with a small car radiator slung out of the window...

Edit: looking on Mouser the only BJT that comes close is a MJW18020 and I'd need 14 off. Digikey doesn't even list anything current that comes close, they're all obsolete devices.
 
Last edited:

BobTPH

Joined Jun 5, 2013
5,493
Wow, what do those babies cost?

I did not know there were MOSFETs specifically designed for operation as current controllers.

Bob
 
Top