Git Product home page Git Product logo

ardupid's Introduction

ArduPID

GitHub version arduino-library-badge

PID library for Arduinos with greater accuracy than the legacy Arduino PID library.

Why Use PID?

PID stands for Proportional, Integral, and Derivative and is a simple type of controller. PID controllers can provide stable control of nearly any system such as the speed of a motor, position of a servo, speed of a car (cruise control), and much more.

How Does it Work?

See the explanation video here

How to Tune a PID:

See here

How to Use the Library:

First import the library, instantiate an ArduPID class, and create 6 doubles:

  • Setpoint
  • Input
  • Output
  • P Gain
  • I Gain
  • D Gain
#include "ArduPID.h"

ArduPID myController;

double setpoint = 512;
double input;
double output;
double p = 1;
double i = 0;
double d = 0;

Next, within the setup() function, initialize the controller with the references to the input, output, and setpoint variables. Also pass the values of the PID gains. After initializing the controller within setup(), you can change the settings/configuration of the controller.

void setup()
{
  Serial.begin(115200);
  myController.begin(&input, &output, &setpoint, p, i, d);
  
  // ADD MORE CONFIGURATION COMMANDS HERE <--------------------
}

Here are the different examples of configuration commands available via the library:

  • reverse()
    • Reverse direction of output
  • setSampleTime(const unsigned int& _minSamplePeriodMs)
    • Will ensure at least _minSamplePeriodMs have past between successful compute() calls - this function is not necessary, but is included for convenience
  • setOutputLimits(const double& min, const double& max)
    • Clip output to values to min and max
  • setBias(const double& _bias)
    • Output will have a constant offset of _bias, usually used in conjunction with setOutputLimits()
  • setWindUpLimits(const double& min, const double& max)
  • start()
    • Enable/turns on the controller
  • reset()
    • Used for resetting the I and D terms - only use this if you know what you're doing
  • stop()
    • Disable/turn off the PID controller (compute() will not do anything until start() is called)

Within the loop(), update the input variable via your sensor and then call compute(). The output variable will then be automatically updated and you can use that updated value to send an updated command to your actuator. You can also use the debug() command to print various status information about your controller to the serial plottor/monitor:

void loop()
{
  input = analogRead(A0); // Replace with sensor feedback

  myController.compute();
  myController.debug(&Serial, "myController", PRINT_INPUT    | // Can include or comment out any of these terms to print
                                              PRINT_OUTPUT   | // in the Serial plotter
                                              PRINT_SETPOINT |
                                              PRINT_BIAS     |
                                              PRINT_P        |
                                              PRINT_I        |
                                              PRINT_D);
  
  analogWrite(3, output); // Replace with plant control signal
}

ardupid's People

Contributors

dinomesina avatar ipsod avatar powerbroker2 avatar ptapping avatar shiukaheng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ardupid's Issues

Information on Parameters

Hello - Thanks for this library. I am working on a PID controller for glass kiln(s) -- annealing, fusing, etc. I have a rig set up with a TC and hot glue gun to test. I am down the rabbit hole of figuring out the Kp,Ki,Kd values. I got it pretty close, but notice all tests are oscillating above the set point. Best so far is a set with Kd = 0. I used your code example and notice the setBias is at 255.0 / 2.0 -- is this making the "landing point" always wind up high? Or maybe setWindUpLimits (also used your code example). As I watch it loop it never seems to range below the set point -- which would keep things closer to where I want them if it went there before starting to fire the heat. I have a PDF with examples if you are interested (but don't know how to share). Thanks.

No I or D terms

I have tried to run this algorithm on many, many different scenarios and I can't get the result to have any I or D terms. I looked at the code and in compute you multiply the delta t by 1000, i'm thinking you do that to convert to seconds instead if milli seconds. If that,s the case you need to divide by 1000 or multiply by .001. When I change to code to this, I get what I expect from the I and D terms.

Frustrated at lack of documentation...can anyone help?

The variable "Setpoint" is the desired angle correct? What is its min/max values (the example just has "512")?

I normally use VS Code, but I went to the Arduino IDE to use the Serial Plotter to diagnose things, but it's just a bunch of lines flying by really fast. How can I display the values correctly (I copied this part straight from the example).

how to tune setOutputLimits for two different motor?

I am using this code to control the speed of two dc motors. But the output is not what I am expecting. I have set the bias to 0 as I only wish to get the PID value for my error. As I am using two motors and want them to work like differential, I plan to manually add and subtract the PID value with my motor's base speed (base speed = 200).
But the problem is when I set output limits to (0, 255), after mycontroller.calculate() I am getting an output value of either 0 or 255 resulting in my ultimate motor speed1 = base speed + output = 455 and motor speed2 = base speed - output = -55. But I expect a value between 0 and 255 depending on the error. Any hints on how I can achieve that?

Anti Windup - Limits

In the linked explaination the method to prevent windup was Back calculation.
Limiting the the I to a certain value doest prevent windup. Of course it gives a somewhat better results than with no limit - but a more efficient way would be to introduce clamping by pausing the integration in the wrong direction during saturated controller output.
For example by placing the following above output clamping in line122:

if(newOutput > outputMax || newOutput < outputMin)
    iOut -= (ki * ((curError + lastError) / 2.0)); //undo integral

setWindUpLimits Problem with Negative min

I am using setOutputLimits(-128, 127), setBias(0.0) and setWindUpLimits(-100.0, 100.0). My integral tern was being limited to 0.0 and 100.0 until I changed your code to:

double iMax = constrain(outputMax - outTemp, 0, outputMax); // Maximum allowed integral term before saturating output
double iMin = constrain(outputMin + outTemp, outputMin, 0); // Minimum allowed integral term before saturating output

which appears to function properly for my case. I also added a debug print of the error term which I find useful.

How do we change the setpoint dynamically?

How can we change the setpoint, the desired value to achieve, dynamically in the loop(). I want to change the value of setpoint depending on an input the user gives. Is it simply just running controller.begin() again? Or is that wrong?

What it the setpoint changes often?

Hi! Can it be used in a situation where the setpoint changes on-the-fly, like a gas pedal of a car, accelerating? Example, you change the speed and the PID tries to keep the new set speed, even if the load increases.

can setpoint be changed?

hello,

is it possible to change the setpoint to a different value in a running controller?
lets say i.e. set setpoint to 100 and then, after 5 hrs set setpoint to 200

thank you very much, for the lib and the reply :)

info request

Hi,

Is this an improved version of the pid_v1 library (and pid_v2 too)?

Cheers!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.