I have a control problem with saturation. It is nearly linear in the non-saturation zone.

Problem: https://i.sstatic.net/9NqrK.jpg

Occasionally I measure huge error spikes. They must not disturb my control routine. I want to get down to 50% (of the reference voltage) in my output voltage. In the moment I do this by stepping one step up or down depending on whether the output is bigger or smaller than 50%. This leads to oscillations.

Oscillations: https://i.sstatic.net/DytFy.jpg

If I wait some bigger time before measuring the output voltage and then adjust the control voltage the oscillations go down. But this also extends my start-up time which is a problem as I don't know which control voltage value delivers 50% output voltage. I have to search quite a time.

How can I control the oscillations without slowing down my sampling rate?

In PID control it is said that the stationary error is reduced to zero if an integral part is added but how can I do something similar here?

Otherwise what would your approach to control this thing be?

  • 1
    \$\begingroup\$ Decrease the saturated zones, increase the resulution in the near-linear zone. In other words change the circuit so a large part on left and right of the first image is snipped. And do it in such a way that you increase the resolution of the steps, decrease the stepsize. \$\endgroup\$
    – jippie
    Commented Jan 6, 2013 at 23:42
  • \$\begingroup\$ Not so easy as the circuit is very temperature dependent and the linear part can move quite a bit. \$\endgroup\$
    – Say
    Commented Jan 7, 2013 at 8:26
  • \$\begingroup\$ Integral control is more useful for constant tracking error, like you might see tracking a ramp, than constant offset,which is easier to deal with by proportional gain. Once you have an I term, you need to consider if integrator windup will hurt you. \$\endgroup\$ Commented Jan 7, 2013 at 11:52
  • \$\begingroup\$ Integrator windup would probably hurt me. \$\endgroup\$
    – Say
    Commented Jan 7, 2013 at 13:23
  • \$\begingroup\$ Maybe you could try a three-sample median filter on your error term to remove the spikes before they get to the control circuitry. \$\endgroup\$
    – markrages
    Commented Feb 6, 2013 at 17:38

1 Answer 1


If you have huge transient error spikes, then you need a derivative part (i.e the D in PID) to handle these.

A simple PID system is not hard to write in code, it's the tuning that's the difficult part - you need to know roughly. The integral part will handle the DC offset, the proportional part the gain, and the derivative the reaction to change.

Here's some code I wrote for a temperature controlled etching tank I made with a PIC16F and a DS18B20 temp sensor ages ago (it used some nichrome wire driven via PWM wrapped round a couple of ceramic tiles for the heating element, so it had a large thermal capacity)
The results, once tuned, were an overshoot a of less than 2 degrees on power up, and a variation of less than a degree or so thereafter. It's very old code for a one off project thrown together quickly, so it can probably be improved a fair bit.
I found this document "PID without a PHD" quite helpful. Also, Matlab, Scilab or Octave can be used to simulate and tune PID systems.

/** Control variables **/

int DEADBAND = 0;   // Range where no change will be made

// PID gain values 
double Kp = 10;
double Ki = 0.02;
double Kd = 5;

// Accumulator variable for Integral calculation
double I_acc = 0;

// Returns out the proportional term
double get_prop(int error)
    double p;
    p = (Kp * error); 
    return p;

// Returns the integral term
double get_int(int error)
    double i;
    I_acc += (error);

    i = (double)(Ki * I_acc);
    if(i > 1000) i = 1000;
    if(i < 0) i = 0;
    return i;

// Returns the derivative term
double get_deriv(int error)
    double d;
    static int prev_error;
    d = (Kd * (error - prev_error));
    prev_error = error;
    return d;

double get_pid(int error)
    double result;
    double p, i, d;

    p = get_prop(error);
    i = get_int(error);
    d = get_deriv(error);
    result = p + i + d;
    return result;
  • \$\begingroup\$ I tried it with a P controller and I did not get it stable but perhaps I did something wrong. \$\endgroup\$
    – Say
    Commented Jan 7, 2013 at 8:32
  • \$\begingroup\$ Have you simply tried turning down your gain? \$\endgroup\$ Commented Jan 7, 2013 at 15:55
  • \$\begingroup\$ I tried it with one but perhaps that's too much. The other thing is that the error is constant over a long time so a controller cannot derive the point to settle. I mean you put the error into a P-controller. You weight it and output the control voltage. Can this converge with huge saturation effects? \$\endgroup\$
    – Say
    Commented Jan 7, 2013 at 21:24
  • \$\begingroup\$ I would try using a PI or PID controller and experiment a bit - just using a P controller is only really suitable for pretty basic/inherently stable systems where you don't mind a bit of fluctuation around the set point. It would help to know some more about your system/circuit also. \$\endgroup\$
    – Oli Glaser
    Commented Jan 7, 2013 at 23:22
  • \$\begingroup\$ The cycle duration is 80 ms. What do you want to know about the circuit? I do not know that much about it but I answer if I can. \$\endgroup\$
    – Say
    Commented Jan 9, 2013 at 19:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.