Adding a a little tweak to my PID controller code.

Ok so I have a code that works fairly satisfactory. However, there is one thing that I want to be able to do.

The controller controls a heater and I see that in part of the code there is this part:

myPID.SetMode(MANUAL);
Output = 0;

Now if you look at the part of my code posted... when the button state becomes high and the PID controller starts doing auto control. I want to change one thing that happens then. Instead of the PID controller starting low and increasing till it reaches target temp, I want the first thing that happens when the "buttonState = high" and heater is first activated is for the output to be at max (255 in numerical terms) for 3000ms. So my question is... Is there some way I can put it on manual output control and have something like:

                myPID.SetMode(MANUAL);
		Output = 255;
                delay(3000);
                myPID.SetMode(AUTO);
		PID_ON =1;

to achieve what I want to do? Max output (255) for 3 seconds then after that back to auto PID control?

Here's some of the code...

void loop()
{
	buttonState = digitalRead(onPin);


	if (buttonState == HIGH) {
		// turn HEATER on
         
		myPID.SetMode(AUTO);
		PID_ON =1;
                 
                
	}
	else {
     		myPID.SetMode(MANUAL);
		Output = 0;
		PID_ON =0;
	}

	
	if(digitalRead(upPin)==HIGH) {
		if (millis()-lastTime >= 250) {
			Setpoint+=5;
                        UpdateEEPROM();
			lastTime=millis();
			UpdScr = 1;
		}
	}

	if(digitalRead(downPin)==HIGH) {
		if (millis()-lastTime >= 250) {
			Setpoint-=5;
                        UpdateEEPROM();
			lastTime=millis();
			UpdScr = 1;
		}
	}
	Input = analogRead(0);
	myPID.Compute();
	analogWrite(10,Output);
	//and output to LCD

	if( (millis() - lShowTime > 100 ) || UpdScr ) {
		UpdScr = 0;
		lcd.setCursor(0,0);
	//if heater is on - show *
	//if not - empty
		if( PID_ON ==1 ) {
			lcd.print("*");
		}
		else {
			lcd.print(" ");
		}

Thanks in advance for any help or suggestions in accomplishing this!

Wouldn't it have been faster to try it and see than to post here?

I already did... and it doesn't seem to perform the action I need....

Which is: Max output manually for 3000ms and then auto PID control.

With uploading it as:

       myPID.SetMode(MANUAL);
		Output = 255;
                delay(3000);
                myPID.SetMode(AUTO);
		PID_ON =1;

It doesn't do that..

Not sure what I am missing or if I need to make an alteration somewhere else in the code....?

Someone was explaining to me that :

So what you want is to initialize its two initial states so that in the first moment it produces 0xFF on the output. This can be done if you have access to the states and you know the measured value.
Your second requirement is "for 3000ms". What if it initialized with 0xFF but measured value is so huge that according to PID rules the output must be decreased instantly? Your requirement for "3000ms first + PID later" is not a PID controller, but some kind of switching controller. You could tailor its anti-windup option to cause this delay but if you are not aware of the consequences I suggest switching from MANUAL to INITIAL and then to AUTO state.

Anyone know of any templates or examples a switching type controller?

Or... maybe a way to fool the PID controller into having its output at max for 3000ms?

The Output variable is just a value that the pid library calculates for you, a double apparently, see examples here Arduino Playground - PIDLibrary. Once you have it, you need to do something with it. Your code does this after pid computes the latest value for it:

analogWrite(10,Output);

You need the same thing after you set Output manually, before you start your 3s delay.

So....

if I do something like this within the loop:

if(abs(Setpoint-Input)>150) { 
myPID.SetTunings(20,2,0);  
//aggressive for fast initial heatup 

 }  else { myPID.SetTunings(4,2,0); } 
   //Then moderately tuned.

Think that will get me the desired effect? I've tried to do a manual output and then 3 second delay in the code... but that doesn't work.... It just keeps the output high the whole time.

Thats the only thing I can think of...

Max output (255) for 3 seconds then after that back to auto PID control?

What do you expect to happen to the output when the PID loop is switched to AUTO?

Is this the library you are using...
http://www.arduino.cc/playground/Code/PIDLibrary

yeah thats it.

My post had TWO questions.

Well... when in AUTO mode the PID is continuously controlling the output right?

and when in MANUAL it outputs whatever value you set for "Output" if I understand it correctly

If you want the output to be high for 3 seconds, why not just do this...

analogWrite( 10, 255 );
delay( 3000 );
analogWrite( 10, Output );

Why do you need to muck with the PID settings?

So im now toying with "Gain Scheduling" - using different parameters in different operating regions.

and Im wondering if I've got it placed in the code correctly...

So right at the top of the code I've got this:

#include <EEPROM.h>
#include <PID_Beta6.h>
#include <LiquidCrystal.h>

double Setpoint, Input, Output;
double aggKp=2, aggKi=1.75, aggKd=0.075;  //The aggressive tuning parameters
double consKp=1, consKi=2.5, consKd=0.07;  //The conservative tuning parameters


//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, aggKp, aggKi, aggKd);

Then in the loop I have the code arranged as follows:

void loop()
{
  Input = analogRead(0);

double gap = abs(Setpoint-Input); //distance away from setpoint

  if(gap>50)
  { 
 //we're far from setpoint, use aggressive tuning parameters
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }
  else
  {
     //we're close to setpoint, use conservative tuning parameters
     myPID.SetTunings(consKp, consKi, consKd);
  }

Does that look like its placed correctly? So it will constantly monitor the error(gap) and adjust the gains accordingly?

Im toying with it now and it just seems like its not going into the conservative tuning parameters.

BTW I'm using this as kind of a reference Arduino Playground - PIDLibraryAdaptiveTuningsExample

And... I just tried something that kind of proved to me that the conservative values are not working... I set all the conservative values to ZERO. 0,0,0

I tried running the heater and it started heating.... then when the error got within 50 .... it still kept heating like nothing changed.... so that makes me think that its not switching between aggressive and conservative...

hrmm.

It is very likely that you need to set the loop to MANUAL, change the parameters, then set the loop back to AUTO.

You really need to have a deadband for changing the parameters. If gap is hovering right at 50 your loop could get into a situation where the code constantly toggles between the two parameter sets.