Author Topic: PID Control code?  (Read 3119 times)

Offline Monito

  • Distributor
  • *****
  • Posts: 1081
  • I have 4 coffee Roasters and I don't collect them!
PID Control code?
« on: May 26, 2008, 05:14:14 PM »
I have decided to make my own PID control using my computer, Linux OS and Wago modules.

I have an in depth knowledge of Wago, but very little in PID control.
Anyone with a PID Control C source code?

With my approach I will be able to plot anything!
use any profile I want!

Here is what I will start with:
Computer
Linux
Wago:
   Ethernet coupler
   power supply
   Digital Output
   L-Type Module
SSR
k-type thermocouple

Simple...

Thanks,

Monito

johnr

  • Guest
Re: PID Control code?
« Reply #1 on: May 27, 2008, 07:13:08 AM »
Hey Monito, sounds like we're working on similar projects. I don't have PID source for you (it doesn't look difficult to write though) but I do have a "modified" behmor interfaced to a laptop using a k-type for environment temp and a phidget relay board to control the heating element. Currently, I'm running this setup with some c# code that I threw together and zedgraph for temp curve display. Heat control is manual at the moment - the manual scheme is percent based, like the hottop b - but at some point I may decide to implement PID logic for the heat control. Lemme know what you find and I'll do the same. :)

Offline Monito

  • Distributor
  • *****
  • Posts: 1081
  • I have 4 coffee Roasters and I don't collect them!
Re: PID Control code?
« Reply #2 on: May 27, 2008, 08:30:14 AM »
I have found several, but they are more complicated than it should.

Monito

johnr

  • Guest
Re: PID Control code?
« Reply #3 on: May 27, 2008, 09:18:21 AM »
Yep, that's exactly my impression as well - I'm not convinced that PID is the optimal approach in the roaster control case, especially if you don't have bean mass temp. However, this is a new problem domain for me so take that comment (and all the ones that follow for that matter) with a grain of salt.

I've grappled with profile control and my view on it has gone through several iterations since I started the project... at first, I thought I'd like PID control so I could create profiles based on fixed length temperature-based segments (i.e., 3 mins at 300, followed by 2 mins at 320, etc), the approach taken by the hottop p. But this approach doesn't work very well if: (1) you don't have the bean dialed in yet; and/or (2) you don't have bean mass temp (which I don't). Ideally, you'd like to base profile segments on internal bean temp rather than environment temp. Without bean mass temp, though, you're left with manipulating env temp based on approximate roast stage, fully aware that env temp <> bean temp and the two values diverge more and more as the roast progresses.

Which brought me to iteration #2: profile segments that are based on percent of full heat application, ala hottop b. In this scheme, maybe for bean "a" you start off with a 4 minute segment at 100%, followed by a 3 minute segment at 70%, etc, and maybe when c1 gets rolling, you reduce to 20% or something, and so on. This is somewhat like the behmor's built-in profiles but with fixed length segments, rather than the existing difficult-to-work-with relative length segments. Or maybe there's a combination of temp-based segments and percent-based segments.

Regardless, you're really just trying to indirectly achieve the same goal in both approaches: control over the rate of env temp change (remember, we don't have bean mass temp here). Enter iteration #3: this will likely involve using the percent based logic that's already in place to control segments that are based on deg/min rate since that's how I find myself using the percent-based control right now anyway.

Offline Monito

  • Distributor
  • *****
  • Posts: 1081
  • I have 4 coffee Roasters and I don't collect them!
Re: PID Control code?
« Reply #4 on: May 27, 2008, 09:27:59 AM »
In my case I do have bean mass, but I have no idea how the PID control works.

Until I figure how the PID works I will program it, so it will do exactly what I do by hand. The difference will be that it will never fail (forget to change the heat settings) and I won't have to watch it for 16 minutes ... May be at the end... ;)

Monito


johnr

  • Guest
Re: PID Control code?
« Reply #6 on: May 27, 2008, 01:55:18 PM »
Here's a very simple PID controller that I wrote in c# while reading this article: http://www.embedded.com/2000/0010/0010feat3.htm ... feel free to use it if it suits your needs but note that the gains need to be tuned to the application.

Code: [Select]
public class PIDController
{
   public PIDController( double setpointValue, bool bProportional, bool bIntegral, bool bDifferential )
   {
      SetpointValue = setpointValue;
      m_functionsEnabled |= bProportional ? 0x01 : 0;
      m_functionsEnabled |= bIntegral     ? 0x02 : 0;
      m_functionsEnabled |= bDifferential ? 0x04 : 0;
   }

   public double Output( double measuredValue )
   {
      return ( Output( SetpointValue - measuredValue, measuredValue ) );
   }

   public double Output( double error, double measuredValue )
   {
      double p = IsProportionalEnabled ? Proportional( error ) : 0;
      double i = IsIntegralEnabled ? Integral( error ) : 0;
      double d = IsDifferentialEnabled ? Differential( measuredValue ) : 0;
      return ( p + i - d );
   }

   public double SetpointValue;
   public double ProportionalGain = 10.0;
   public double IntegralGain = 0.1;
   public double DifferentialGain = 50;
   
   private int m_functionsEnabled;
   private double m_iState = 0;
   private double m_iMinState = 0;
   private double m_iMaxState = 550;
   private double m_dState = 0;

   protected bool IsProportionalEnabled { get { return ( ( m_functionsEnabled & 0x01 ) == 0x01 ); } }
   protected bool IsIntegralEnabled { get { return ( ( m_functionsEnabled & 0x02 ) == 0x02 ); } }
   protected bool IsDifferentialEnabled { get { return ( ( m_functionsEnabled & 0x04 ) == 0x04 ); } }

   protected double Proportional( double error )
   {
      return ( ProportionalGain * error );
   }

   protected double Integral( double error )
   {
      m_iState += error;
      m_iState = Math.Min( m_iState, m_iMaxState );
      m_iState = Math.Max( m_iState, m_iMinState );
      return ( IntegralGain * m_iState );
   }

   protected double Differential( double measuredValue )
   {
      double prevState = m_dState;
      m_dState = measuredValue;
      return ( DifferentialGain * ( measuredValue - prevState ) );
   }
}

Offline Monito

  • Distributor
  • *****
  • Posts: 1081
  • I have 4 coffee Roasters and I don't collect them!
Re: PID Control code?
« Reply #7 on: May 27, 2008, 03:06:53 PM »
Thanks,

The part that I don't understand is what do I do with the data:
i.e.

1. I get the temperature, from the thermocouple where do I feed that info.
2. When do I turn on/off the oven, what output?
That is just a couple...

Thanks,

Monito

johnr

  • Guest
Re: PID Control code?
« Reply #8 on: May 27, 2008, 03:55:32 PM »
The basic idea is: you have a measured value, a setpoint value and a function that spits out an analog value that's applied as input to the system.

In our case, the measured value is the thermocouple temp sample; the setpoint value is the temperature you'd like the beans/chamber to be; and the output corresponds to the amount of heat to be applied. I believe the intent is to scale/transform the output value such that it can be used in a meaningful way in a specific system. For example, let's say your use case involved taking one sample a second and getting an output value from the pid controller from this sample. Let's further suppose that you wanted to control a heating element with the output and you only had the means of switching it ON or OFF. In other words, you would need to convert the analog output value of the pid function to a digital value. A simple approach might be to turn the heating element ON when the value is > 0 and turn the heating element OFF when it is < 0. This may or may not be the optimal conversion but it's one way you could do it. Make sense?
« Last Edit: May 27, 2008, 03:59:37 PM by johnr »

Hananonn

  • Guest
Re: PID Control code?
« Reply #9 on: May 28, 2008, 12:57:12 AM »
Lets see if I?m right.
Is it true that with a pid you can have one set point at the time unless it is a programmable pid?
From what I know, if you need to have a several set points, which correspondence to  inputs and out puts   you actually going to need a PLC.
I?m breaking my head finding a programmable PID that will create a gradual rise with several set points.
Do you guys control the set points through the C++ for me it is Chinese.

Offline Monito

  • Distributor
  • *****
  • Posts: 1081
  • I have 4 coffee Roasters and I don't collect them!
