problem in balancing inverted pendulum.

Hi. I am currently working on inverted pendulum as my final year project.The problem which i am facing is that it is not balanced at vertically upright. Attached hereby is my code . kindly check my code and tell me where i am doing a problem. I shall be highly thankful to you.
Specifications of my project are:
Quadrature incremental encoder for pendulum angle feedback having 500 slots.
Motor with 1400 r.p.m.

sketch_feb27b_final_code_true.ino (1.72 KB)

Please post your code here to make it easier to access and copy to an editor. When you do please use code tags as described in read this before posting a programming question

``int encoder0=0;//interrupt.orange wire pin no 2
int encoder1=4;//brown wire of encoder
int motorA=10;//brown wire of motor
int motorB=11;//red wire of motor
int limit=3;//limit switch.
int last_error=0;
int errorccw = 0;
int correction = 0;
int errorcw = 0;
double kp =20;
double ki = 10;
double kd =30;
int PID = 0;
int error=0;
volatile int encoder0PinALast=LOW;
volatile int encoder0Pos = 0;//variable to be updated by the interrupt
//volatile int n;
void setup()
{
pinMode(encoder1, INPUT);
pinMode(motorA, OUTPUT);
pinMode(motorB, OUTPUT);
pinMode(limit, INPUT);
pinMode(13, OUTPUT);
//attach interrupts
attachInterrupt(encoder0, count, RISING);
Serial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:
int n=digitalRead(limit);
if(n==0)
{
double angle=0.72*encoder0Pos;
if(angle>0)
{
errorcw=angle;
correction=calcPid(errorcw);
analogWrite(motorA,255);
analogWrite(motorB,0);
digitalWrite(13,HIGH);
angle=0;
}
if(angle<0)
{
errorccw=angle;
correction=calcPid(abs(errorccw));
analogWrite(motorB,255);
analogWrite(motorA,0);
digitalWrite(13,HIGH);
angle=0;
}
if(angle==0)
{
analogWrite(motorB,0);
analogWrite(motorA,0);
//angle=0;

}
}
else
{
digitalWrite(10,LOW);
digitalWrite(11,LOW);
}
}
void count()
{
if(encoder0PinALast==LOW)
{
if(digitalRead(encoder1) == LOW) {
encoder0Pos–;
} else {
encoder0Pos++;
}
Serial.print (encoder0Pos);
Serial.print ("/");
}
encoder0PinALast = LOW;
//return encoder0Pos;
}
int calcPid(int error)
{
PID = (kp*(error)) + (ki*(error + last_error)) + (kd*(error - last_error));
last_error = error;

return constrain(PID, 0, 255);
}


please help.

You have posted code without using code tags. This creates certain problems and obstacles for other forum members. The code tags make the code look

like this

when posting source code files. It makes it easier to read, and can be copied with a single mouse click.
If you have already posted without using code tags, open your message and select “modify” from the pull down menu labelled, “More”, at the lower left corner of the message. Before posting the code, use Ctrl-T in the IDE to reformat the code in a standard format, which makes it easier for us to read. Highlight your code by selecting it (it turns blue), and then click on the “</>” icon at the upper left hand corner. Click on the “Save” button. Code tags can also be inserted manually in the forum text using the [code] and [/code] metatags.

When you are finished that, please read this post:

How to use this forum - please read.

int encoder0 = 0; //interrupt.orange wire pin no 2
int encoder1 = 4; //brown wire of encoder
int motorA = 10; //brown wire of motor
int motorB = 11; //red wire of motor
int limit = 3; //limit switch.
int last_error = 0;
int errorccw = 0;
int correction = 0;
int errorcw = 0;
double kp = 20;
double ki = 10;
double kd = 30;
int PID = 0;
int error = 0;
volatile int   encoder0PinALast = LOW;
volatile int encoder0Pos = 0;//variable to be updated by the interrupt
//volatile int n;
void setup()
{
  pinMode(encoder1, INPUT);
  pinMode(motorA, OUTPUT);
  pinMode(motorB, OUTPUT);
  pinMode(limit, INPUT);
  pinMode(13, OUTPUT);
  //attach interrupts
  attachInterrupt(encoder0, count, RISING);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  int n = digitalRead(limit);
  if (n == 0)
  {
    double angle = 0.72 * encoder0Pos;
    if (angle > 0)
    {
      errorcw = angle;
      correction = calcPid(errorcw);
      analogWrite(motorA, 255);
      analogWrite(motorB, 0);
      digitalWrite(13, HIGH);
      delay (100);

    }
    if (angle < 0)
    {
      errorccw = angle;
      correction = calcPid(abs(errorccw));
      analogWrite(motorB, 255);
      analogWrite(motorA, 0);
      digitalWrite(13, HIGH);
      delay(100);
    }
    if (angle == 0)
    {
      analogWrite(motorB, 0);
      analogWrite(motorA, 0);
      //angle=0;

    }
  }
  else
  {
    digitalWrite(10, LOW);
    digitalWrite(11, LOW);
  }
}
void count()
{
  if (encoder0PinALast == LOW)
  {
    if (digitalRead(encoder1) == LOW) {
      encoder0Pos--;
    } else {
      encoder0Pos++;
    }
    Serial.print (encoder0Pos);
    Serial.print ("/");
  }
  encoder0PinALast = LOW;
  //return encoder0Pos;
}
int calcPid(int error)
{
  PID = (kp * (error)) + (ki * (error + last_error)) + (kd * (error - last_error));
  last_error = error;

  return constrain(PID, 0, 255);
}

The problem which i am facing is that it is not balanced at vertically upright.

What does it do ?

One immediate problem is that you are printing inside the ISR. Serial.print() uses interrupts Interrupts are disabled when in an ISR

Why are you checking the value of the encoder0PinALast variable in the ISR ? How will it ever have a value of anything but LOW in your code ?

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Can you please post a picture of your project?

Thanks.. Tom... :)

Attached hereby are the pictures of h-bridge,arduino and project.

please help

is there anyone to help me about my problem?

Hi,

The problem which i am facing is that it is not balanced at vertically upright

  • What does it do?
  • What are the spec on the motor?
  • What are the spec on the encoder?
  • Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :)

UKHelibob thanks for your reply. where i am counting the pulses i got this code from arduino .cc for how to calculate the pulses of encoder in 2 directions.