Nano Power Inverter - Roll Your Own Style


Author Message
wiseguy

Guru

Joined: 21/06/2018
Location: Australia
Posts: 1156
Posted: 12:29pm 10 Jul 2022      

  poida said  aw Jeez Wiseguy. you broke it.
did I answer what you needed?

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