PID and Servos

Greetings!
So, I have a quick problem, which I searched the forums for but to no avail.

I have a temperature sensor that I am reading, and based on the input / setpoint error, I would like to command a servo motor to open/close. This would be a closed feedback loop since opening and closing the valve would effectively control the temp.

My holdup here is that I have a servo that is looking for a (0, 90 ,180) signal (closed, hold, open) respectively. And I have the output from the myPID which is (0, 255) by default. I know that using the SetOutputLimits() function I should be able to change my output scaling, but it seems to only be able to go one way when I try to fuss with that.

I was thinking I could set the output limits to -90 and 90, and then map those values to 0 and 180. But I still feel like that might be an inelegant solution.

Does anyone have a pointer or an example I can look at that might enlighten me as to how to accomplish this?

Where exactly did you get the PID library?

map() is a good choice. The PID doesn't really care what you do with the output; it doesn't need to know how many degrees the valve has turned.

Since your servo takes a value from 0 to 180 I would set those as the PID Output limits. Then the PID Output can go directly to the servo. For more precision control you could use servo.writeMicroseconds() which generally takes values from 1000 (0°) to 2000 (180°). In that case I would use 1000 and 2000 as my PID Output limits.

Since you are running a device where the higher Output causes a LOWER Input, set the PID for REVERSE instead of DIRECT.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :slight_smile:

Good morning all!
Thank you for replying,

MorganS:
Where exactly did you get the PID library?

This is the library I am using.

MorganS:
map() is a good choice. The PID doesn’t really care what you do with the output; it doesn’t need to know how many degrees the valve has turned.

Thats what I was thinking originally, but I havent yet figured out how to tell the PID loop that 90 is the middle.

johnwasser:
Since your servo takes a value from 0 to 180 I would set those as the PID Output limits. Then the PID Output can go directly to the servo. For more precision control you could use servo.writeMicroseconds() which generally takes values from 1000 (0°) to 2000 (180°). In that case I would use 1000 and 2000 as my PID Output limits.

Since you are running a device where the higher Output causes a LOWER Input, set the PID for REVERSE instead of DIRECT.

I can try the (0 - 180) range and let you know.
Wouldnt that just invert the control method and then leave me with the same problem of the zero being in the middle but it going in reverse? Just curious if maybe I am not understanding this correctly.

TomGeorge:
Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks… Tom… :slight_smile:

Hi Tom, thanks for the welcome.
I didnt post my code, because I don’t have any code to post yet. I am in the “Playing around” phase where its mostly flowcharts and trying to figure an overall control scheme. Most of my code is just snippets of the arduino examples. I wanted to ask what the best practice for this kind of thing was, before I spent a weekend going down the wrong path.

Also, no circuit yet, just some sketches in block diagram that show the various components. No reason to waste time drawing circuits I may never use.

I will post both when I have both.

Thanks everyone for your warm welcome.

Fedgar:
Thats what I was thinking originally, but I havent yet figured out how to tell the PID loop that 90 is the middle.

There's no "middle" for PID. Either the process is in control or it isn't. If it's in control then the input is somewhere between the end stops and the output is acceptably close to the value you want. If it's not in control then the input has hit its end stop and the computer can no longer bring the output to where you asked it to be.

Think of the accelerator pedal in your car. You never care if it's in the middle or not, do you? Either the car is going fast enough or you've got your foot all the way to the floor and wishing it would go faster.

Fedgar:
I can try the (0 - 180) range and let you know.
Wouldn't that just invert the control method and then leave me with the same problem of the zero being in the middle but it going in reverse? Just curious if maybe I am not understanding this correctly.

I don't know what you mean by "invert the control method". The PID compares the Input (current value) to the Setpoint (the value you want) and adjusts the Output in the direction that will cause Input to get closer to Setpoint. With the DIRECT mode it increases Output to increase Input (like a heater). With the REVERSE mode it increases Output to decrease Input (like a refrigerator).
Input and Setpoint have to be in the same units (degrees, RPM, KPH...). Output is an arbitrary value between two limits that is the control signal into the system. In the case of the Servo library the value is 0 to 180 or 1000 to 2000.
The PID will drive the Output in the right direction and when Input gets very close to Setpoint the Output value will be at that right setting to keep it there. If that value is near the middle then that is where the PID will settle down.