CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PID control code integer math

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Tom-H-PIC



Joined: 08 Sep 2003
Posts: 105
Location: New Castle, DE

View user's profile Send private message

PID control code integer math
PostPosted: Mon Feb 06, 2012 9:18 am     Reply with quote

I have search the form for PID control using integer math.
And have found parts of code here and there in the form.
But have not found complete code for a PID control using integer math.
Am I missing it some place?
Or would someone be kind and post some in the code example for us.

Thanks
Tom
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 10:07 am     Reply with quote

Here was a good article I found on implementing PID - http://igor.chudov.com/manuals/Servo-Tuning/PID-without-a-PhD.pdf
The trick to doing it without having to use floating point is to scale (normalize) things when you are working with them then use multipliers/divisors etc that are factors of 2 (divide by 8 is simply shift right 3 bits). The one I built recently (for controlling the heat element on the hummingbird feeders in the winter here in the Seattle area :-) ) just used the PI portion (the hooks are there for the "D" portion, but it worked just fine as it was). There was also a good article on homebrew in a past issue of Circuit Cellar that discussed implementing the PID. June 2006 had that article. You may also find some additional information in this thread from a while back: http://www.ccsinfo.com/forum/viewtopic.php?p=151009

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 10:11 am     Reply with quote

I don't think you will find a cut & paste solution. You need to go through your PID algorythm by hand and see what the range of values may be for each variable. Then scale the variables into a decent integer range. Also note what might happen if any of them exceed the range, make sure it will fail gracefully and not catch fire or kill people.
_________________
The search for better is endless. Instead simply find very good and get the job done.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 10:17 am     Reply with quote

The problem is that it always has to be custom tuned.
However if you post an email address to me, I'll send the 'core maths' directly from some old code I did.

Best Wishes
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 10:48 am     Reply with quote

The nice thing about Matlab is the ability to 'reverse engineeer' the PIC math to get the values for the PIC controller. Great for old guys like me that always move the decimal point the wrong way...
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 11:42 am     Reply with quote

temtronic wrote:
The nice thing about Matlab is the ability to 'reverse engineeer' the PIC math to get the values for the PIC controller.Great for old guys like me that always move the decimal point the wrong way...


Ah ha !! Another frustrated slide rule user :-)

mikey (who comes from the era where the geeks had slide rules in leather cases on their belts ... )
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 5:36 pm     Reply with quote

Some old code from an old pet project of mine, a HERMS (heat exchanging recirculating mash system). PID section should be self explanatory. As has been suggested, start by reading "PID without a PhD" first and try to measure/model your system the best you can to come up with reasonable guesses for the P, I and D terms.

Code:

#define p_gain 5 // 2^5 = 32
#define i_gain 11 // 2^11 = 2048
#define d_gain 10 // 2^10 = 1024
#define max_error 63 * (1 << (i_gain + 4))

void cycle_heaters(void) {
   int m;
   // lauter tun heater
   if ((lauter_temp < (lauter_set_temp - 2)) && lauter_enable) {
      bpin1 = 1; // turn on lauter tun heater relay
   }
   else if ((lauter_temp > lauter_set_temp) && lauter_enable) {
      bpin1 = 0;
   }
   else if (!lauter_enable) {
      bpin1 = 0;
   }

   // HE heater
   // if pump is on, HE power setting is based on diff between present mash temp and mash set temp (PID)
   // if pump is off, HE power setting is based on diff between present HE temp and mash set temp (thermostat)
   // implementing a PID control to the mashtun power setting,
   // increased resolution from 15 steps to 63.  Power setting is based on the formula:
   // setting = proportional term + integral term - differential term (limited to 0 - 63 range)
   // proportional term = proportional gain * (set temp - present temp)
   // integral term = integral gain * sum of (set temp - present temp), the sum of (set temp - present temp) is
   // limited to lie within the range 0 - 63 * integral gain
   // differential term = differential gain * (present temp - previous temp)
   // prop gain = 32
   // integral gain = 1/2048
   // differential gain = 1024

   error = ((int32)mash_set_temp << 4) - mash_temp_sixteenths;
   if (started && piping == RECIRC) { // only calculate the PID coeff's if we're recirculating
      total_error = total_error + error;
      if (total_error > max_error) {
         total_error = max_error;
      }
      else if (total_error < 0) {
         total_error = 0;
      }
   }
   p_term = error << p_gain; // "multiply"
   i_term = total_error >> i_gain; // "divide"
   if (total_error < 0) { // if total error is negative, must set msb's to 1's
      for (m = 0; m < i_gain; m++) {
         bit_set(i_term, 31 - m);
      }
   }
   d_term = (mash_temp_sixteenths - old_mash_temp_sixteenths) << d_gain; // "multiply"
   overall_gain = (p_term + i_term - d_term) >> 4;
   if ((p_term + i_term - d_term) < 0) {
      for (m = 0; m < 4; m++) {
         bit_set(overall_gain, 31 - m);
      }
   }
   if (overall_gain > 63) {
      overall_gain = 63;
   }
   else if (overall_gain < 0) {
      overall_gain = 0;
   }

   if (pump_on && piping == RECIRC) {
      power_setting = overall_gain; // use PID only if we're recirculating
   }
   else if (he_temp < (mash_set_temp - 1)) { // ...otherwise just do a simple thermostat
      power_setting = 32;
   }
   else if (he_temp > mash_set_temp) {
      power_setting = 0;
   }
   print_temp((int16)power_setting, HE_POWER);
}
Tom-H-PIC



Joined: 08 Sep 2003
Posts: 105
Location: New Castle, DE

View user's profile Send private message

PID control code integer math
PostPosted: Wed Feb 08, 2012 6:29 am     Reply with quote

Thank you all for your replies and help.

Ttelmah I would really like to see your code so I sent you a PM with my email in it.

And Thanks again All

Tom
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group