I understand that your MPPT function "fcn" behaves differently depending on whether you use "abs()" in the step size formula, leading to erratic behavior in duty cycle. You can consider the below suggestions to eliminate this:
Step Size Instability
- The formula "step = N * abs(di/dv + I/V)" can become large when dv is very small, since di/dv shoots up.
- To eliminate this you can limit the step to prevent huge jumps as given below:
step = min(max(N * abs(di/dv + I/V), 0.000001), 0.00005);
Handling dv == 0 Condition
- If dv is zero or extremely small, you risk division by zero or no updates at all.
You can add a tiny offset so dv never stays at zero like as shown below:
Duty Cycle Adjustment is Too Reactive
- The simple “if change > cond then d = d - step, else d = d + step” responds too quickly to minor fluctuations.
- To fix this you can smooth out changes using a factor alpha (closer to 1 = slower change):
d = alpha * d + (1 - alpha) * (d - step);
d = alpha * d + (1 - alpha) * (d + step);
This softens how fast the duty cycle moves, avoiding wild swings.
By limiting the step size, handling dv near zero, and smoothing duty cycle changes, your MPPT loop will stay more stable and settle around the maximum power point without large spikes.
You can also refer to below filexchnage models on Perturb and Observe (P&O) MPPT: