Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

PID controller

Name: Anonymous 2011-05-06 4:29

Written in sepples for Arduino

Can you find any immediate problems with this bitch? I won't be able to test before implementing so I'd like multiple eyes on this.


#include <Metro.h>  // Metro is a time keeping library, necessary for the Integral and Derivative parts of the controller.

// PID CONTROLLER
//  2011 / 5 / 3

// The PID CONTROLLER reads one ADC input and writes to one PWM output
const int adcInput = A0; // Can use pins A0 to A5
const int pwmOutput = 2; // Can use pins 0 to 13 but 0 and 1 are Serial I/O

// Controller constants.
double kP = 0;
double kI = 0;
double kD = 0;

int outputMin = 0;    // The controller will never output a lower pulse width than this value
int outputMax = 255;    // The controller will never output a higher pulse width than this value
int sp = 512;  // Setpoint. ADC is 10 bit so max value is 1023.
int db = 0;    // Deadband
int dt = 10;   // Step value. Should be at least 10 milliseconds so the ADC can settle after reading.



// -------------------------------------------+
// NO USER SERVICABLE CODE BENEATH THIS LINE. |
// -------------------------------------------+

int integral = 0;
int derivative = 0;
int error = 0;
int lastError = 0;
int output = 0;
Metro step = Metro(dt);

void setup()
{
  int dummy = 0; // Nothing is in scope setup() but it is customary to have the function in ARDUINO projects. If PID
                 // values are to be changed on the fly, the setup() function is where serial commo should be initiated.
}

void loop()
{
  if(step.check() == 1)// IF steptime has passed.
  {
    error = sp - analogRead(adcInput);
    integral = integral + (error*dt);
   
    if((error>(sp+db))||(error<(sp-db))) // IF the error falls outside the deadband
    {
      derivative = ((error - lastError)/dt);
      output = (int)((kP*(double)error) + (kI*(double)integral) + (kD*(double)derivative));
      analogWrite(pwmOutput, output);
    }
  }
}

Name: Anonymous 2011-05-06 4:32

and of course, I find an error right after I post - I forgot to limit output to outputMin/outputMax


Revised:

#include <Metro.h>  // Metro is a time keeping library, necessary for the Integral and Derivative parts of the controller.

// PID CONTROLLER
//  2011 / 5 / 3

// The PID CONTROLLER reads one ADC input and writes to one PWM output
const int adcInput = A0; // Can use pins A0 to A5
const int pwmOutput = 2; // Can use pins 0 to 13 but 0 and 1 are Serial I/O

// Controller constants.
double kP = 0;
double kI = 0;
double kD = 0;

int outputMin = 0;    // The controller will never output a lower pulse width than this value
int outputMax = 255;    // The controller will never output a higher pulse width than this value
int sp = 512;  // Setpoint. ADC is 10 bit so max value is 1023.
int db = 0;    // Deadband
int dt = 10;   // Step value. Should be at least 10 milliseconds so the ADC can settle after reading.



// -------------------------------------------+
// NO USER SERVICABLE CODE BENEATH THIS LINE. |
// -------------------------------------------+

int integral = 0;
int derivative = 0;
int error = 0;
int lastError = 0;
int output = 0;
Metro step = Metro(dt);

void setup()
{
  int dummy = 0; // Nothing is in scope setup() but it is customary to have the function in ARDUINO projects. If PID
                 // values are to be changed on the fly, the setup() function is where serial commo should be initiated.
}

void loop()
{
  if(step.check() == 1)// IF steptime has passed.
  {
    error = sp - analogRead(adcInput);
    integral = integral + (error*dt);
   
    if((error>(sp+db))||(error<(sp-db))) // IF the error falls outside the deadband
    {
      derivative = ((error - lastError)/dt);
      output = (int)((kP*(double)error) + (kI*(double)integral) + (kD*(double)derivative));
      if(output>outputMax)
      {
        analogWrite(pwmOutput, outputMax);
      }
      else if(output<outputMin)
      {
        analogWrite(pwmOutput, outputMin);
      }
      else
      {
        analogWrite(pwmOutput, output);
      }
    }
  }
}

Name: Anonymous 2011-05-06 5:14

The code tags are there for a reason.

Name: Anonymous 2011-05-06 5:15

Sure


#include <Metro.h>  // Metro is a time keeping library, necessary for the Integral and Derivative parts of the controller.

// PID CONTROLLER
//  2011 / 5 / 3

// The PID CONTROLLER reads one ADC input and writes to one PWM output
const int adcInput = A0; // Can use pins A0 to A5
const int pwmOutput = 2; // Can use pins 0 to 13 but 0 and 1 are Serial I/O

// Controller constants.
double kP = 0;
double kI = 0;
double kD = 0;

int outputMin = 0;    // The controller will never output a lower pulse width than this value
int outputMax = 255;    // The controller will never output a higher pulse width than this value
int sp = 512;  // Setpoint. ADC is 10 bit so max value is 1023.
int db = 0;    // Deadband
int dt = 10;   // Step value. Should be at least 10 milliseconds so the ADC can settle after reading.



// -------------------------------------------+
// NO USER SERVICABLE CODE BENEATH THIS LINE. |
// -------------------------------------------+

int integral = 0;
int derivative = 0;
int error = 0;
int lastError = 0;
int output = 0;
Metro step = Metro(dt);

void setup()
{
  int dummy = 0; // Nothing is in scope setup() but it is customary to have the function in ARDUINO projects. If PID
                 // values are to be changed on the fly, the setup() function is where serial commo should be initiated.
}

void loop()
{
  if(step.check() == 1)// IF steptime has passed.
  {
    error = sp - analogRead(adcInput);
    integral = integral + (error*dt);
  
    if((error>(sp+db))||(error<(sp-db))) // IF the error falls outside the deadband
    {
      derivative = ((error - lastError)/dt);
      output = (int)((kP*(double)error) + (kI*(double)integral) + (kD*(double)derivative));
      if(output>outputMax)
      {
        analogWrite(pwmOutput, outputMax);
      }
      else if(output<outputMin)
      {
        analogWrite(pwmOutput, outputMin);
      }
      else
      {
        analogWrite(pwmOutput, output);
      }
    }
  }
}

Name: Anonymous 2011-05-07 3:33

Anyone?

Name: Anonymous 2011-05-07 3:39

what?

Name: Anonymous 2011-05-07 3:48

FUCK YEAH ARDUINObut i won't buy one till they're on sale at radio shack

Name: Anonymous 2011-05-07 5:38

>>7
lol pig american. enjoy your asscheeburgers.

Name: Anonymous 2011-05-07 6:01

Why do you calculate the integral outside the if sentence, and only the derivative inside? And why do you even have a deadband?

if((error>db)||(error<-db)) // IF the error falls outside the deadband

Name: Anonymous 2011-05-07 12:09

double kP = 0;
double kI = 0;
double kD = 0;

Expert microcontroller developer.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List