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
}
}
// 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.
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;
//}
}
// 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.