Step Up / Down Variable (Target Temperature) with Buttons

Hey guys, I'm working on a new project where I am building a fermentation chamber for making beer.

I was hoping someone had a suggestions as to how I can use two buttons to adjust a target temperature variable. I would basically like to kick on a fan when above a target temperature and in the future I will attach a relay and turn on a heat mat if below the target temperature. I've attached the code below and I will have 2 buttons and a LCD monitor. When the program starts it will start by creating a targetTemp variable at 68 degrees. Then I would like to have two buttons (one to increase and one to decrease the targetTemp). I tried putting together what I thought would work, but it is not actually changing the target temp. Any help you could provide would be great.

Thanks,

Craig

// Kegerator Temperature Monitor

// Included libraries
#include <OneWire.h>                // For DS18b20 temp sensor
#include <DallasTemperature.h>      // Simplifies reading of temp
#include <Wire.h>                   // Communicate with I2C / TWI devices
#include <LiquidCrystal_I2C.h>      // For SainSmart IIC/I2C/TWI Serial 2004 LCD

LiquidCrystal_I2C lcd(0x27,20,4);   // Sets LCD to 20 Columns by 4 Rows

#define tempSensor 2                // Temperature sensor is plugged into pin 2 on the Arduino 
  OneWire oneWire(tempSensor);      // Setup a oneWire instance to communicate with any OneWire devices  
  DallasTemperature sensors(&oneWire); // Pass oneWire reference to Dallas Temperature.

  const int FanPin = 11;            // Fan pin
  const int  buttonUp = 7;          // Up Button pin
  const int  buttonDown = 6;        // Down Button pin
  int targetTemp = 68;              // Define a target temp when Arduino resets
  
void setup(void) 
{ 
  lcd.init();                       // initialize the lcd 
  lcd.backlight();
  Serial.begin(9600);
  sensors.begin();                  // turn on sensors for DS18b20
  pinMode(buttonUp, INPUT);         // Set INCREASE button to input
  pinMode(buttonDown, INPUT);       // Set DECREASE button to input
  pinMode(FanPin, OUTPUT);          // Set Fan motor to output
  lcd.setCursor(0,0);               // Set LCD cursor to first cursor spot
  lcd.print("Temperature");         // Print "Temperature" to cursor spot on LCD
} 
void loop(void) 
{ 
  sensors.requestTemperatures();    // Get temperature readings

  lcd.setCursor(2,1);
  lcd.print(sensors.getTempFByIndex(0));  // Print actual temperature 

  // Write to Serial for Testing
  Serial.println("Actual Temperature");
  Serial.println(sensors.getTempFByIndex(0));

  // Increase target temp
  if (buttonUp == HIGH) {
      targetTemp = ++targetTemp;     // If button is pushed, move Target Temp up by 1
    } else {
  }
  
  // Decrease target temp
  if (buttonDown == HIGH) {
      targetTemp = --targetTemp;    // If button is pushed, move Target Temp down by 1
    } else {
  }
  
  Serial.println("Target Temperature");
  Serial.println(targetTemp);

  // Cooling Element
  // Turn on Fan if temp is below target temperature
  if (sensors.getTempFByIndex(0) > targetTemp) {
    analogWrite(FanPin, 255);
  } else {
    analogWrite(FanPin, 0);
  }

   delay(1000); 
}
  pinMode(buttonUp, INPUT);         // Set INCREASE button to input
  pinMode(buttonDown, INPUT);       // Set DECREASE button to input

