slow push button response in Statemachine counter

Hi,
Have code for a relay heater controller that reads temperature and compares value to set temperature number using two push buttons. Problem is when I push the buttons its very slow to respond, though it all does what I want just slowly. Not sure if its how I'm returning the value in the int temp_control() function.

I'm using a Aruduino Uno, and have 10K ohm resistors for pulldowns on the buttons IO pins to GND.

int temp_control() {
  
  //unsigned long currentMillis = millis();
  
  // read the pushbutton input pin:
  int UpButtonState = digitalRead(set_temp_increase_Pin);
  int DownButtonState = digitalRead(set_temp_decrease_Pin);
  
  // If the switch changed, due to noise or pressing:
  if (UpButtonState != lastUpButtonState && DownButtonState != lastDownButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }
  
  if((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:
             
    // if the button state has changed: 
    if (UpButtonState != lastUpButtonState) {
      //increment by 1 if button is HIGH
      if (UpButtonState == HIGH) {
        ++buttonCounter;
        //return buttonCounter;
      }      
    }
    else {
      if ((DownButtonState != lastDownButtonState)) {
        if (DownButtonState == HIGH) {
          --buttonCounter;
          //return buttonCounter;
        }
      }
    }
        
      
    
    // save the reading.  Next time through,
    // it'll be the lastButtonState:
    lastUpButtonState = UpButtonState;
    lastDownButtonState = DownButtonState;
    
    lcd.setCursor(0,1);
    lcd.print("Set Temp ");
    lcd.print(buttonCounter);      
    //Serial.println(buttonCounter);
    return buttonCounter;//THE SET TEMP VALUE I WANT TO RETURN    
  }  
}

State_Machine_Heater_Controller_DS18B20_Apr16.zip (2.45 KB)

  // If the switch changed, due to noise or pressing:
  if (UpButtonState != lastUpButtonState && DownButtonState != lastDownButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

You change the last debounce time only when both switches have changed state. Seems to me that you'd want to do then when either switch changed state.

How are the switches wired? You are not using the internal pullup resistors, so you need external resistors. You do have them, right?

You have not posted a complete program so I have no idea what is the value of debounceDelay. I have no intention of wasting time opening a ZIP file.

Note also that purpose of a short interval between reading button pins is to avoid mechanical bounce in the switch contacts - so 50 msecs is probably more than enough. Checking whether the state of the switch has changed is a separate issue.

...R

I'm using external resistors not internal pull-ups. I tested the circuit on a simple button sketch and all worked good and wasn't slow to respond. I have changed the debounce time as it was 50ms.
Here's the full code.

/* This program to control a heat by pressing two buttons that set the temperature you want and then 
   if the measured temperature is lower then the heater turns on! */ 

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Temperature averaging 
const int numReadings = 10;

float readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
float total = 0; // the running total
float average = 0; // the average



float temperatureC = 0;

// Button control Pins and values
const int set_temp_increase_Pin = 7; //temp control button Pin
const int set_temp_decrease_Pin = 6; //temp control button Pin

         
int UpButtonState = 0;
int lastUpButtonState = 0;     // previous state of the button

int DownButtonState = 0;
int lastDownButtonState = 0;     // previous state of the button

int buttonCounter = 0;   // counter for the number of button presses

//Digital pins for the relays that control heater
const int relay1 = 3;


long lastDebounceTime = 0;        // will store last time button was updated
long debounceDelay = 100;   // interval at which to read button state (milliseconds)// the debounce time; increase if the output flickers


//Serial ic2 LCD 
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C	lcd(0x27,2,1,0,4,5,6,7); // 0x27 is the I2C bus address for an unmodified module


void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  
  // Start up the DS18B20 library
  sensors.begin();
  
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH); // NOTE: You can turn the backlight off by setting it to LOW instead of HIGH
  lcd.begin(16, 2);
  lcd.clear();
  
  
  // initialize the button pin as a input:
  pinMode(set_temp_increase_Pin, INPUT);
  pinMode(set_temp_decrease_Pin, INPUT);
  
  

  pinMode(relay1, OUTPUT);
    
  //initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++){
    readings[thisReading] = 0;
  }
}  


      


void loop() {
  
  float T;
  T = TempsensorRead();
  int C;
  C = temp_control();
  
  
  //Serial.println(T);
  
  
  Serial.println(C);
  
  if (T < C)
  {
    digitalWrite(relay1, HIGH); //mains power turn on
    lcd.setCursor(12,1);
    lcd.print("ON!");    
  }
  else
  {
    digitalWrite(relay1, LOW); //switch off heaterer once heater fan runs for a minute to cool heater down
    //lcd.clear();
    lcd.setCursor(12,1);
    lcd.print("OFF");
  }
}


int temp_control() {
  
  //unsigned long currentMillis = millis();
  
  // read the pushbutton input pin:
  int UpButtonState = digitalRead(set_temp_increase_Pin);
  int DownButtonState = digitalRead(set_temp_decrease_Pin);
  
  // If the switch changed, due to noise or pressing:
  if (UpButtonState != lastUpButtonState && DownButtonState != lastDownButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }
  
  if((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:
             
    // if the button state has changed: 
    if (UpButtonState != lastUpButtonState) {
      //increment by 1 if button is HIGH
      if (UpButtonState == HIGH) {
        ++buttonCounter;
        //return buttonCounter;
      }      
    }
    else {
      if ((DownButtonState != lastDownButtonState)) {
        if (DownButtonState == HIGH) {
          --buttonCounter;
          //return buttonCounter;
        }
      }
    }
        
      
    
    // save the reading.  Next time through,
    // it'll be the lastButtonState:
    lastUpButtonState = UpButtonState;
    lastDownButtonState = DownButtonState;
    
    lcd.setCursor(0,1);
    lcd.print("Set Temp ");
    lcd.print(buttonCounter);      
    //Serial.println(buttonCounter);
    return buttonCounter;//THE SET TEMP VALUE I WANT TO RETURN    
  }  
}
  


//CODE BELOW READS THE TEMPERATURE SENSOR AND THEN AVERAGES IT  
float TempsensorRead() {
  sensors.requestTemperatures(); // Send the command to get temperatures
  
  //unsigned long currentMillis = millis();
  
  //subtract the last reading
  total = total - readings[index];
  
  float senorTemp = sensors.getTempCByIndex(0); // Why "byIndex"? 
    // You can have more than one IC on the same bus. 
    // 0 refers to the first IC on the wire
    
  //read from the sensor
  readings[index] = senorTemp;
  
  //add the reading to the total
  total = total + readings[index];
  
  //advanced to the next position in the array
  index = index + 1;
  
  //Cap the index to the numReadings 10 value, the size of the array.
  if(index >= numReadings) {    
    //wrap around to the beginning
    index = 0;
  }
  //now index is ready to start over again
  
  //now we can finally calculate the average and enjoy smoothed data.
  average = total / numReadings;    
  
  temperatureC = average;
      
  //if(currentMillis - previousMillis > interval) {
    //Serial.println(temperatureC);
    lcd.setCursor(0,0);
    lcd.print("Room Temp ");
    lcd.print(temperatureC);
    lcd.print("C");
    return temperatureC;
  //}
}

In line 80, I would fill the readings array with the current temperature, not 0.

I don't have one myself but IIRC from other Threads that the Dallas temperature sensor is slow and the library blocks until the read completes.

I think it is possible to do the reading in two parts - initiate a measurement and then come back and get the value when it is ready.

I may not be correct but it may be worth investigating.

...R

  // If the switch changed, due to noise or pressing:
  if (UpButtonState != lastUpButtonState && DownButtonState != lastDownButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

The comment says "if THE switch..." and then deals with two switches. Fix the damned comment to match what you want to do when TWO switches are involved.

Decide if you want to record the last debounce time when BOTH switches change state (which seems pretty unlikely to ever happen) or when EITHER switch changes state.