#define PWM_CT2_B 3 //OC2B #define Vout A0 #define Vin A1 // 15us = 64khz // 120us = 8 khz #define maxpwm 164 int pwm = maxpwm-1; #define dotrack unsigned long nextmeasTime; unsigned long measInterval = 1000 * 60; // every minute int V_set_out = 200; // 140 = 4V int V_set_in = 300; // 160 = 10V void ct2_init() { pinMode(PWM_CT2_B,OUTPUT); TCCR2A = (1 << COM2B1) | (1 << WGM21) | (1 << WGM20); //fast PWM TCCR2B = (1 << CS20) | (1 << WGM22); // prescaler 0 OCR2A = maxpwm; // 100khz // TOP overflow value (Hz) OCR2B = maxpwm-1; // pwm value } void getactmpp() { int V_meas; OCR2B = maxpwm - 1; // zero load delay(500); V_meas = analogRead(Vin); V_set_in= 0.8 * V_meas; // MPP = 80% of open voltage OCR2B = pwm; delay(100); } void setup() { pinMode(LED_BUILTIN, OUTPUT); pinMode(Vout, INPUT); pinMode(Vin, INPUT); Serial.begin(115200); ct2_init(); #if defined dotrack getactmpp(); #endif } // out 12V -> 3V -> 1:4 // in 18V -> 3V -> 1:6 int V_out, V_in; void loop() { int diff_out; int diff_in; #if defined dotrack if (millis() > nextmeasTime) { getactmpp(); nextmeasTime = measInterval + millis(); } #endif V_in = analogRead(Vin); V_out = analogRead(Vout); diff_out = V_out - V_set_out; diff_in = V_in - V_set_in; // check overvoltage at output if (diff_out > 0) pwm += diff_out/8; // check undervoltage at input else if (diff_in < 0) pwm -= diff_in/8; else pwm += diff_out/16 - diff_in/16; pwm = constrain(pwm,5,maxpwm-5); Serial.print(maxpwm-pwm); Serial.print(", "); Serial.print(V_in); Serial.print(", "); Serial.print(V_out); Serial.println(); OCR2B = pwm; delay(50); }