Pages: [1] 2   Go Down
Author Topic: Adding ON/OFF control & temp display to PID SCRIPT  (Read 2488 times)
0 Members and 1 Guest are viewing this topic.
LA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey all I am currently playing with some of the PID scripts and my arduino.

I've got it hooked up to two things, a heater to heat to the set temp and a thermocouple to take the readings and adjust accordingly.

My questions are about the script...

I've  got the following  script uploaded to my board:

/********************************************************
 * PID Simple Example
 * Reading analog input 0 to control analog PWM output 3
 ********************************************************/

#include <PID_Beta6.h>

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, 2,5,1);

void setup()
{
  //initialize the variables we're linked to
  Input = analogRead(0);
  Setpoint = 150;
  
  //turn the PID on
  myPID.SetMode(AUTO);
  myPID.SetSampleTime(250);
  myPID.SetTunings(2,3,1);
  
}

void loop()
{
  Input = analogRead(0);
  myPID.Compute();
  analogWrite(3,Output);
}

Now, when the board is turned on, it starts heating to the setpoint and does a magnificent job of keeping it there.

What I am trying to achieve is adding a on/off button to trigger the board to start heating the element ONLY when the signal from the button is received Also, I would like to add two buttons that adjust the temperature UP or DOWN, and a LCD readout of the Setpoint, and the ACTUAL temperature VIA a single serial wire.

Can anyone point me to the direction where I might find an example of this?  Or simply throw the code down in a post?  I would imagine the first two things I am trying to achieve are relatively simple in terms of coding. The simple on/off thing and temp up/down in response to the buttons.

Thanks in advance for all your responses!

Logged

LA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay... So i've got 3 SPST pushbutton switches (Normally Open) hooked up to +5v  and the outputs of each going to digital  pins 4--- (Trigger or operation button)  5---(Increase temp by 1 degree) and 6----(Decrease temp)

As far as the On/off operation goes.. Am I kind of on the right track??... I'd like to keep the code as simple as possible.


void setup()
{
  //initialize the variables we're linked to
  Input = analogRead(0);
  Input = digitalRead(4);
  Input = digitalRead(5);
  Input = digitalRead(6);
  Setpoint = 150;
  
  //turn the PID on
  myPID.SetMode(AUTO);
  myPID.SetSampleTime(250);
  myPID.SetTunings(2,3,1);
  myPID.SetOutputLimits(0, 178.5);
  
}

void loop()
{
  Input = analogRead(0);
  myPID.Compute();
  
  if(digitalRead(4),HIGH);
   analogWrite(3,Output);
   }else{
      I dont know what to put here??
}


How's this going?

Did I do okay introducing the new inputs? Should it be digital or analog?
« Last Edit: June 23, 2009, 01:01:32 pm by dacr0n » Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I may be able help with one item on your list.  

This PID algorithm appears to include mode (myPID.SetMode).  If mode works with this implementation the way I've seen it work with other implementations (the way it should work) you can use it to "turn off" and "turn on" the PID loop.  

Setting mode to manual should...

  • Leave the output value at the current value
  • Stop updating the internal values from the input

Setting mode back to auto should...

  • Reset the internal values
  • Provide a "bumpless" transition from the current (old) output value to the next (new) output value
  • Seamlessly resume calculations

Good luck,
Brian
Logged

Boston
Offline Offline
Full Member
***
Karma: 0
Posts: 101
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

coding badly is correct.  (that is a sentence I never thought I'd write!)
that is to say, Brian is correct.

you can have your on/off button toggle the Auto/Manual state of the pid using the SetMode(..) function.  when in manual mode, the pid will stay out of things, and you can write whatever you want to the output variable.

for ease of coding you're still free to all Call myPID.Compute().  it will see that the current mode is manual and will immediately return without calculating.

glad to hear that the library is working for you!

Brett
« Last Edit: June 25, 2009, 12:17:25 pm by br3ttb » Logged

LA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay... So I have done a bit of tinkering and moving the code around. I've taken small portions of code from the "button library" to see if I can get this going.....

It complied Okay in the arduino program, but I am wondering if anyone see's anything that is wrong right off the bat.

I've put my goals to hook up the LCD untill later when I get the buttons working and doing what I want.

I think I have the on/off thing going... I just need someone to give me some pointers on how to make "buttonPin2" and "buttonPin3" to increase and decrease the setpoint by 1 degree.

Here's what I've got so far.

/********************************************************
 * PID Simple Example
 * Reading analog input 0 to control analog PWM output 3
 ********************************************************/

#include <PID_Beta6.h>

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

const int buttonPin1 = 1;     // the number of the RUNpushbutton pin
const int buttonPin2 = 2;     // the number of the UPpushbutton pin
const int buttonPin3 = 3;     // the number of the DOWNpushbutton pin
 
  // variables will change:
int buttonState = 0;         // variable for reading the pushbutton status


//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, 2,5,1);

void setup()
{
        
  // initialize the pushbuttons as inputs:
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  
  //initialize the variables we're linked to
  Input = analogRead(0);
  Setpoint = 100;
  
  //set initial tunings
  
  myPID.SetSampleTime(250);
  myPID.SetTunings(2,3,1);
  myPID.SetOutputLimits(0, 220);
  
}

void loop()
{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin1);

  // check if the RUNpushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {    
    // Perform action:    
    Input = analogRead(0);
    myPID.Compute();
    analogWrite(3,Output);  
  }
  else {
    // Turn PID OFF
    myPID.SetMode(MANUAL);  
  }
  
}


Logged

Boston
Offline Offline
Full Member
***
Karma: 0
Posts: 101
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

the basic way to increase the setpoint would be

