help with pid code

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How to limit integral sum error?

Last Edited: Fri. Jan 17, 2020 - 01:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, post what you have written and point out where you are having the issue(s).

 

jeet55 wrote:
How to limit integral sum error?

Isn't going to get you much positive response.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

if(Isum < MAX) Isum++;

else Isum = MAX;

 

 

 

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do a search term for integrator windup   This happens when the plant (ex: motor) can't keep up with the PID's commanded level, for example: at maximum deliverable power, torque, rpm, etc.  The integrator keeps finding the setpoint is not being reached & increases its accumulated error (pos or neg), demanding ever-increasing fwd/rev power, torque, RPM, etc, which is useless, since no more is available.  If this accumulation continues unabated, it takes a long long time for the PID commanded value to desaturate the plant command.  

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

#include "complementary_filter.h"

uint8_t MPU6050_data[12];
volatile int acx,gyy,acx_lut_index,gyy_lut_index,acx_deg,gyy_deg,anglex;

void COMPFILT_Initialize()
{
TCCR2A = (WGM21);
//CTC 0 TO OCR2A
TCCR2B = (CS22) | (CS21) | (CS20);
//1024 PRESCALER

OCR2A = 10;
//1562.5 hz sample rate
TIMSK2 = (1 << OCIE2A);
//OCR2A COMAPARE INTTERUPT
}

ISR(TIMER2_COMPA_vect)
{
MPU6050_ReadByteS(ACXH,&MPU6050_data[0],6);
MPU6050_ReadByteS(GYXH,&MPU6050_data[6],6);

acx = MPU6050_data[0] << 8 | MPU6050_data[1];
gyy = MPU6050_data[8] << 8 | MPU6050_data[9];

//-----------------------------------------------------------------------------------------------------------------------

if (acx < 0)
acx_lut_index = -acx;
else
acx_lut_index = acx;

acx_lut_index = acx_lut_index >> 6;
acx_lut_index = acx_lut_index << 1;
acx_deg = (pgm_read_byte(&arcsinelut[acx_lut_index]) << 8 | pgm_read_byte(&arcsinelut[acx_lut_index + 1]));

if (acx < 0)
acx_deg = -acx_deg;
//----------------------------------------------------------------------------------------------------------------------------
if (gyy < 0)
gyy_lut_index = -gyy;
else
gyy_lut_index = gyy;

gyy_lut_index = gyy_lut_index >> 7;
gyy_lut_index = gyy_lut_index << 1;
gyy_deg = (pgm_read_byte(&gyrolut[gyy_lut_index]) << 8 | pgm_read_byte(&gyrolut[gyy_lut_index + 1]));

if (gyy < 0)
gyy_deg = -gyy_deg;
//-------------------------------------------------------------------------------------------------------------------------

anglex = multfix(anglex,0x00fd) + gyy_deg + multfix(acx_deg,0x0003);//00fb,0005//00fd,0003
//--------------------------------------------------------------------------------------------------------------------------

int speed,error,sum_error = 0,previous_error = 0,p_term,i_term,d_term;
//--------------------------------------------------------------------------------------------------------------------------

error = anglex - SETPOINT;
//---------------------------------------------------------------------------------------------------------------------------
if (error > P_ERROR_MAX)
{
p_term = PID_MAX_OUTPUT;
}
else if(error < -P_ERROR_MAX)
{
p_term = -PID_MAX_OUTPUT;
}
else
{
p_term = multfix(anglex,KP);
}
//---------------------------------------------------------------------------------------------------------------------------

if (sum_error + error > PID_MAX_OUTPUT)
{
sum_error = PID_MAX_OUTPUT;
i_term = PID_MAX_OUTPUT;
}
else if (sum_error + error < -PID_MAX_OUTPUT)
{
sum_error = -PID_MAX_OUTPUT;
i_term = -PID_MAX_OUTPUT;
}
else
{
if (sum_error + error > I_ERROR_MAX)
{
i_term = PID_MAX_OUTPUT;
}
else if (sum_error + error < -I_ERROR_MAX)
{
i_term = PID_MAX_OUTPUT;
}
else
{
i_term = multfix(KI,sum_error);
}

sum_error = sum_error + error;
}
//-------------------------------------------------------------------------------------------------------------------------------
if ((error - previous_error > PID_MAX_OUTPUT) || (error - previous_error > I_ERROR_MAX))
{
d_term = PID_MAX_OUTPUT;
}
else if((error - previous_error < -PID_MAX_OUTPUT) || (error - previous_error < -I_ERROR_MAX))
{
d_term = -PID_MAX_OUTPUT;
}
else
{
d_term = multfix(error-previous_error,KD);
}
previous_error = error;
//--------------------------------------------------------------------------------------------------------------------------------

if (p_term + i_term + d_term > PID_MAX_OUTPUT)
{
speed = PID_MAX_OUTPUT;
}
else if (p_term + i_term + d_term < -PID_MAX_OUTPUT)
{
speed = -PID_MAX_OUTPUT;
}
else
speed = p_term + i_term + d_term;
//-------------------------------------------------------------------------------------------------------------------------------
if (speed < 0)
{
speed = -speed;
speed = speed << 1;
MOTOR_Backward((uint8_t)(speed >> 8),(uint8_t)(speed >> 8));

}
else
{
speed = speed << 1;
MOTOR_Forward((uint8_t)(speed >> 8),(uint8_t)(speed >> 8));
}

}

This is the code

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please format the code properly!

 

You did it in the other thread!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is the code

So what....you neglect to say anywhere at all what you are observing.  Should we assume everything is working great & others should add this to their code snip library? 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!