AdvancedPID.h giving me weird spikes

Howdy friends,

I got this linear actuator, and I had good experience with AdvancedPID.h

However I'm getting weird spikes on the output for no reason.
They only occur downwards, meaning when I change direction.
I tried 2 forces and 2PIDs one for each direction and it was worse...

The documentation on the library is very basic....
Any help would be appreciated.

here is the implementation on a GIGA R1

  if (!ActMode) {                            //only compensate in active mo
    ACTUATOR_PID.setTunings(1, .3, 0.1, 0);  // Kp, Ki Kd and Clamping
                                             //ACTUATOR_PID.setDerivativeFilter(0.3);//Enable derivative filter (0.8 = strong smoothing, 1.0 = OFF)

    // ACTUATOR_PID.setOutputRampRate(100.0); // Protect actuator: Output can change max 100 units per second
    DeadBand_int = 6;

    int Input = PotnActu - (PotnChair - 500);
    Error_M1 = M1_target_pos - PotnChair;
ACTUATOR_PID.setMode(MODE_AUTO);
      ACTUATOR_PID.setControllerDirection(DIR_DIRECT);
      FORCE = ACTUATOR_PID.run(PotnChair, M1_target_pos);  //input and Setpoint
    if (Error_M1 >= DeadBand_int and PotnActu < 470 ) 
    {  //in this case the plunger is pushing out
      analogWrite(PUSH_PWM, FORCE);
      analogWrite(PULL_PWM, 0);
    PID_State=1;

    } else if (Error_M1 <= -(DeadBand_int) and PotnActu > 20) 
    {  //Pulling in
      analogWrite(PUSH_PWM, 0);
      analogWrite(PULL_PWM, abs(FORCE));
   PID_State=2;
    }


    else  // This is the dead band between -4 to +4
    {
     PID_State=0;
      ACTUATOR_PID.reset();               // 1. Stops the internal PID calculations
      ACTUATOR_PID.setMode(MODE_MANUAL);  // 1. Stops the internal PID calculations

     FORCE = 0;  //
      analogWrite(PULL_PWM, 0);
      analogWrite(PUSH_PWM, 0);

    }

  }  // end of if !act mode

I got rid of the Derivative (Kd=0) and the problem went away,
Please contribute if you have more ideas.

I'd bet that the mode/deadband changes would cause issues, but it would be hard to tell much without the rest of the code with the timing and mode-switching details.

And unsubstantiated WAG: if you need deadband behavior, maybe it might work better to do a deadband-like preprocessing on Input.

A noisy input signal can cause issues , especially with the derivative term .

I think that the .reset() and .setMode(...) calls around the deadband edges could easily cause noise in the internals of the algorithm. They set the dT tiny, and lastInput=0.

...and a large, positive dInput over a tiny dT would explain a large negative spike due to the derivative term.

If you want a well-documented PID, use the regular:

And if you want more some advanced features, consider this small patch that exposes some internals to userspace so you can monitor and adjust/manage the integral term/windup yourself:

Worth a general look at PID control , its limitations and do on with Mr Google .