Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 66 additions & 22 deletions mppTracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,10 @@ def weAreDone(sm):
# setup complete. the real mppTracker begins here

# for curve exploration
dAngleMax = 25 #[degrees] (plus and minus)
dAngleMax = dAngleMaxLimit = 25 #[degrees] (plus and minus)
dAngleMinLimit = 3
scannedPointsMinLimit = 5
previousScanStartDirection = -1

while True:
exploring = 0
Expand All @@ -354,7 +357,9 @@ def weAreDone(sm):
if t_run > args.t_total:
weAreDone(sm)
toc = time.time() - tic

myPrint("Stabilized power at Mpp:", file=sys.stderr, flush=True)
myPrint(i*v*1000,"mW @",v,"V", file=sys.stderr, flush=True)

myPrint("Exploring for new Mpp...", file=sys.stderr, flush=True)
exploring = 1
i_explore = numpy.array(i)
Expand All @@ -363,10 +368,24 @@ def weAreDone(sm):
dAngle = 0
angleMpp = numpy.rad2deg(numpy.arctan(i/v*Voc/Isc))
v_set = Vmpp
switched = False
myPrint("Walking up in voltage...", file=sys.stderr, flush=True)
while dAngle < dAngleMax:
v_set = v_set + dV
scanDirection = previousScanStartDirection = previousScanStartDirection * -1
myPrint("Walking {direction} in voltage for starting scan...".format(direction="up" if scanDirection == 1 else "down"), file=sys.stderr, flush=True)
while -dAngleMax < dAngle < dAngleMax:
v_set = v_set + dV * scanDirection
sm.write(':source:voltage {0:0.4f}'.format(v_set))
[v, i, tx, status] = sm.query_ascii_values('READ?')
i = i*polarity
t_run = tx-t0
myPrint('{:1d},{:.4e},{:.4e},{:.4e}'.format(exploring,t_run,v,i), flush=True)
if t_run > args.t_total:
weAreDone(sm)
dAngle = numpy.rad2deg(numpy.arctan(i/v*Voc/Isc)) - angleMpp
myPrint("{limit} exploration voltage limit reached.".format(limit="Upper" if scanDirection == 1 else "Lower"), file=sys.stderr, flush=True)
scanDirection = scanDirection * -1
scannedPoints = 0
myPrint("Scanning walking {direction} in voltage...".format(direction="up" if scanDirection == 1 else "down"), file=sys.stderr, flush=True)
while scannedPoints < scannedPointsMinLimit or -dAngleMax < dAngle < dAngleMax:
v_set = v_set + dV * scanDirection
sm.write(':source:voltage {0:0.4f}'.format(v_set))
[v, i, tx, status] = sm.query_ascii_values('READ?')
i = i*polarity
Expand All @@ -377,35 +396,60 @@ def weAreDone(sm):
i_explore = numpy.append(i_explore, i)
v_explore = numpy.append(v_explore, v)
dAngle = numpy.rad2deg(numpy.arctan(i/v*Voc/Isc)) - angleMpp
if (dAngle < -dAngleMax) and not switched:
myPrint("Upper exploration voltage limit reached.", file=sys.stderr, flush=True)
myPrint("Walking down in voltage...", file=sys.stderr, flush=True)
switched = True
dV = dV * -1 # switch our voltage walking direction (only once)

myPrint("Lower exploration voltage limit reached.", file=sys.stderr, flush=True)

scannedPoints += 1
# find the powers for the values we just explored
p_explore = v_explore*i_explore
maxIndexFirstScan = numpy.argmax(p_explore)
VmppFirstScan = v_explore[maxIndexFirstScan]
ImppFirstScan = i_explore[maxIndexFirstScan]
angleMppFirstScan = numpy.rad2deg(numpy.arctan(ImppFirstScan/VmppFirstScan*Voc/Isc))
myPrint("{limit} exploration voltage limit reached.".format(limit="Upper" if scanDirection == 1 else "Lower"), file=sys.stderr, flush=True)
myPrint("Voltage for Mpp in {direction} scan found at {:.4e} V".format(VmppFirstScan, direction="forward" if scanDirection == 1 else "reverse"), file=sys.stderr, flush=True)
i_explore = numpy.array(i)
v_explore = numpy.array(v)
scannedPoints = 0
scanDirection = scanDirection * -1
myPrint("Scanning walking {direction} in voltage...".format(direction="up" if scanDirection == 1 else "down"), file=sys.stderr, flush=True)
while scannedPoints < scannedPointsMinLimit or -dAngleMax < dAngle < dAngleMax:
v_set = v_set + dV * scanDirection
sm.write(':source:voltage {0:0.4f}'.format(v_set))
[v, i, tx, status] = sm.query_ascii_values('READ?')
i = i*polarity
t_run = tx-t0
myPrint('{:1d},{:.4e},{:.4e},{:.4e}'.format(exploring,t_run,v,i), flush=True)
if t_run > args.t_total:
weAreDone(sm)
i_explore = numpy.append(i_explore, i)
v_explore = numpy.append(v_explore, v)
dAngle = numpy.rad2deg(numpy.arctan(i/v*Voc/Isc)) - angleMpp
scannedPoints += 1
# find the powers for the values we just explored
p_explore = v_explore*i_explore
maxIndex = numpy.argmax(p_explore)
Vmpp = v_explore[maxIndex]
maxIndexSecondScan = numpy.argmax(p_explore)
VmppSecondScan = v_explore[maxIndexSecondScan]
ImppSecondScan = i_explore[maxIndexSecondScan]
angleMppSecondScan = numpy.rad2deg(numpy.arctan(ImppSecondScan/VmppSecondScan*Voc/Isc))
myPrint("{limit} exploration voltage limit reached.".format(limit="Upper" if scanDirection == 1 else "Lower"), file=sys.stderr, flush=True)
myPrint("Voltage for Mpp in {direction} scan found at {:.4e} V".format(VmppSecondScan, direction="forward" if scanDirection == 1 else "reverse"), file=sys.stderr, flush=True)

myPrint("New Mpp found:", file=sys.stderr, flush=True)
myPrint(p_explore[maxIndex]*1000,"mW @",Vmpp,"V", file=sys.stderr, flush=True)
Vmpp = (VmppFirstScan + VmppSecondScan) / 2
myPrint("New Mpp found at {:.4e} V:".format(Vmpp), file=sys.stderr, flush=True)

mppAngleVariation = max(abs(angleMpp - angleMppFirstScan), abs(angleMpp - angleMppSecondScan))
dAngleMax = min(mppAngleVariation + dAngleMinLimit, dAngleMaxLimit)
# now let's walk back to our new Vmpp
dV = dV * -1
v_set = v_set + dV
scanDirection = scanDirection * -1
v_set = v_set + dV * scanDirection
myPrint("Walking back to Mpp...", file=sys.stderr, flush=True)
while v_set < Vmpp:
while not Vmpp - dV <= v_set <= Vmpp + dV:
sm.write(':source:voltage {0:0.4f}'.format(v_set))
[v, i, tx, status] = sm.query_ascii_values('READ?')
i = i*polarity
t_run = tx-t0
myPrint('{:1d},{:.4e},{:.4e},{:.4e}'.format(exploring,t_run,v,i), flush=True)
if t_run > args.t_total:
weAreDone(sm)
v_set = v_set + dV
v_set = v_set + dV * scanDirection
sm.write(':source:voltage {0:0.4f}'.format(Vmpp))
myPrint("Mpp reached.", file=sys.stderr, flush=True)