Nope - not even close :( but thanks for trying - I will try to ask more concisely
I wanted soft start to count up to 1000/1001 not 100/101
I tried to get soft start to begin from count 100 up to 1000/1001 (saving 100 steps low down)
So I changed SST value from SST = 0 to SST = 100 in the 5th line below headed by ** note: I thought most //comments of 250/251 should have been changed to 1000/1001 ??
I never touched anything else.
The code below started the inverter perfectly no grunt whatsoever, best start ever repeatedly.
But changing back to SST = 0 grunted again.
Obviously it seems my setting to 100 changed something for the better - but what ?
Also making SST = 200 appeared to make D5 high the second I set D8 to go - from the code I couldn't see why.
void init_vars() // called prior to setting oen = 1, as well as from setup() { ICR1 = PPWM; lv_stopped = 0; **sst = 0; // slow start counter 0 - 251 v1low = 1; // half wave output flag, 0 or 1 pcount = 0; // counter for sine wave lookup table uf = 0; // set to 1 to enable AC output voltage feedback code to execute pwr = 0.0; // PWM duty cycle analog, 0.0 to 1.0 vpwr= 0; // integer equivalent of pwr, 0 to PPWM dbounce = 0; // debounce counter for input switch kp = 0.1; // set up PID for AC output voltage control ki = 0.0; kd = 0.01; errSum = 0.0; // initialise PID lastErr = 0.0; int_f = 0; //used in AC sync, one shot per 50Hz if (p_lock == 1) { // nothing to do so far } else { p_lock = 0; // phase lock flag = 0 = NOT locked pcount_acc = 0; // fractional integer math. Each PWM, pcount_delta is added to pcount_acc and divided by 1024 pcount_delta = 1024; // in effect we are getting an addition of 1. But pcount_delta can be modified, a little bigger or smaller.. old_phase_error = 0; // used in PID, to obtain derivative } cbi(PORTD,4); }
void do_pid() { double timeChange = 0.01; // always called at 100Hz, so dT will be 10msec.. error = Setpoint - Input; errSum += (error * timeChange); dErr = (error - lastErr) / timeChange; Output = kp * error + ki * errSum + kd * dErr; lastErr = error; }
void loop() { float ch0;
// sample channel.. // In the past, I low pass filtered this. not now, no need thanks to active LP filter on Vfb ac_output = (float)analogRead(ADC_OUT) / 1024.0; // scale 0 - 5V to 0.0 to 1.0
if(uf == 1 ) // this will execute at 100Hz { // it runs at near zero volt crossing of AC output uf=0; ac_setpoint = 0.55; // for same Vfb as EG8010. change AC output voltage via Vfb voltage divider trimpot if (oen == 1) sst++; // slow start. If output is enabled, keep starting up. sst = output pwm% or approx. voltage. if (sst > 1001) sst = 1001; // stop increasing when sst has got to the end of slow start. when = 1001, this enables PID. See below.. if (oen == 0) sst--; // if stopping, slow stop if (sst <= 0) // once fully stopped, no more changes to sst needed { sst = 0; cbi(PORTD,5); // pull IR2184 shutdown LOW to disable gate drive output } else sbi(PORTD,5); // pull it HIGH, to enable output
if(sst > 0 && sst < 1000) // slow start timer counts to 250 with gentle ramp up, then switches over to PID control. { // sst can increase or decrease, giving the slow start and slow stop. if (oen == 1) // slow stop? I think of it as de-gauss { if(ac_output < ac_setpoint) pwr += 1.0/1000.0; // bang-bang control, should AC output reach setpoint prior to PID. else // During slow start need to ensure output is tracking setpoint pwr -= 1.0/1000.0; // should output get close enough to matter. } else pwr -= 1.0 /1000.0; // this will execute in slow stop }
if (sst == 1001) // once sst = 1001, run PID. the above bang-bang control will NOT have executed, because sst = 251 { Setpoint = ac_setpoint; Input = ac_output; do_pid(); pwr = pwr + Output; }
Would be great to have you as a fly on the wall, we would probably lick this in 15 minutes if we were in the same room......and there was no wine bottle opened.... Edited 2022-07-10 22:39 by wiseguy