Having trouble with PID library

I'm trying to use the Brett Beauregard PID library, found here.

/********************************************************
 * PID Basic Example
 * Reading analog input 0 to control analog PWM output 3
 ********************************************************/

#include <PID_v1.h>

#define PIN_INPUT A7
#define PIN_OUTPUT 3

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
double Kp=2, Ki=5, Kd=1;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()
{
  //initialize the variables we're linked to
  Input = analogRead(PIN_INPUT);
  Setpoint = 100;

  Serial.begin(38400);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  Input = analogRead(PIN_INPUT);
  myPID.Compute();
  analogWrite(PIN_OUTPUT, Output);

    //Send data by serial for plotting
  Serial.print("Input ");
  Serial.print(Input);
  Serial.print(" Output ");
  Serial.print(Output);
  Serial.print(" Setpoint ");
  Serial.println(Setpoint);
}

I added the print statements to see what is going on. Here is the output.

Input 1023.00 Output 0.00 Setpoint 100.00
Input 1023.00 Output 0.00 Setpoint 100.00
Input 1023.00 Output 0.00 Setpoint 100.00

The input comes from a pot attached to a wiper motor. Without any output it makes it hard to move the motor.

Any ideas what I need to do to get the output from the library?

Thanks

You are getting output from the library, which is zero.

What output do you expect for those particular K values? The formula is very simple.

Hint: to get a feel for what is happening, choose sensible starting values for the Ks, (like Kp = 1, Ki = 0, and Kd = 0), and give inputs much closer to the setpoint (above and below).

Thanks for the hint, I'll make adjustments and test it out.

Yea I need it to move both ways, but I need it to move one direction first. :grinning:

I am open for hints where to look to get it to go both ways!

To drive the motor in both directions, you need a bidirectional motor driver, suited to the motor characteristics.

Please post the motor voltage rating and stall current or maximum load current, or a link to the motor data sheet or product page.

Got a few mins to work on this. I put a pot on and use that to mimic the input. As long as the input (pot value) is less than the target I get an output.

Is there a different library that will output negatives? I assumed this one would cause I can't think of a situation where it wouldn't bee needed.

It's difficult to provide the specs for a junkyard motor. My testing has shown 3 amps under load.

I drive this with a cytron MD 13s. I just need the neg values to use it.

To get started with a new library, It is extremely important to read the documentation and study the library examples. GitHub - br3ttb/Arduino-PID-Library

Tutorials here Improving the Beginner’s PID – Introduction | Project Blog

In doing so, you will see that the default output limits are 0-255. Change them using the function


    void SetOutputLimits(double, double); // * clamps the output to a specific range. 0-255 by default, but
										                      //   it's likely the user will want to change this depending on
										                      //   the application
	

It is also hard to get started with a "junkyard" parts, until you have some idea of their characteristics.

For a motor that draws "3 amps under load", plan on buying a motor driver than can handle the start/stall current, which is typically 5x to 10x that value, or 15 to 30 Amperes.

1 Like

What is the intended purpose of using PID with the motor?

The motor is to adjust the bypass on my sprayer in relation to the speed.

Thanks to you all.

The Arduino PID will output negatives. Check out the SetOutputLimits command:

 mypid.SetOutputLimits(-255,255);

From the source code:

I noticed PID::SetOutputLimits(0, 255); at line # 28 in the .cpp file. Changed 0 to -255 and it works as expected!!!!

First time I ever saw the insides of a .cpp file - goes to show you can teach an old dog new tricks 70.5 yrs tomorrow.

Again thanks to all!!

You don’t need to change the library file. You can add a line to set the limits in the program.

The library cpp file just uses its own functions to set the default limits to match the limits of analogWrite.

Maybe they need to learn more new tricks?

  Output2=Output*2-255;


  Output3 = map(Output,0,255,-100,100);

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.