Button interrupts - arduino uno - help

Hello!

I am very new to arduino and programming in general. I am trying to build a temperature controller that displays on a LCD screen and uses two buttons to set the temperature. I found a code online that someone else created and apparently had working correctly. I was able to get everything except the 2nd button working so far.

I have both buttons connected with an individual 10k pull up resistor to the ground. Most of the comments in the code are not mine.

This will be for a kegerator, so I would like to add 3 more buttons later that display what is on each the corresponding tap when pressed. If I understand correctly, my uno cannot handle more than two interrups, so any help on this issue would be great also.

Thank you,

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

volatile long lastDebounceTimeU = 0;
volatile long lastDebounceTimeD = 0;
#define ONE_WIRE_BUS 4
#define debounceDelay 300

byte buttonInterruptUp = 0;
byte buttonInterruptDown = 1;


LiquidCrystal lcd(12, 11, 10, 9, 8, 6);
double currentTemp = 1337;
double setTemp = 35.00;


OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);


const int COOLING = 1;
const int RESTING = 0;
const double precision = 0.3; //.5 degrees precision

int minOn = 1; //2 mins = 120 - changed for testing
int maxOn = 3600; //1h
int minOff = 1; //10m = 600 - changed for testing

int rest_count;
int cool_count;
int fridge_status;
int startup_time = 3000;


const int fridge_relay = 5;

boolean tooWarm(){
return (currentTemp >= (setTemp+precision));
}

boolean restLongEnough(){
return (rest_count >= minOff);
}

boolean tooCold(){
return (currentTemp <= setTemp); //temp keeps dropping after temp is reached
}

boolean onLongEnough(){
return(cool_count >= minOn);
}

boolean onTooLong(){
return (cool_count >= maxOn);
}

void setup() {
digitalWrite(fridge_relay, HIGH); //start with fridge off, relay is active low

lcd.begin(16, 2);
//Serial.begin(9600);
lcd.print("starting up");

attachInterrupt(buttonInterruptUp, tempUp, RISING);
attachInterrupt(buttonInterruptDown, tempDown, RISING);
sensors.begin();
pinMode(fridge_relay, OUTPUT);
fridge_status = RESTING;
rest_count = minOff;
cool_count = 0;
}

void loop() {
delay(startup_time); //allow lcd to be initialized first
startup_time = 0;

getTemp();
lcdPrint();

if(fridge_status == RESTING){
if(tooWarm() && restLongEnough()){
//turn fridge on after temp has risen and waiting for compressor to cool down
digitalWrite(fridge_relay, LOW);
delay(2000);
cool_count = 0;
fridge_status = COOLING;
}
rest_count++;
}else{//fridge status is COOLING

if(onTooLong() || (onLongEnough() && tooCold()))
{
//turn the fridge off if its cool enough or compressor on too long
digitalWrite(fridge_relay, HIGH);
delay(2000);
rest_count = 0;
fridge_status = RESTING;
}
cool_count++;
}
delay(1000);
}


void tempUp(){//dont feel like adding a debouncing circuit.. this is good enough
if((millis()-lastDebounceTimeU) > debounceDelay){
lastDebounceTimeU = millis();
if(setTemp < 100.00){
setTemp += 0.5;
lcdPrint();
}
}
}

void tempDown(){
if((millis()-lastDebounceTimeD) > debounceDelay){
lastDebounceTimeD = millis();
if(setTemp > 30.00){
setTemp -= 0.5;
lcdPrint();
}
}
}


void getTemp(){
sensors.requestTemperatures();
double t = sensors.getTempFByIndex(0);
if(t > 0 && t < 120){ //faulty wiring causes weird temperatures..
currentTemp = t;
}
}


void lcdPrint(){
lcd.begin(20,4); //sometimes lcd goes blank, i guess this fixes it....
char tbuff[6];
tbuff[0] = '0'+((int)currentTemp/10%10);
tbuff[1] = '0'+((int)currentTemp%10);
tbuff[2] = '.';
tbuff[3] = '0'+((int)(currentTemp*10)%10);
tbuff[4] = '0'+((int)(currentTemp*100)%10);
tbuff[5] = '\0';

char sbuff[6];
sbuff[0] = '0'+((int)setTemp/10%10);
sbuff[1] = '0'+((int)setTemp%10);
sbuff[2] = '.';
sbuff[3] = '0'+((int)(setTemp*10)%10);
sbuff[4] = '\0';
lcd.clear();
lcd.setCursor(0,0);
lcd.print("TEMP:");
lcd.setCursor(8,0);
lcd.print(tbuff);

lcd.setCursor(1,1);
lcd.print("SET:");
lcd.setCursor(8,1);
lcd.print(sbuff);
lcd.print(" ");

//print a "*" on the display if the fridge is on
lcd.setCursor(16,2);
if(fridge_status == COOLING){
lcd.print("*");
}else lcd.print(" ");
lcd.display();

}

I am very new to arduino and programming in general.

Then, you have NO business trying to use interrupts.

I have both buttons connected with an individual 10k pull up resistor to the ground.

A wiring diagram would be useful, as would using proper terminology. A pull UP resistor pulls the pin UP to 5V. A pull DOWN resistor pulls the pin DOWN to ground.

The Arduino has built-in pullup resistors, so the simplest way to connect a SWITCH is to connect one leg to ground and the other the digital pin, and then turn on the internal pullup resistor.

const double precision = 0.3; //.5 degrees precision

If you are going to have useless comments that state the obvious, they MUST be correct.

You need to delete all the stuff dealing with interrupts. There is nothing in your code that needs to respond IMMEDIATELY to a change in button state. Reading the pin once per pass through loop() is good enough. There is nothing that is going to matter if you are a few nanoseconds late reading the switch state.

delay(startup_time); //allow lcd to be initialized first

Bullshit. If your LCD is so lazy that it needs a rest on EVERY pass through loop, throw it away and get one that can work harder.

Read, understand, and embrace the blink without delay philosophy and get rid of EVERY delay(). You do not need them. AT ALL.

Ah yes... the knowledgeable forum guy with thousands of posts who while giving helpful info... loves to point out how obviously dumb a noob is while talking down to them and who probably chases many people away from the forum and perhaps hobby.

You seem to have read everything except the statements I made about it not being my code or comments.

Having said that..

I do appreciate your reply and will attempt to implement your suggestions on the internal resistor and removing the LCD delay. I believe you are also correct on completely removing the interrupts... of course implementing that suggestion might be a problem for me.

I wrote an extended example of the blink without delay technique in the first post in this Thread.

In general interrupts are only essential if you need precision of the order of microseconds.

...R

The Uno supports interrupts on every pin via the pin-change interrupt mechanism,
as well as the two "external interrupt" pins D2 and D3. Pin change interrupts have
the granularity of a port, not a pin, so you have to write code in the handler
to investigate what change happened.

To detect human input an interrupt is overkill, its much neater just to look at
the pin with digitalRead() in loop().

Interrupts are useful when dealing with frequent or urgent events (think 1kHz
or above, microseconds).

Thanks Robin and Mark!

Your demo looks very helpful to me in general Robin I bookmarked it and plan on looking at it tonight. I definitely want to get away from the interrupts. I'm going to try to rewrite the code a bit tonight. But I will probably be back with more questions.