PID temperature control

I want to temperature control system where the setpoint can be adjustable from 15 to 5 degree celsius.I have attached code for basic PID for one single set point ,I dont know how to add push button to add and decrease setpoints.Here is the code

/********************************************************
  PID Basic Example
  Reading analog input 0 to control analog PWM output 3
********************************************************/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//I2C pins declaration

#include <PID_v1.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


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

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, 8.8, 1.4, 2.3, REVERSE);

void setup()
{
  //initialize the variables we're linked to
  Input = analogRead(1);
  Setpoint = 15;
  Serial.begin(9600);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  lcd.begin(16, 2);

}

void loop()
{
  Input = analogRead(1);
 Input= (5.0 * Input * 100.0) / 1024.0;
  myPID.Compute();
  analogWrite(3, Output);
  Serial.print(Input); Serial.println(Output);
  //delayy next read out
  lcd.setCursor(0, 0);
  lcd.print("Temperature:");
  lcd.print(Input);
  lcd.setCursor(0, 1);
  lcd.print("Set Point:");
  lcd.print(Setpoint);
  lcd.print("C   ");

}

A typical way to add buttons is to connect one side to ground and the other to one of the arduino pins and then define that pin as INPUT_PULLUP to enable the internal pullup resistor. You have to read the state of the arduino pin and if it is HIGH, it is not being pushed, if it is LOW, it is being pushed. Also do some research on "debounce" for the button pushes (or use the Button library)

Based on which button is being pushed, you add or subtract 1 from your setpoint, making sure you stay within your range.

Give it a shot and post your code if you have problems.

an alternative to push buttons is a RotaryEncoder

Use hardware interrupt.

syntax: attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

ISR: write the function name (in where it goes whenever you press pushbutton, where your increment/decrement happens)

mode: defines when the interrupt should be triggered. Four constants are predefined as valid values:

RISING : to trigger when the pin goes from low to high,

FALLING : for when the pin goes from high to low.

check for your arduino (UNO/Mega/...) interrupt pins.

Hope it helps. ping back, if not.

thanks for the reply.I did try to combine with code above.I got something like this

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
//I2C pins declaration

#include <PID_v1.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 

double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, 8.8, 1.4, 2.3, REVERSE);
int tempPin = A1;   // analog input to read the temperature
int temp;

int set = 15;           //set temperature variable
int lastset = 2;
int Counter1 = 0;       // counter for the number of button presses
int Counter2 = 0;       // counter for the number of button presses
int State1 = 0;         // current state of the button
int State2 = 0;         // current state of the button
int lastState1 = 0;     // previous state of the button
int lastState2 = 0;
int val = 0;
const int set1 = 11;     //temp up and temp down buttons
const int set2 = 12;

int pwm1 = 9;        // pin ENA on L298N
int in_1 = 1;        // in 1
int in_2 = 8;       // in 2

int pwm2 = 10;        // pin ENB on L298N
int in_3 = 6;          // in 3
int in_4 = 7;          // in 4



void setup() {
                                                           

  pinMode(set1, INPUT);
  pinMode(set2, INPUT);

  Input = analogRead(tempPin);
  Setpoint = 15;
  myPID.SetMode(AUTOMATIC);
  myPID.SetSampleTime(200); 
  
  lcd.begin(16,2);  
   
  
 }
                           
  void loop() {
 int temp = ((5.0/1024.0) * analogRead(A1)) * 100;  //10mV per degree 0.01V/C. Scalling
 lcd.setCursor(0,0);
 lcd.print("Temperature:");
  lcd.print(temp);
      
State1 = digitalRead(set1);
  State2 = digitalRead(set2);  
  if (State1 != lastState1) {
        if (State1 == HIGH && set!= 15) {        //if up button is pressed, add 1 to des
        set++;
     } 
    
  }
  
  if (State2 != lastState2) {  //if down button is pressed, subtract 1 from des
       if (State2 == HIGH && set!=5) {
       set--; 
    }
   
  }
   myPID.Compute();
  analogWrite(3, Output);
  lcd.setCursor(0,1);
  lcd.print("Set Point:");
  lcd.print(set);
  lcd.print("C   ");
}

But its not working

Jackrau18:
But its not working

That's a shame.

If you told us what the code actually does, and how that differs from what you expect, perhaps you'd get something more than fake sympathy.

How are your buttons wired up? Normally, one side it tied to ground and the other side it tied to the input pin with the pin configured to have the internal pullup resistor enabled. If this is the case, when the button state is HIGH, it means the button is NOT pressed. Your logic is the opposite of that.

Also, the way your code is will cause one button press to increment/decrement the setpoint many times since you will go back through the loop() To a human, a single button press of ~ 1/2 a second will look like hundreds of button presses to your code. You should only sample the buttons once in a while or wait for the button to be released or use a button library that handles this and debouncing, etc.