Are the switches wired properly, with pullup or pulldown resistors?

  if (buttonUp == HIGH) {

In my part of the solar system, 7 does not equal 1. In yours, maybe?

Or, perhaps you meant to call digitalRead() somewhere...

Hey Paul,

Thanks for the quick response. I am not sure what you meant about the solar system quote, but I'm guessing that you're inferring that there is something fundamentally wrong with my code. I believe that the buttons are wired correctly as I used one of the Arduino tutorials using a pullup resistor, but my guess is that the code is incorrect.

My goal was to read if the buttonUp is pressed, then to increase the targetTemp. Do I need to make it say digitalRead(buttonUp)?

Thanks for the help. Also, if there is a different way which you'd recommend doing this, I am all for suggestions. I just tried to make up how I thought it should work.

Craig

Paul, let me know if you think this should fix it. I probably did forget the digitalRead...

// Kegerator Temperature Monitor

// Included libraries
#include <OneWire.h>                // For DS18b20 temp sensor
#include <DallasTemperature.h>      // Simplifies reading of temp
#include <Wire.h>                   // Communicate with I2C / TWI devices
#include <LiquidCrystal_I2C.h>      // For SainSmart IIC/I2C/TWI Serial 2004 LCD

LiquidCrystal_I2C lcd(0x27,20,4);   // Sets LCD to 20 Columns by 4 Rows

#define tempSensor 2            // Temperature sensor is plugged into pin 2 on the Arduino 
  OneWire oneWire(tempSensor);      // Setup a oneWire instance to communicate with any OneWire devices  
  DallasTemperature sensors(&oneWire); // Pass oneWire reference to Dallas Temperature.

  const int FanPin = 11;            // Fan pin
  const int  buttonUp = 7;          // Up Button pin
  const int  buttonDown = 6;        // Down Button pin
  int targetTemp = 68;              // Define a target temp when Arduino resets
  
void setup(void) 
{ 
  lcd.init();                       // initialize the lcd 
  lcd.backlight();
  Serial.begin(9600);
  sensors.begin();                  // turn on sensors for DS18b20
  pinMode(buttonUp, INPUT);         // Set INCREASE button to input
  pinMode(buttonDown, INPUT);       // Set DECREASE button to input
  pinMode(FanPin, OUTPUT);          // Set Fan motor to output
  lcd.setCursor(0,0);               // Set LCD cursor to first cursor spot
  lcd.print("Temperature");         // Print "Temperature" to cursor spot on LCD
} 
void loop(void) 
{ 

  sensors.requestTemperatures();    // Get temperature readings

  lcd.setCursor(2,1);
  lcd.print(sensors.getTempFByIndex(0));  // Print actual temperature 

  // Write to Serial for Testing
  Serial.println("Actual Temperature");
  Serial.println(sensors.getTempFByIndex(0));

  // Increase target temp
  if (digitalRead(buttonUp) == HIGH) {
      targetTemp = ++targetTemp;     // If button is pushed, move Target Temp up by 1
    } else {
  }
  
  // Decrease target temp
  if (digitalRead(buttonDown) == HIGH) {
      targetTemp = --targetTemp;    // If button is pushed, move Target Temp down by 1
    } else {
  }
  
  Serial.println("Target Temperature");
  Serial.println(targetTemp);

  // Cooling Element
  // Turn on Fan if temp is below target temperature
  if (sensors.getTempFByIndex(0) > targetTemp) {
    analogWrite(FanPin, 255);
  } else {
    analogWrite(FanPin, 0);
  }

   delay(1000); 
}
      targetTemp = ++targetTemp;     // If button is pushed, move Target Temp up by 1

This is undefined behavior. Use one of:

   targetTemp = targetTemp + 1;
   targetTemp += 1;
   targetTemp++;
 else {
  }

Useless.

  if (sensors.getTempFByIndex(0) > targetTemp) {

You already got the temperature when you wanted to print it. Do it ONCE. Save the value in a variable. Print the variable's contents. Compare the variable's value in this if statement.

  if (sensors.getTempFByIndex(0) > targetTemp) {
    analogWrite(FanPin, 255);
  } else {
    analogWrite(FanPin, 0);
  }

Your fan will bang on and off as the ambient temperature is close to the set point. Google hysteresis.

1 Like