Code:
if(digitalRead(buttonPin2)==HIGH)
{
   Setpoint+=1;
}
the problem with this is that since loop excecutes so quickly, this code may be hit several times in the time it takes to press and release the button.

what I have done in similar situations is instead of looking at the current state of the button, I looked for a CHANGE in the state of the button.  so something like:

Code:
int lastState = LOW;
void loop()
{
   int currentState = digitalRead(buttonPin2);
  if(currentState == HIGH && lastState ==LOW)  //only go in if we were off last time, and on this time
  {
    Setpoint+=1;  //increment the setpoint
  }
  lastState = currentState;  //remember the button state for next time
}

Hope that helps.  Brett
« Last Edit: June 30, 2009, 03:09:48 pm by br3ttb » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That code could still trigger multiple events due to contact bouncing. I would suggest setting a minimum elapsed time before letting the button trigger another event. For example:
Code:
unsigned long lastTime;
if(digitalRead(buttonPin2)==HIGH)
{
  if (lastTime+250<millis()) {
    Setpoint+=1;
    lastTime=millis();
  }
}

That way, you can click the button once, and it'll increase one degree, or hold it down to increase at a rate of 4 per second. With a bit more coding, you could have it count how long the button stays down, and after say, 2 seconds, have it increase the rate of change.
Logged

Boston
Offline Offline
Full Member
***
Karma: 0
Posts: 101
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
That code could still trigger multiple events due to contact bouncing

That's a good point goose.  I like your way better.

Brett
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Given that this system is still under development and that you're trying to control something that could be dangerous (heaters have been know to cause burns smiley-wink), I suggest starting the PID loop in manual.  This gives you an opportunity to look things over before letting the (potentially buggy) code take control...

Code:
void setup()
{
  // stuff already in your setup...
  myPID.SetMode(MANUAL);  
}



If the PID code supports writes to the output (some sort of command like myPID.WriteOutput or myPID.SetOutput), you should move these two lines of code...

Code:
  myPID.Compute();
   analogWrite(3,Output);

...to the bottom of loop so they always execute.  This will provide output clamping in one place (the PID code).

Even if the PID code does not support writes to the output, there is no harm in moving the two lines of code.  When the loop is in manual, Output won't change.


- Brian
« Last Edit: June 30, 2009, 05:16:17 pm by bcook » Logged

LA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for all the tips everyone!

I am just finishing up wiring the thing and I will apply the changes to the code that have been recommended.

Now... Since I don't have the LCD hooked up at present... Is there a way to monitor the "setpoint" as I change it up and down with the buttons? Like to make sure that they're doing what they're supposed to?  I notice on the arduino program there is a serial monitor button...



Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

goose2283:

This...

Code:
 if (lastTime+250<millis()) {

...doesn't work quite the way you expect when millis is close to wrapping.  Let's say that the previous time through loop, lastTime was set to 0xFFFFFFFF - 249.  This time through the loop we have...

Code:
 if ( (0xFFFFFFFF - 249)+250<millis()) {

Code:
 if ( 1<millis()) {

For the 250ms until millis() wraps back to zero the condition is always true.  Generally, it's better to calculate the delta then compare...

Code:
 if (millis()-lastTime>=250) {

- Brian
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17263
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, the Arduino's serial command is the simplest way to debug or use as a temporary user interface to test out the basic application, then later you can can add the LCD UI stuff. You can use the Arduino's serial monitor or a PC serial terminal program to monitor system performance and even send setpoint and mode commands to the your Arduino sketch.


Lefty

Logged

LA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well... I have cleaned up a bit to take things one step at a time..

So...

All I want is for the PID code to send the PWM output signal ONLY then the button is ON.

Code:
//********************************************************
 * PID Simple Example
 * Reading analog input 0 to control analog PWM output 3
 ********************************************************/

#include <PID_Beta6.h>

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1);
    
const int onPin = 1; // choose the input pin to trigger heater
const int upPin = 2;   // choose the input pin to increase temp
const int downPin = 3;   // choose the input pin to decrease temp
int buttonState = 0;     // variable for reading the pin status


void setup() {
  // Declare inputs
  pinMode(onPin, INPUT);    // declare pushbutton as input
  pinMode(upPin, INPUT);    // declare pushbutton as input
  pinMode(downPin, INPUT);    // declare pushbutton as input
  //initialize the variables we're linked to
  Input = analogRead(0);
  Setpoint = 100;
    
    myPID.SetSampleTime(250);
    myPID.SetTunings(2,3,1);
    myPID.SetOutputLimits(0, 220);
  
 
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(onPin);
  
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {    
    // turn PID on:    
    WHAT CODE HERE?;
  }
  else {
    // turn PID off:
    WHAT CODE HERE?;
  }
  Input = analogRead(0);
  myPID.Compute();
  analogWrite(3,Output);
}




Did I do all the declarations and stuff right?

« Last Edit: July 01, 2009, 05:26:55 pm by dacr0n » Logged

LA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

in regards to "myPID.SetMode(MANUAL);"

doesn't the mode refer to auto or manual tuning?  Not operation...

From what I understand that Coding Baldy said MANUAL mode is OFF?
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
doesn't the mode refer to auto or manual tuning?

No.

Quote
MANUAL mode is OFF?

Yes.



The terms are historical.  Long ago, closed-loop control was performed by a human.  The person would walk about, write instrument readings on paper, perform calculations, then adjust valves.  In other words, control was performed manually.  Automatic means a machine is performing the closed-loop control.

- Brian
« Last Edit: July 01, 2009, 07:45:34 pm by bcook » Logged

Pages: [1] 2   Go Up
Jump to: