Tripple MPPT with one Pro Micro

Hi everyone, I’ve got a project I’m wanting to build, and its quite complex, but I think I can handle it with just a little guidance.
The scope of the project is to build a 3 legged MPPT system. The physical layout of my property, and other limiting physical factors, such as buildings, and trees, require that I have my PV panels laid out in 3 separate arrays, one facing E, one S, and the last SSW. Each array consists of 2 x 15W panels. 22Voc.
My current charge controller simply combines the arrays in parallel through a diode on each leg input. This combined input then feeds a PWM charge controller which is connected to a pair of 100Ah “deep-ish” cycle batteries.(automotive style liquid lead acid trolling motor), LVCO(loads) and night light controller.

So I’ve been reading and collecting parts lists, and I think what I have settled on is a synchronous buck arrangement. Well, 3 of them. I’ve found several schematics for these, most of which use IFRZ44 FETs, and a driver chip. Easy enough. While I realize that these parts are a bit of overkill for the current size system, if I can make this controller work, panel and storage upgrades will be next. (also let it be known that this project is as much about having an idea and trying to make it work as it is about actually improving my PV system)

Here is where the design decisions become sticky, and I’d like some input. The panels are currently paralleled in each leg, meaning that each input wire coming in from outside is 22Voc and the panels are + to + and – to – out in the field. Theory was that I could get 2xpanel current coming in on each of the 3 legs. Due to long wire losses, and the impedance mismatch between the panels and the battery, at best I’m getting 1A @14.7v from each leg during charging. Half of the current I would get ideally.

So the basis for all this was that I was thinking that if I put the panels in series in each leg, thus getting 44Voc, but trying to push less amps through long wires, I could use a MPPT circuit and improve the system efficiency.

So, using a pro micro, and figuring I’ll need 4 measurements from each of the arrays, plus a control signal to each of the MPPT’s, I’ve run outta pins. Enter the I2c ADC. I’ve seen 8bit ones, 10bit ones and 12 and 16’s. But really, how much resolution do I need? I’m thinking that 10bits should be enough(cause the pro micro uses 10bit for it’s internal ADC’s). And they have 4 and 8 channel ones. I’m thinking this sounds great, I2c is easy, and I can have up to 4 of the 4chanel adc’s I found all on the same com lines. If I use 3 of them, one for each array, That gives me 12 inputs(and in my mind will make coding easier cause when I address the ADC I can just group my readings together) and then I can read the battery state directly through the on-board pro micro ADC

what about timing? Can I read that many inputs through the ADC’s via I2c fast enough to be useful feedback to control the 3 MPPT’s?

Would an analog MUX be faster? I’d have to use a couple pins on the pro micro as control lines to the MUX, but if I have all of my readings coming in through the MUX, then I have pins to spare. That also raises the question of noise, or reading instability, by going through the MUX.

Are the 3 MPPT circuits going to battle at their outputs? Do they need to be combined through diodes so that when one is a little higher V output, this doesn’t fool the others into trying to reduce their outputs?

Going further into the project, I’d like to collect the data, and post it online so I can see it from my phone from anywhere. I could also see adding the night light control function and LVCO, but those will be easy if I can get all the rest to work.

So, whaddya think? Can a 5V 16Mhz Pro Micro handle all this?

Project5k:
Can a 5V 16Mhz Pro Micro handle all this?

Sure.

But I don't understand what your question is.

Sort your thoughts, draw a nice wiring diagramm and post it here, provide links to the additional hardware you want to use with arduino, then we might be able to help you.

Project5k:

Going further into the project, I’d like to collect the data, and post it online so I can see it from my phone from anywhere. I could also see adding the night light control function and LVCO, but those will be easy if I can get all the rest to work.

So, whaddya think? Can a 5V 16Mhz Pro Micro handle all this?

not sure about the way to balance MPPT devices.
but the Pro Micro cannot post data online. you need some sort of internet connection.
The ESP32 has the analog inputs and a WiFi ability in one chip.

Hi,
Welcome to the forum.

