PID question

Hi everyone. I'm experimenting with the PID library and running the PID adaptive tuning example on my Mega. The example works fine as is, but when I add some code to send a new Setpoint value via the serial monitor it doesn't seem to work. It doesn't adjust to the new value. Any thought on what I'm doing wrong. Thanks.

/********************************************************

  • Arduino PID Library
  • by Brett Beauregard
  • contact: br3ttb@gmail.com
  • PID Adaptive Tuning Example
  • One of the benefits of the PID library is that you can
  • change the tuning parameters at any time. this can be
  • helpful if we want the controller to be agressive at some
  • times, and conservative at others. in the example below
  • we set the controller to use Conservative Tuning Parameters
  • when we're near setpoint and more agressive Tuning
  • Parameters when we're farther away.
    ********************************************************/
    #include <PID_v1.h>

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

//Define the aggressive and conservative Tuning Parameters
double aggKp=4, aggKi=0.2, aggKd=1;
double consKp=1, consKi=0.05, consKd=0.25;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);

void setup()
{
//initialize the variables we're linked to
Serial.begin(9600);
Input = analogRead(0);
Setpoint = 100;

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

void loop()
{
Input = analogRead(0);
if (Serial.available()>0) // Added this section to pass a Setpoint value
{ //via the serial monitor
Setpoint=Serial.read(); //
Serial.println(Setpoint);
}
double gap = abs(Setpoint-Input); //distance away from setpoint
if(gap<10)
{ //we're close to setpoint, use conservative tuning parameters
myPID.SetTunings(consKp, consKi, consKd);
}
else
{
//we're far from setpoint, use aggressive tuning parameters
myPID.SetTunings(aggKp, aggKi, aggKd);
}

myPID.Compute();
analogWrite(2,Output);
}

Hello tetris911

I'm guessing that you want to type in a number e.g. "125" and then press send and have Setpoint changed to 125?

If so, you need to change this part of the code.

Setpoint=Serial.read();

This reads just one character from Serial and assigns its ASCII value to Setpoint. So, for example, it would take the 1 from "125" and assign 49 to Setpoint. Then do the same for the 2 and then the 5.

Try this instead.

Setpoint=Serial.parseInt();

Serial.parseInt() returns the first valid (long) integer number from the serial buffer. Characters that are not integers (or the minus sign) are skipped. Serial.parseInt() is terminated by the first character that is not a digit.

All the best

Ray

Thanks!! It's working now. (At least in one direction) :smiley: