Go Down

Topic: Pendulum Balance Robot (Read 2 times) previous topic - next topic


Mar 13, 2013, 04:28 pm Last Edit: Mar 13, 2013, 04:30 pm by laadams85 Reason: 1

PID(&Input, &Output, &Setpoint, Kp, Ki, Kd, Direction)

Input: The variable we're trying to control (double)
Output: The variable that will be adjusted by the pid (double)
Setpoint: The value we want to Input to maintain (double)
Kp, Ki, Kd: Tuning Parameters. these affect how the pid will chage the output. (double>=0)
Direction: Either DIRECT or REVERSE. determines which direction the output will move when faced with a given error. DIRECT is most common.

m needs to be a double to work correctly with the PID library
you can cast it to an int for your stepper motor like this if you want
Code: [Select]


I think it would be best to start over and do tests to see if it works, and again after each additional code.

Okay,  i have gone back and and sorted out the stepper motor, this code was a second attempt,  and the bits you mentioned I had forgotten to copy over. So now the motor will now step if commanded.

I'm still struggling to input a 'double*' however,  I guess the code ' double int = (something) '  is used,  but I am unsure what to put as the something. I guess a similar thing will happen for the variable 'newPosition'?  to give a variable that has the double format required by the PID? (and hopefully fixing the encoder reader in the process)


Mar 13, 2013, 05:10 pm Last Edit: Mar 13, 2013, 05:13 pm by laadams85 Reason: 1
Code: [Select]
long newPosition = myEnc.read();
Don't do this it will re-define newPosition which will no longer be associated with your PID.

Code: [Select]
double m = 0;
double newPosition = 0;
PID myPID(&newPosition, &m, 0.0, 1.0, 20.0, 100.0, DIRECT);
void loop(){
 newPosition = (double)myEnc.read();

You may not have to explicitly cast myEnc.read(), but I'm a little rusty on my automatic casts.


Thanks, The PID isnt throwing up any more errors :D

I've looked with an oscilloscope,  and the encoder changes its values when rotated in manner that I would expect,  however unfortunately no change its still not showing in the serial monitor, with it sticking at the initial value (now -512) lke this:


Basic Encoder Test

I'm not sure what the Y'' is,  here is the most recent code for good measure.

Code: [Select]
#include <PID_v1.h>
#include <Encoder.h>
#include <Stepper.h>
const int pwmA = 3;
const int pwmB = 11;
const int brakeA = 9;
const int brakeB = 8;
const int dirA = 12;
const int dirB = 13;
const int STEPS = 200;
double m = 0;
double newPosition  = 0;
int chanA = 20;
int chanB = 21;
Stepper myStepper(STEPS, dirA, dirB);
Encoder myEnc(chanA, chanB);
PID myPID(&newPosition, &m, 0, 1, 20, 100, DIRECT);
void setup() {
pinMode (pwmA, OUTPUT);
  digitalWrite(pwmA, HIGH);
  pinMode(pwmB, OUTPUT);
  digitalWrite(pwmB, HIGH);
  pinMode(brakeA, OUTPUT);
  digitalWrite(brakeA, LOW);
  pinMode(brakeB, OUTPUT);
  digitalWrite(brakeB, LOW);

long oldPosition  = -999;

void loop() {
  newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;

  delay (1);


Thanks a lot for help everyone, every post puts me one step closer to  an  automatic breakfast machine :D

(edited to fix broken quote '}' )


Try this, comment out "myEnc.write(-512);" and spin the encoder, does it give out readings. Whats happening is, your telling the encoder to be set to a value, and then without any actual movement, its reading back that same value.
Created Libraries:
TFT_Extension, OneWireKeypad, SerialServo, (UPD)WiiClassicController, VWID

Go Up