I have implemented PID control of a generator governor to maintain a constant RPM using an Arduino Uno. It works pretty well, but there is a tradeoff between stabilty and response time. Using PID values that allow it to respond without oscillation is also about half as fast as the old mechanical governor.

I came up with a plan to use a CT to sense the AC amps and have the Uno rapid the throttle servo to a known value determined manually. Either using a lookup table or an interpolation algorithm, I haven't yet checked the linearity of the amps vs. throttle angle. The idea is to use a table (or interpolation) to get the governor close, and then let the PID fine tune it.

My hangup is that I'm not sure how to switch between lookup control and PID control as needed.


analogRead(AMPS); myservo.write(table_Val); somehow_switch_to_PID; myservo.write(PID_value);

  • You can use an if condition, checking if you reached the target RPM within the fine tune range.
    – chrisl
    Commented May 23, 2019 at 5:11
  • If I use some method of getting the RPMs close, won't the PID just swing to one extreme or the other trying to adjust the value with no success because the "get close" operation is in control? I mean, the PID is looking at the RPMs and giving an output but that output is being ignored because another operation has servo control. By the time PID is in control, shouldn't the output have gone full tilt trying to make a change, and now will just slam the servo to that erroneous value? Commented May 23, 2019 at 11:04

1 Answer 1


the PID is looking at the RPMs and giving an output but that output is being ignored because another operation has servo control.

PID is not something, that happens somewhere in the background without you having any control. On the Arduino it is done in software, so you can totally control it. Why should you run a PID calculation, if you don't use the value? The solution is to simply only do the appropriate calculation depending on the RPM at any given time. No need to do 2 calculations at the same time. I will form that into a code with explanations:

You have 2 ways of calculating the needed servo values:

  1. Your "getting close" method
  2. The PID method

To switch between those methods you need to make a decision based on the RPM. If the RPM is outside of your interval, the first method is used. If it is inside, the second will be used. Decision/conditionals are often wrote with an if else statement. Look at this (not tested) code snippet:

int target_rpm = 700;
int half_interval = 20;
int current_servo_pos = 0;

void loop(){
    current_rpm = analogRead(AMPS);

    if(current_rpm > target_rpm - half_interval && current_rpm < target_rpm + half_interval){
        // Do the PID calculation here and save the result in current_servo_pos
    } else {
        // Do the "getting close" calculation here and save the result in current_servo_pos


I didn't go into detail about the actual calculation, since that is not important here. You may use any calculation, that you like there. For PID you can find libraries, that do the calculation for you, for example here at github.

The code will simply decide based on the RPM, what calculation should be used. If the RPM goes out of the interval for some reason (maybe is was disturbed and lost some speed), it will automatically use the "getting close" method until it is again inside of the interval.

Note: The numbers, that I used here, are arbitrary. You should change them to what ever you need.

  • Thanks again Chris! I haven't been successful using the PID outside of void loop(). If I place the PID parameters anywhere else, it doesn't respond. I'll get the code currently in use later today. But that's why I asked about the PID calc already having an output. I can write the PID output into anything I want in any function, but trying to call the PID outside of void loop() has been fruitless. Commented May 23, 2019 at 11:47
  • 2
    Yes, please add your code to your question. That way I can add more to my answer to help you with that.
    – chrisl
    Commented May 23, 2019 at 12:06

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.