user21481: I am hooking up an accelerometer to an arduino uno and running it through this pid controller. However the output isnt going to my setpoint. When i move the accelerometer back and forth the data goes to 255 or 0. Any ideas?
Datasheet for accelerometer:
https://www.sparkfun.com/datasheets/Components/SMD/adxl335.pdf
I get 336 for the x direction, which is the only direction i'm using, when its set flat on the table, which is my setpoint/desired output.
Note: Is the output the value away from the setpoint or the actual acceleration it calculates through the controller?
#include <PID_v1.h>

#define PIN_INPUT A0

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

//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); //Start a serial session
int  xdata = analogRead(PIN_INPUT);
Input = map(xdata, 0, 1024, 0, 255); //Change read scale to analog out scale
int setPoint = 336;
Setpoint = map(setPoint, 0, 1024, 0, 255); //Change read scale to analog out    
//turn the PID on
myPID.SetMode(AUTOMATIC);
}

void loop()
{
int xdata = analogRead(PIN_INPUT);
Input = map(xdata, 0, 1024, 0, 255); //Change read scale to analog out scale

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();

Serial.print("Setpoint = ");
Serial.print(Setpoint);
Serial.print(" Input = ");
Serial.print(Input);
Serial.print(" Output = ");
Serial.print(Output);
Serial.print("\n");
// analogWrite(PIN_OUTPUT, Output);
}

OUTPUT:
Setpoint = 83.00 Input = 87.00 Output = 0.00
Setpoint = 83.00 Input = 81.00 Output = 0.00
Setpoint = 83.00 Input = 64.00 Output = 255.00
Setpoint = 83.00 Input = 64.00 Output = 255.00
Setpoint = 83.00 Input = 68.00 Output = 255.00
Setpoint = 83.00 Input = 79.00 Output = 0.00
Setpoint = 83.00 Input = 91.00 Output = 0.00
Setpoint = 83.00 Input = 96.00 Output = 0.00
Setpoint = 83.00 Input = 99.00 Output = 0.00
Setpoint = 83.00 Input = 88.00 Output = 0.00
Setpoint = 83.00 Input = 68.00 Output = 0.00
Setpoint = 83.00 Input = 58.00 Output = 255.00
Setpoint = 83.00 Input = 64.00 Output = 255.00
Setpoint = 83.00 Input = 78.00 Output = 255.00
Setpoint = 83.00 Input = 95.00 Output = 0.00
Setpoint = 83.00 Input = 97.00 Output = 0.00
Setpoint = 83.00 Input = 95.00 Output = 0.00


user19102: Ensure that your period for the PID execution routine is reasonable for your system.  I generally like to execute my PID loops at 5 to 20 times the system impulse response.  For instance, with a motor, I will apply 100% power from a standstill and measure the time it takes to get up to 90% of final value.  I will then multiply that time by 0.1 and start there.  If it takes 1s, then I will start my PID loop executing every 0.1s.  Sometimes I adjust this up or down, depending on system requirements, but this is not a bad starting point.
If your PID loop is executing too fast, then it will respond too quickly to actually have a real-world effect on the system.  The output will tend to oscillate.  Motors vibrate and make more noise.... different systems respond differently, but you see the point.

Start at kp = 0,ki = 0, kd = 0
Increase kp until you get a reasonable response.  Don't expect your error to go to 0.  As long as you aren't oscillating, that should be good.
Very slowly increase kiuntil you are happy.
You should probably keep kd to 0.  It is for advanced usage and PI loops will meet the vast majority of application requirements.

This is a very crude guide.  There are better on google, but this should get you started.  PID loops are fun, especially with motors.  Enjoy!

21481: <p>I am hooking up an accelerometer to an arduino uno and running it through this pid controller. However the output isnt going to my setpoint. When i move the accelerometer back and forth the data goes to 255 or 0. Any ideas?</p>

<p>Datasheet for accelerometer:
<a href="https://www.sparkfun.com/datasheets/Components/SMD/adxl335.pdf" rel="nofollow">https://www.sparkfun.com/datasheets/Components/SMD/adxl335.pdf</a></p>

