/* * mppt.c * * Created on: Jun 11, 2025 * Author: janik */ #include "mppt.h" #include // for fabsf void MPPT_IncCond_Init(MPPTController *mppt, float initial_iref, float step, float iref_min, float iref_max, float dv_min) { mppt->last_vin = 0.0f; mppt->last_iin = 0.0f; mppt->iref = initial_iref; mppt->step = step; mppt->iref_min = iref_min; mppt->iref_max = iref_max; mppt->dv_min = dv_min; mppt->deadband = 0.005f; } float MPPT_IncCond_Update(MPPTController *mppt, float vin, float iin) { float dv = vin - mppt->last_vin; float di = iin - mppt->last_iin; // Skip if input voltage is essentially zero if (vin < 1e-2f) return mppt->iref; // Suppress update if both dv and di are below noise floor if (fabsf(dv) < mppt->dv_min && fabsf(di) < mppt->dv_min) return mppt->iref; /* dP = vin*di + iin*dv (avoids dv division, works even when dv is small) */ float dp = vin * di + iin * dv; float p = vin * iin; /* current power (mV*mA = nW scale) */ /* Relative deadband: |dP| < 0.5% of P => near MPP */ if (p > 1e3f && fabsf(dp) < mppt->deadband * fabsf(p)) { // At or near MPP — don't step } else if (dp > 0) { mppt->iref -= mppt->step; } else { mppt->iref += mppt->step; } // Clamp if (mppt->iref > mppt->iref_max) mppt->iref = mppt->iref_max; if (mppt->iref < mppt->iref_min) mppt->iref = mppt->iref_min; // Save state mppt->last_vin = vin; mppt->last_iin = iin; return mppt->iref; }