Arne Schmidt
Balcony power plant
Microinverter
MPP tracker
Free programmable?
Closed source
Own development
Microcontroller
Mircopython
Power electronics
Solar module optimizer
Interactive with mouse and enter
Circuit diagram
On time dTs
Turn-off time (1−d)Ts
Input resistance
max dutycycle dmax=1−UoutUin=1−50V15V=0,7
min dutycycle dmin=1−(UoutUin)⋅(1−dmax)1−(15V30V)⋅(1−0,7)=0,4
Inductor L=ΔiLfsUmaxdmin=2,5A⋅50kHz30V⋅0,4=96μH
Output Capacitor Cout=ΔUoutfsIoutDmax=0,1V⋅50kHz2A⋅0,7=280μF
Voltage divider
Uout=UinR1+R2R20V<Uin/out<50V0V<Uadc<3.3VR1=36kR2=2,2k
Translate function ADC:
Udigital=Uanalog⋅Auflo¨sungADCUsysfrom machine import Pin, ADC adcScaleFac = 3.2 / 2**16 voltDiv = 36 / 2.2 adc1 = ADC(Pin(26)) while(True): voltage = adc1.read_u16() * adcScaleFac * voltDiv print(voltage)
from machine import Pin, ADC adcScaleFac = 3.2 / 2**16 voltDiv = 36 / 2.2 adc1 = ADC(Pin(26)) while(True): voltage = adc1.read_u16() * adcScaleFac * voltDiv print(voltage)
from machine import Pin, ADC adcScaleFac = 3.2 / 2**16 voltDiv = 36 / 2.2 adc1 = ADC(Pin(26)) while(True): voltage = adc1.read_u16() * adcScaleFac * voltDiv print(voltage)
from machine import Pin, ADC adcScaleFac = 3.2 / 2**16 voltDiv = 36 / 2.2 adc1 = ADC(Pin(26)) while(True): voltage = adc1.read_u16() * adcScaleFac * voltDiv print(voltage)
Hall effect sensor
Transferfunction:
Uout=Iin⋅S+Uout,0Afrom machine import ADC, Pin adc = ADC(Pin(27)) sensivity = 0.2 zero_current_output = 3.2 * 0.5 adcScaleFac = 3.2 / 2**16 while(True): voltage = adc.read_u16() * adcScaleFac current = (voltage - zero_current_output) / sensivity print(current)
from machine import ADC, Pin adc = ADC(Pin(27)) sensivity = 0.2 zero_current_output = 3.2 * 0.5 adcScaleFac = 3.2 / 2**16 while(True): voltage = adc.read_u16() * adcScaleFac current = (voltage - zero_current_output) / sensivity print(current)
from machine import ADC, Pin adc = ADC(Pin(27)) sensivity = 0.2 zero_current_output = 3.2 * 0.5 adcScaleFac = 3.2 / 2**16 while(True): voltage = adc.read_u16() * adcScaleFac current = (voltage - zero_current_output) / sensivity print(current)
from machine import ADC, Pin adc = ADC(Pin(27)) sensivity = 0.2 zero_current_output = 3.2 * 0.5 adcScaleFac = 3.2 / 2**16 while(True): voltage = adc.read_u16() * adcScaleFac current = (voltage - zero_current_output) / sensivity print(current)
from machine import ADC, Pin adc = ADC(Pin(27)) sensivity = 0.2 zero_current_output = 3.2 * 0.5 adcScaleFac = 3.2 / 2**16 while(True): voltage = adc.read_u16() * adcScaleFac current = (voltage - zero_current_output) / sensivity print(current)
Problem: noisey signal
Cfilter=2πRfilterfc1 Rfilter=10k fc=75Hz →Cfilter=220nFPythoncode:
class FilterAvg(): def __init__(self, adc: ADC, samples: int): self.buf = 0. self.samples = samples self.adc = adc def calc(self): for sample in range(self.samples): self.buf += self.adc.read_u16() filtered = self.buf/self.samples self.buf = 0. return(filtered)
class FilterAvg(): def __init__(self, adc: ADC, samples: int): self.buf = 0. self.samples = samples self.adc = adc def calc(self): for sample in range(self.samples): self.buf += self.adc.read_u16() filtered = self.buf/self.samples self.buf = 0. return(filtered)
class FilterAvg(): def __init__(self, adc: ADC, samples: int): self.buf = 0. self.samples = samples self.adc = adc def calc(self): for sample in range(self.samples): self.buf += self.adc.read_u16() filtered = self.buf/self.samples self.buf = 0. return(filtered)
Selection criteria
RDS(on)
UDSS
UGSmax
Qgsmax
Pythoncode:
from machine import Pin, PWM pwm = PWM(Pin(6)) pwm.freq(50000) pwm.duty_u16(35000) enable = Pin(7, Pin.OUT) enable.on() def setDutyCycle(self, duty): '''Set mosfet dutycycle for boost converter''' self.duty = int(((100 - duty) / 100) * 65536) self.pwm.duty_u16(self.duty)
from machine import Pin, PWM pwm = PWM(Pin(6)) pwm.freq(50000) pwm.duty_u16(35000) enable = Pin(7, Pin.OUT) enable.on() def setDutyCycle(self, duty): '''Set mosfet dutycycle for boost converter''' self.duty = int(((100 - duty) / 100) * 65536) self.pwm.duty_u16(self.duty)
from machine import Pin, PWM pwm = PWM(Pin(6)) pwm.freq(50000) pwm.duty_u16(35000) enable = Pin(7, Pin.OUT) enable.on() def setDutyCycle(self, duty): '''Set mosfet dutycycle for boost converter''' self.duty = int(((100 - duty) / 100) * 65536) self.pwm.duty_u16(self.duty)
from machine import Pin, PWM pwm = PWM(Pin(6)) pwm.freq(50000) pwm.duty_u16(35000) enable = Pin(7, Pin.OUT) enable.on() def setDutyCycle(self, duty): '''Set mosfet dutycycle for boost converter''' self.duty = int(((100 - duty) / 100) * 65536) self.pwm.duty_u16(self.duty)
Note: poor picture Nyquist–Shannon sampling theorem violated
while(True): device.getfilteredADC() device.calcADCData() power_delta = device.power[0] - power_pre voltage_delta = device.voltage[0] - voltage_pre power_pre = device.power[0] voltage_pre = device.voltage[0] if power_delta >= 0: if voltage_delta > 0: device.vRef -= 1 else: device.vRef += 1 elif power_delta < 0: if voltage_delta > 0: device.vRef += 1 else: device.vRef -= 1 device.vRef = clamp(device.vRef) device.setDutyCycle(device.vRef)
while(True): device.getfilteredADC() device.calcADCData() power_delta = device.power[0] - power_pre voltage_delta = device.voltage[0] - voltage_pre power_pre = device.power[0] voltage_pre = device.voltage[0] if power_delta >= 0: if voltage_delta > 0: device.vRef -= 1 else: device.vRef += 1 elif power_delta < 0: if voltage_delta > 0: device.vRef += 1 else: device.vRef -= 1 device.vRef = clamp(device.vRef) device.setDutyCycle(device.vRef)
while(True): device.getfilteredADC() device.calcADCData() power_delta = device.power[0] - power_pre voltage_delta = device.voltage[0] - voltage_pre power_pre = device.power[0] voltage_pre = device.voltage[0] if power_delta >= 0: if voltage_delta > 0: device.vRef -= 1 else: device.vRef += 1 elif power_delta < 0: if voltage_delta > 0: device.vRef += 1 else: device.vRef -= 1 device.vRef = clamp(device.vRef) device.setDutyCycle(device.vRef)
while(True): device.getfilteredADC() device.calcADCData() power_delta = device.power[0] - power_pre voltage_delta = device.voltage[0] - voltage_pre power_pre = device.power[0] voltage_pre = device.voltage[0] if power_delta >= 0: if voltage_delta > 0: device.vRef -= 1 else: device.vRef += 1 elif power_delta < 0: if voltage_delta > 0: device.vRef += 1 else: device.vRef -= 1 device.vRef = clamp(device.vRef) device.setDutyCycle(device.vRef)
while(True): device.getfilteredADC() device.calcADCData() power_delta = device.power[0] - power_pre voltage_delta = device.voltage[0] - voltage_pre power_pre = device.power[0] voltage_pre = device.voltage[0] if power_delta >= 0: if voltage_delta > 0: device.vRef -= 1 else: device.vRef += 1 elif power_delta < 0: if voltage_delta > 0: device.vRef += 1 else: device.vRef -= 1 device.vRef = clamp(device.vRef) device.setDutyCycle(device.vRef)
Interactive with mouse
power_curve =[] while(True): for duty in range(70): device.setDutyCycle(duty) time.sleep_ms(50) device.getfilteredADC() device.calcADCData() time.sleep_ms(50) power_curve.append(device.power[0]) device.printOut() if device.voltage[0] < 12: print('Abbruch ', device.voltage[0]) break power_max = max(power_curve) duty_max = power_curve.index(power_max) power_curve.clear() time.sleep_ms(500) devive.setDutyCycle(duty_max) print('power_max:{}W duty_max:{}'.format(power_max, duty_max)) time.sleep(10)
power_curve =[] while(True): for duty in range(70): device.setDutyCycle(duty) time.sleep_ms(50) device.getfilteredADC() device.calcADCData() time.sleep_ms(50) power_curve.append(device.power[0]) device.printOut() if device.voltage[0] < 12: print('Abbruch ', device.voltage[0]) break power_max = max(power_curve) duty_max = power_curve.index(power_max) power_curve.clear() time.sleep_ms(500) devive.setDutyCycle(duty_max) print('power_max:{}W duty_max:{}'.format(power_max, duty_max)) time.sleep(10)
power_curve =[] while(True): for duty in range(70): device.setDutyCycle(duty) time.sleep_ms(50) device.getfilteredADC() device.calcADCData() time.sleep_ms(50) power_curve.append(device.power[0]) device.printOut() if device.voltage[0] < 12: print('Abbruch ', device.voltage[0]) break power_max = max(power_curve) duty_max = power_curve.index(power_max) power_curve.clear() time.sleep_ms(500) devive.setDutyCycle(duty_max) print('power_max:{}W duty_max:{}'.format(power_max, duty_max)) time.sleep(10)
power_curve =[] while(True): for duty in range(70): device.setDutyCycle(duty) time.sleep_ms(50) device.getfilteredADC() device.calcADCData() time.sleep_ms(50) power_curve.append(device.power[0]) device.printOut() if device.voltage[0] < 12: print('Abbruch ', device.voltage[0]) break power_max = max(power_curve) duty_max = power_curve.index(power_max) power_curve.clear() time.sleep_ms(500) devive.setDutyCycle(duty_max) print('power_max:{}W duty_max:{}'.format(power_max, duty_max)) time.sleep(10)
power_curve =[] while(True): for duty in range(70): device.setDutyCycle(duty) time.sleep_ms(50) device.getfilteredADC() device.calcADCData() time.sleep_ms(50) power_curve.append(device.power[0]) device.printOut() if device.voltage[0] < 12: print('Abbruch ', device.voltage[0]) break power_max = max(power_curve) duty_max = power_curve.index(power_max) power_curve.clear() time.sleep_ms(500) devive.setDutyCycle(duty_max) print('power_max:{}W duty_max:{}'.format(power_max, duty_max)) time.sleep(10)
power_curve =[] while(True): for duty in range(70): device.setDutyCycle(duty) time.sleep_ms(50) device.getfilteredADC() device.calcADCData() time.sleep_ms(50) power_curve.append(device.power[0]) device.printOut() if device.voltage[0] < 12: print('Abbruch ', device.voltage[0]) break power_max = max(power_curve) duty_max = power_curve.index(power_max) power_curve.clear() time.sleep_ms(500) devive.setDutyCycle(duty_max) print('power_max:{}W duty_max:{}'.format(power_max, duty_max)) time.sleep(10)
power_curve =[] while(True): for duty in range(70): device.setDutyCycle(duty) time.sleep_ms(50) device.getfilteredADC() device.calcADCData() time.sleep_ms(50) power_curve.append(device.power[0]) device.printOut() if device.voltage[0] < 12: print('Abbruch ', device.voltage[0]) break power_max = max(power_curve) duty_max = power_curve.index(power_max) power_curve.clear() time.sleep_ms(500) devive.setDutyCycle(duty_max) print('power_max:{}W duty_max:{}'.format(power_max, duty_max)) time.sleep(10)
power_curve =[] while(True): for duty in range(70): device.setDutyCycle(duty) time.sleep_ms(50) device.getfilteredADC() device.calcADCData() time.sleep_ms(50) power_curve.append(device.power[0]) device.printOut() if device.voltage[0] < 12: print('Abbruch ', device.voltage[0]) break power_max = max(power_curve) duty_max = power_curve.index(power_max) power_curve.clear() time.sleep_ms(500) devive.setDutyCycle(duty_max) print('power_max:{}W duty_max:{}'.format(power_max, duty_max)) time.sleep(10)
Interactive with mouse
shaded
shaded
not shaded
shaded
not shaded
shaded