<p>I get 336 for the x direction, which is the only direction i'm using, when its set flat on the table, which is my setpoint/desired output.</p>

<p>Note: Is the output the value away from the setpoint or the actual acceleration it calculates through the controller?</p>

<pre><code>#include &lt;PID_v1.h&gt;

#define PIN_INPUT A0

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

//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(&amp;Input, &amp;Output, &amp;Setpoint, consKp, consKi, consKd, DIRECT);

void setup()
{
  //initialize the variables we're linked to
Serial.begin(9600); //Start a serial session
int  xdata = analogRead(PIN_INPUT);
Input = map(xdata, 0, 1024, 0, 255); //Change read scale to analog out scale
int setPoint = 336;
Setpoint = map(setPoint, 0, 1024, 0, 255); //Change read scale to analog out    
//turn the PID on
myPID.SetMode(AUTOMATIC);
}

void loop()
{
int xdata = analogRead(PIN_INPUT);
Input = map(xdata, 0, 1024, 0, 255); //Change read scale to analog out scale

double gap = abs(Setpoint-Input); //distance away from setpoint
if (gap &lt; 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();

Serial.print("Setpoint = ");
Serial.print(Setpoint);
Serial.print(" Input = ");
Serial.print(Input);
Serial.print(" Output = ");
Serial.print(Output);
Serial.print("\n");
// analogWrite(PIN_OUTPUT, Output);
}
</code></pre>

<p>OUTPUT:</p>

<pre><code>Setpoint = 83.00 Input = 87.00 Output = 0.00
Setpoint = 83.00 Input = 81.00 Output = 0.00
Setpoint = 83.00 Input = 64.00 Output = 255.00
Setpoint = 83.00 Input = 64.00 Output = 255.00
Setpoint = 83.00 Input = 68.00 Output = 255.00
Setpoint = 83.00 Input = 79.00 Output = 0.00
Setpoint = 83.00 Input = 91.00 Output = 0.00
Setpoint = 83.00 Input = 96.00 Output = 0.00
Setpoint = 83.00 Input = 99.00 Output = 0.00
Setpoint = 83.00 Input = 88.00 Output = 0.00
Setpoint = 83.00 Input = 68.00 Output = 0.00
Setpoint = 83.00 Input = 58.00 Output = 255.00
Setpoint = 83.00 Input = 64.00 Output = 255.00
Setpoint = 83.00 Input = 78.00 Output = 255.00
Setpoint = 83.00 Input = 95.00 Output = 0.00
Setpoint = 83.00 Input = 97.00 Output = 0.00
Setpoint = 83.00 Input = 95.00 Output = 0.00
</code></pre>
 19102: <p>Ensure that your period for the PID execution routine is reasonable for your system.  I generally like to execute my PID loops at 5 to 20 times the system impulse response.  For instance, with a motor, I will apply 100% power from a standstill and measure the time it takes to get up to 90% of final value.  I will then multiply that time by 0.1 and start there.  If it takes 1s, then I will start my PID loop executing every 0.1s.  Sometimes I adjust this up or down, depending on system requirements, but this is not a bad starting point.</p>

<p>If your PID loop is executing too fast, then it will respond too quickly to actually have a real-world effect on the system.  The output will tend to oscillate.  Motors vibrate and make more noise.... different systems respond differently, but you see the point.</p>

<ol>
<li>Start at <code>kp = 0</code>,<code>ki = 0</code>, <code>kd = 0</code></li>
<li>Increase <code>kp</code> until you get a reasonable response.  Don't expect your error to go to 0.  As long as you aren't oscillating, that should be good.</li>
<li>Very slowly increase <code>ki</code>until you are happy.</li>
<li>You should probably keep <code>kd</code> to 0.  It is for advanced usage and PI loops will meet the vast majority of application requirements.</li>
</ol>

<p>This is a very crude guide.  There are better on google, but this should get you started.  PID loops are fun, especially with motors.  Enjoy!</p>