OPs pic.
current solar controller 3edit.jpg

Tom… :slight_smile:

It appears that you are intereted in learning as well as doing.

I would offer that any Arduino you get can data log.
you could pick any one and start to datalog and then see what you like, what you can do, and what you feel needs to be done.

nothing like hands-on to learn something.

not sure if it is against the forum rules to cross-quote....

Quote from: Nick_Pyner Mon Dec 24 2018 18:13:58 GMT-0500 (Eastern Standard Time)

original post

There are better options than the serial plotter, indeed I believe any option is better, and the serial plotter is a complete waste of time. I believe you are better off using a proper terminal programme like RealTerm to collect the data and send that file to whatever it is you intend to use for analysis. If that destination is Excel, you can use the PLX v2 macro to send the data to Excel direct and view live graphs therein.

Another option was LiveGraph, I think it came from University of Melbourne.

the introduction of the idea of the ESP32 really fired up my analytical paralysis. (I suffer from trying to overthink every detail before making any moves)

The ESP32 is a really interesting idea, and I’ll have to read further on it, cause at first glance, it seems that it would really simplify my project.

Do I understand correctly that I can program the ESP32 from the Arduino IDE? (meaning the coding I have learned so far with my pro micro’s wasn’t a waste)

I think I found a video class and a book available for it too, Have yall seen this one?

I’ll attach the diagram I drew up before I began considering the ESP32.

<>
UH OH, i just read this… that’s gonna be a show stopper if i cant read analog values…
"Not Yet Implemented

The Arduino board definitions for the ESP32 are still a work in progress. There are a handful of peripherals and features that have yet to be implemented, including:

Analog Input (analogRead([pin]))"

<>
<>
I’m not seeing the same limitations on the mega 2560, this one doesn’t have the wifi, but if i cant read all my inputs, then wifi doesn’t really matter…

not to put the ESP32 down, but it just seems the mega 2560 is the one i should use, yes??

As far as I can see from your block diagram, there is a lot of redundancy in your measurements.
You plan to measure the same voltage 4 times at the mppt outputs and battery.
Also, why do you want to measure the current output from each mppt AND the sum of it? You can just add them up in software.

Charging current is what you are trying to maximize for each PV-Array, so that is probably the only thing you really need to measure for that part.

ahhh, yes, I see your point. I’m going to have to come up with a way to “combine while keeping separate”.

Currently the 3 arrays come together through a diode on each leg, this is a loss in the system, but it allows the 3 legs to vary in voltage, and thus only contribute to charging when the voltage on any given leg (or combination of legs)is high enough.

I should have included the diodes in the block diagram.
with the diodes in, having the output of each MPPT measured becomes necessary.

having voltage sensing directly on the battery will allow for reporting during non charging hours, and to serve the LVCO controlling the loads.

updated block diagram attached.

Yes the ESP8266 can be programmed from the Arduino IDE. You just need to install the correct boards definition. Follow any of the online tutorials. There's a bunch.

One significant limitation is there's only one analog input. Yes you can use analogRead() just fine, but only from that one pin. If you need more, then you may need to add an external ADC chip.

Alright.

You are using Buck Converters as MPPT. They are controlled to maximize the outputted power (U*I)
As there are multiple PV "chains" charging the same battery, they will influence each other's MPP slightly, but that's fine.
After some MPP "search" runs they will automatically "agree" on the best charging voltage.

I don't see why you need to measure voltage and current at the mppt input though.

couka:
I don't see why you need to measure voltage and current at the mppt input though.

i probably don't to make it work, but for data logging purposes, and my own personal entertainment i wanna.

couka:
As there are multiple PV "chains" charging the same battery, they will influence each other's MPP slightly, but that's fine.
After some MPP "search" runs they will automatically "agree" on the best charging voltage.

could I ask you to expound on the agree portion?

seems to me that probably what will happen is that the 3 will teeter back and forth, PV1 a little higher than 2 and 3, then on the next judgment 2 and 3 try to catch up, and that may cause 1 to "rubberband" downward, and so on. basically i figure the 3 will play with each other, each taking the lead off and on... (actually i figure one set of PV's will generally produce more and will be in the "lead" most often, but not always)

MorganS:
Yes the ESP8266 can be programmed from the Arduino IDE.
One significant limitation is there's only one analog input. Yes you can use analogRead() just fine, but only from that one pin. If you need more, then you may need to add an external ADC chip.

ok, good to know, but the limitation of the analogRead command is why i stepped away from it. Adding ADC's is the same as what i started off with, and is an additional layer of complication that the MEGA resolves. As i have no size restrictions, having all the ADC's already onboard makes things easier and thus as of right now i think the MEGA 2560 seems my best answer.

Project5k:
i probably don't to make it work, but for data logging purposes, and my own personal entertainment i wanna.

could I ask you to expound on the agree portion?

I think I had a misconception there, the more I think about it...
Anyways this is how I would approach it:

  1. turn 2 MPPTs off (0% duty cycle)
  2. search MPP of the third PV -> remember current value (mA)
  3. repeat 1. and 2. for all MPPTs
  4. turn all MPPTs off and slowly increase duty cycle of all MPPTs simultaneously
  5. when the remembered current value from 2. is reached for one of the MPPTs, keep that duty cycle
  6. proceed with increasing the duty cycle of the other MPPTs etc. until all of them approximately reached their value from 2.
  7. wait for a certain amount of time or until one of the current values has changed significantly (lighting conditions have changed)

Thank you…

couka:

  1. turn 2 MPPTs off (0% duty cycle)
  2. search MPP of the third PV → remember current value (mA)
  3. repeat 1. and 2. for all MPPTs
  4. turn all MPPTs off and slowly increase duty cycle of all MPPTs simultaneously
  5. when the remembered current value from 2. is reached for one of the MPPTs, keep that duty cycle
  6. proceed with increasing the duty cycle of the other MPPTs etc. until all of them approximately reached their value from 2.
  7. wait for a certain amount of time or until one of the current values has changed significantly (lighting conditions have changed)

I see where you are going here, and I like the logic behind it.

i see one potential issue though,
In step 6, the increasing of the other MPPT’s would cause the current in the one left behind to fall with each increase in the leaders, wouldn’t it?

gathered up a pile of parts,
I’m just waiting for a few more, and it ceases being theory :))

pile of parts.jpg

Project5k:
In step 6, the increasing of the other MPPT’s would cause the current in the one left behind to fall with each increase in the leaders, wouldn’t it?

Yes.

Here’s some pseudo code:

1. Search and remember MPPs

2. Have all PVs reached their MPP?
        No:
            Cycle through all 3 PVs
                PV has reached MPP?
                    No:
                        Increase duty cycle
                    Yes:
                        Do nothing
        Yes:
            Wait for some time
            Go to 1.
    Go to 2.

You just have to find a good metric for when the MPP counts as “reached”
e.g.
MPP is reached when:

  • current is >= 0.95*(the MPP current measured before)
    OR
  • voltage is < 0.95*(the MPP voltage measured before)
    OR
  • duty cycle is 100% already

That way you avoid driving into a too inefficient point in the characteristic U-I-Curve when the MPP cannot be reached anymore or searching forever.

There’s not the ONE correct way to do this, this is just my quick idea to approach this, based on gut feeling :slight_smile:

ok, so i’m trying to get the general flow down, and i realize my notation is horrendus, but i think you can follow my logic…

I need to do some more reading about “looping back untill” in reference to my “pointer” below…

does it look like this operational flow would work? (again, i know its not proper code yet)

Include libraries
Define pins
define variables
	sendtonet = 100 //sets how often the data is stored
<loop>
[
Measure PV voltages
call to pwmfinder for 1, then 2 then 3
]


(pwmfinder)
	if pv(#)v>20v(actual start v YTBD)
		fire MPPT(#) @5%pwm
pointer>	measure MPPT(#)V
		measure MPPT(#)A
		store MPPT(#)V * MPPT(#)A in MPPT(#)Plast
		Increase MPPT(#)pwm by 5%
		measure MPPT(#)V
		measure MPPT(#)A
		store MPPT(#)V * MPPT(#)A in MPPT(#)Pnew
		if MPPT(#)Pnew > MPPT(#)Plast
			Increase MPPT(#)pwm by 5%
		else decrease MPPPT(#)pwm by 5%
// here is where I need to learn more about programming, I wanna run this loop until I get no change,
// I think i wanna do a while ! kinda thing here, i just gotta figure out how to structure it
	else
if (#)==3
		display data
		if cyclecount == sendtonet
			send data to the internet, or sdcard or both
			set cyclecount to 0
			set (#) to 1
			return
		else
		increment cyclecount	
		set (#) to 1
		return
	else
		display data 
		Increment (#)
		return
	else  return

I’m not sure if I should post this here, or if I should start a new thread, so I’m thinking, “keep all like stuff together” and if I’m wrong, please forgive me.

After many youtube tutorials, I have finally come up with enough code that I think will do what I’m trying to do, and that will pass the compiler with no errors.

I’ve been staring at it for so many days in a row now, my logic is just running in circles, so I thought I’d post what I’ve got, and see if anyone has any suggestions, or sees any problems I’ve missed. Considering that this is my first ever try at C++, I’m sure there are better ways to do things, but I’m learning as I go, and this is the best my limited knowledge has put together thus far. at least it’ll compile…

and yes I’ve scavenged some of the code I used from any source I could find, so credit where credit due, its not all my own creation.

intended to be run on Arduino mega 2560
// code attached as it was too long to fit in a single post inside a /code window.

from here, i’m going to start working on the data collection and storage, I’ve got the network interface to figure out, and the real time clock to add in, and then I’m thinking about a conditional shunt load, that would be a PWM’d load, so that when the battery is full, and the panels are under utilized, I could shunt that unused power to something like a water heater preheater.

tripple_MPPT16.ino (9.79 KB)

All in all, I think you created a well structured sketch :slight_smile:

First, some stylistic suggestions (which of course are just my opinion on things):

GLOBAL_CONSTANTS should be named this way, as you did most of the time correctly.
e.g.: mVperAmp1 → MV_PER_AMP_1

I would combine set_pwm_MPPT1() and so on into a single set_MPPT_pwm(mppt_number).

Maybe you want to use constrain() to save a couple of lines.

On the functional side:

I don’t like your MPPT search algorithm, though.

One problem that will probably occur is that after you change the pwm-setting, you don’t give the system any time to settle to the new operating point.

Remember that there are capacitors that need to be charged or discharged to the new level.
If you measure immediately after changing the value, you won’t see the effect of your change.

The characteristic U-I-Curve of a Solar-Panel:

Now let’s take a look at the main “decision” algorithm in the for loop:

if ((pwm1 < PWM_MAX) && (mppt1watts > oldmppt1watts)){
        pwm1++;
        analogWrite(pwm1out, pwm1);
}else if (pwm1 > PWM_MIN){
        pwm1--;
        analogWrite(pwm1out, pwm1);
}else if (mppt1watts == oldmppt1watts){
        i = PWM_UPDATE_COUNT;
}

Imagine the following situation:

  • We are currently on the “left” side of the MPP (See image above)
  1. The current power measurement is lower than last time.
  2. → we decrease the pwm value
  3. → now the power we get is even less
  4. Back to 1

Now in the worst case we just move away from the MPP 25 times and stay there.

Thanks couka,
I’ll work on my CAPS and stuff. I’m still working on my left to right alignment as well…

ok, so have one mppt search alg. but pass it the “channel #” like i did with the read_adc() function? thats gonna take some serious reconfiguring…

I’ve written up a new algorithm, if you would, take a look. I’ll /code in the new alg, and attach the entire sketch, i haven’t modified or taken out the mpp2 and 3 parts yet.

 void set_pwm_MPPT1(){
  if ((batvolts < BATMAXV) && (pv1volts >= PV_MIN_V)){
    pwm1 = constrain(pwm1, 1, 250);    // limits range of pwm
    analogWrite(pwm1out, pwm1);
    digitalWrite(mppt1enable, HIGH);
    
    int i = 0;
    int pwmup = 0;
    int pwmdn = 0;
    float powerbefore = 0;
    float powerup = 0;
    float powerdn = 0;
      for (i=0; i<PWM_UPDATE_COUNT; i++) 
        { 
        read_data1();
        powerbefore = mppt1watts;
        if (pwm1 < PWM_MAX)
          {
          pwmup = (pwm1 + 1);
          pwmdn = (pwm1 - 1);
          analogWrite(pwm1out, pwmup);    
          delayMicroseconds(50);              // pauses for 50 microseconds  
          read_data1();
          powerup = mppt1watts;
          analogWrite(pwm1out, pwmdn);
          delayMicroseconds(50);
          read_data1();
          powerdn = mppt1watts;
          if(powerdn >= powerbefore && powerbefore >= powerup)
            {
            pwm1--;
            analogWrite(pwm1out, pwm1);
            }
          if( powerup >= powerbefore && powerbefore >= powerdn)
            {
            pwm1++;
            analogWrite(pwm1out, pwm1);
            }
          else 
            {
            i = PWM_UPDATE_COUNT;
            analogWrite(pwm1out, pwm1);
            }
          }
        
          
   }  // closes for (i=0; i<PWM_UPDATE_COUNT; i++)
  }  // closes "if ((batvolts"
  else
    {
    digitalWrite(mppt1enable, LOW);
    }
 }  //closes set_pwm_MPPT1

tripple_MPPT19.ino (10.6 KB)

Project5k:
ok, so have one mppt search alg. but pass it the "channel #" like i did with the read_adc() function? thats gonna take some serious reconfiguring....

Yes, but only once.
If you don't do that, everytime you want to make a little change, you need to do it at 3 spots in your code.
Any mistakes here causes bugs that are very hard to find.

I like your new approach better, I think it's worth trying out.

I doubt 50µs is long enough though, but you would need an oscilloscope to be sure.
When I built an MPPT, I went with 10ms for my hardware (200x longer!)

Don't worry to much about the algorithm being to slow or trying out innefficient points in the U-I-curve.

You don't have to continously run it.
Find the MPP and then just let it sit there for a couple of minutes.

couka:
Yes, but only once.
If you don’t do that, everytime you want to make a little change, you need to do it at 3 spots in your code.
Any mistakes here causes bugs that are very hard to find.

roger that. I’ll get to work on that asap, unfortunately I’m so physically limited right now that i can only tolerate sitting in a chair and looking at a screen for very short periods of time.(pinched nerve in back)

couka:
I like your new approach better, I think it’s worth trying out.

I doubt 50µs is long enough though, but you would need an oscilloscope to be sure.
When I built an MPPT, I went with 10ms for my hardware (200x longer!)

ok cool, and in the interest of making things simpler, I think this is the point when i birth a new global variable: AFTER_CHANGE_WAIT_TO_SETTLE_DELAY (well probably something a little shorter, but you get the idea.

I have a decent workbench, O-scope, sig gen, multiple power supplies and so forth. I don’t have a 3.5" floppy drive anymore tho, so getting captured waveforms is a pain. I’m basically stuck taking a picture of the screen of the O-scope.

I tried to test fire the switching portion of the sync. buck as a stand alone circuit last night and fried a couple FET’s, so I’ll have to figure that out… Using a ir2104 driver into a couple IRFZ44N’s.
My first trouble shooting step will be to scope the HO and LO and make sure that they aren’t on at the same time.

Attached is the schematic for my test fired(fried) circuit. the IN pin was fed a 5vp-p square wave from the sig-gen, @31.5kHz. trying to simulate the freq. i plan to use from the Arduino.

edit: i think i blew my 2104 as well, the Lo out is high, and responds to the enable(SD) pin, but i cant get the HO to do anything, both whilst feeding the in pin a 5vpp sqrwave @15kHz, i have more on order, they just aren’t here yet.