Re: PID Control code?
« Reply #10 on: May 28, 2008, 04:57:45 AM »
...snip...
I?m breaking my head finding a programmable PID that will create a gradual rise with several set points.
Do you guys control the set points through the C++ for me it is Chinese.
This is exactly what I'm doing, I can do it at any time during the roast.

With an old computer an a little knowledge of I/O systems and a programming language (C/C++/Fortran/Basic) you are in...

Monito

kwksilver

  • Guest
Re: PID Control code?
« Reply #11 on: May 28, 2008, 06:34:36 AM »
Hannan, if the PID doesn't have some sort of graded output responding to the size of the error signal, then it isn't really a PID. If gain is not variable, then it is vanilla :p

It doesn't have to be ramp and soak, there are a lot of algorithms you could use. But every PID controller should not only adjust the size of the output to the size of the error, it should be able to adjust gain to the temporal relationship.
For example if you are heating water right before it changes phase you will not have a linear relationship between energy (heating element) put in and temperature measured. A good PID can be set to interpret the relationship between temperature and energy put in over time. One better is when you allow predictive algorithms where they learn from past events to expect a certain response along different timepoints. Then it doesn't have to wait for output. That is what the idea of adjusting gain to error is emulating anyways.

THe "I" in PID is the portion of a PID that allows it memory of what happened with past adjustments. Don't have that? don't have pid....

The derivative of that is the rate, as in the moment to moment effect of the adjustment...again don't have it don't have pid.

You have only ONE setpoint in a PID, but your gain is not defined by one number. It is floating. You can often give the algorithms different variables that determine how sensitive each portion is and one can set limits.

If you are using a computer to compute a PID circuit, usually you will want to cascade PID your setup, as it does not cost you anything to do so.

Monito do you want Matlab? just asking.

Felix

johnr

  • Guest
Re: PID Control code?
« Reply #12 on: May 28, 2008, 09:16:56 AM »
If you are using a computer to compute a PID circuit, usually you will want to cascade PID your setup, as it does not cost you anything to do so.

Sounds interesting - what is the advantage of cascading? And I assume that the sample rate would have to be faster in the first pid than the second pid in order to achieve the desired effect?

johnr

  • Guest
Re: PID Control code?
« Reply #13 on: May 28, 2008, 09:22:08 AM »
Btw, I tried the controller code pasted above in my setup last night (both with and without beans) and, for the most part, it worked fairly well. With the current gain settings, oscillations were minimal, response was good but it has a tendency to stay a couple of degrees above the setpoint. I need to build a tuning harness for it and tweak it some more.

kwksilver

  • Guest
Re: PID Control code?
« Reply #14 on: May 30, 2008, 08:22:34 PM »
If you cascade, the second pid can make due  with a very low rate indeed. After all you usually cascade it to the first PID's output. And his output is far below his sampling.
Can your roasters vary voltage to the heating element or is it boolean?
If you have analog control over your current, you can REALLY do something cool by running multiple PID loops.

Another question I have is this:

 Since we have a desired profile with predetermined knowledge of where you want to go and how fast, I really think for a roaster a feedforward component with you partially setting the "I" gain to zero would give wickedly good results.
The PID only has one god, your setpoint. Cascade them and the piggyback gives the primary PID a changing god. connect the piggyback algorithm to your feedforward info and make the piggy a PD instead of PID, and you have a system that should be able to predictively deliver a dream roast profile. So instead of you experimenting how much drum preheat and how much heating to get to say 350 in XYZ minutes, you can tell the piggyback what is supposed to be the de facto profile and he develops it for you.
(So you can design the profile based on what you imagine the entire temperature over time should be.)
That is very different from having a pre programmed profile where you invent a sequential heating behavior... that is huge.
I know you cannot get bean mass, but I know you guys are very good at knowing where your beans are from sight,smell and so on.
So if you can correlate the bean mass temp you could have the above PID setup develop a profile on your roaster based on  the idealized profile you enter.
Now I wish I had the gizmos to do that!  (thermocouples speedy enough, a roaster with balls and a laptop)


PS: Since runnign a profile in this manner makes executrion dynamic ambient temperature and batch size variability as well as bean variability would allow you to put them through a remarkably similar temperature experience repeatedly! extremely cool.