Including push-button to thermometer

Hi guys,

I'm new to arduino and doing my first project at the moment. It's a thermometer and now I've ran into a problem while trying to add push-button to it.

Push-button should be used to choose if the sensor is active or not: active when pressed, not active when pressed again. Also an extra LED should be indicating the state of the button: ON = sensor active; OFF = sensor not active.

I've tried to find different ways to solve this (while, if/else) but can't get the system working. I got the button working fine with if and else statements but it made the sensor read only one value while it wasn't pressed, and different value when pressed.

All the help is appreciated since I'm kinda out of ideas now.

Here is what I've managed to do so far:

// set variables
int sensorVal;
int heartBeat = 0;
int blinkingMIN = 0;
int blinkingMAX = 0;

unsigned long timer1;
unsigned long timer2;
unsigned long timer3;
unsigned long timer4;

const int sensorPin = A0;                 // the number of pin for the temperature sensor (analog input)
const float roomTemp = 21.0;              // room temperature in Celsius
float temperature;

void setup() {
  // open a serial connection to display values
  Serial.begin(9600);
  // set the LED pins as outputs
  pinMode(13, OUTPUT);
  for (int pinNumber = 2; pinNumber < 8; pinNumber++) {
    pinMode(pinNumber, OUTPUT);
    digitalWrite(pinNumber, LOW);
  }

  //LED test at startup
  digitalWrite(2,HIGH);
  delay(100);
  digitalWrite(3,HIGH);
  delay(100);
  digitalWrite(4,HIGH);
  delay(100);
  digitalWrite(5,HIGH);
  delay(100);
  digitalWrite(6,HIGH);
  delay(100);
  digitalWrite(7,HIGH);
  delay(500);
  digitalWrite(7,LOW);
  digitalWrite(6,LOW);
  digitalWrite(5,LOW);
  digitalWrite(4,LOW);
  digitalWrite(3,LOW);
  digitalWrite(2,LOW);
  delay(500);
}

void loop() {
  // Make the LED blink
  if (millis() - timer1 > 500){
    heartBeat = !heartBeat;
    digitalWrite (13, heartBeat);
    timer1 = millis();
  }

  // update sensor value at 1Hz and print the values to serial monitor
  if(millis() - timer2 > 1000) {
    sensorVal = analogRead(sensorPin);
    temperature = (5.0 * sensorVal * 100.0) / 1024;
    Serial.print("degrees C:  ");
    Serial.println(temperature);
    timer2 = millis();
  }
  
  // if the current temperature is lower than the roomTemp: turn off all LEDs and blink the LED in pin 2 -> temperature under minimum value
  if (temperature < roomTemp + 2) {
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);

  // Make the LED blink
  if (millis() - timer3 > 500){
    blinkingMIN = !blinkingMIN;
    digitalWrite (2, blinkingMIN);
    timer3 = millis();  
    }
  }
  
  // if the temperature rises 2-3 degrees: turn an LED on
  else if (temperature >= roomTemp + 2 && temperature < roomTemp + 3) {
    digitalWrite(2, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 3-4 degrees: turn a second LED on
  else if (temperature >= roomTemp + 3 && temperature < roomTemp + 4) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(3, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 4-5 degrees: turn a third LED on
  else if (temperature >= roomTemp + 4 && temperature < roomTemp + 5) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 5-6 degrees: turn a fourth LED on
  else if (temperature >= roomTemp + 5 && temperature < roomTemp + 6) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 6-7 degrees, turn a fifth LED on
  else if (temperature >= roomTemp + 6 && temperature < roomTemp + 7) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature goes 7 degrees over the roomTemp: turn on all LEDs and blink the led in pin 7 -> maximum value has been crossed
  else if (temperature >= roomTemp + 7) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
 
   // Make the LED blink
   if (millis() - timer4 > 500) {
     blinkingMAX = !blinkingMAX;
     digitalWrite (7, blinkingMAX);
     timer4 = millis();  
   }
  }
}

The code you posted doesnt appear to have any pushbutton functionality. It would be useful to include the code you had tried..

The basic scheme is pretty simple :

// this doesnt take into account switch bounce
current_button=digitalRead(BUTTON_PIN);

if (current_button!=previous_button) {
   if (current_button==HIGH) {
     // button is pressed
     if (sensor_state==HIGH) {
        // was HIGH, going low so turn off sensor, LEDS etc

         sensor_state = LOW;
     } else {
         // was LOW, going high so turn on sensor, LEDS ect

          sensor_state = HIGH;
     };
   // update button state so we dont trigger until it changes again.
   previous_button=current_button;     
};

But you may need to account for Switch Bounce

rw950431:
The code you posted doesnt appear to have any pushbutton functionality. It would be useful to include the code you had tried..

The basic scheme is pretty simple :

// this doesnt take into account switch bounce

current_button=digitalRead(BUTTON_PIN);

if (current_button!=previous_button) {
  if (current_button==HIGH) {
    // button is pressed
    if (sensor_state==HIGH) {
        // was HIGH, going low so turn off sensor, LEDS etc

sensor_state = LOW;
    } else {
        // was LOW, going high so turn on sensor, LEDS ect

sensor_state = HIGH;
    };
  // update button state so we dont trigger until it changes again.
  previous_button=current_button;   
};





But you may need to account for [Switch Bounce](https://www.arduino.cc/en/Tutorial/Debounce)

Hey rw and thank for the answer!

Here is the code with push-button function included

// set variables
int sensorVal;
int heartBeat = 0;
int blinkingMIN = 0;
int blinkingMAX = 0;

unsigned long timer1;
unsigned long timer2;
unsigned long timer3;
unsigned long timer4;

const int sensorPin = A0;                 // the number of pin for the temperature sensor (analog input)
const float roomTemp = 21.0;              // room temperature in Celsius
float temperature;

int button = 11;
int tempSensorEnabled = 0;
boolean previousButtonState = LOW;
boolean buttonState = LOW;

void setup() {

  pinMode(button, INPUT);
  pinMode(sensorPin, OUTPUT);
  
  // open a serial connection to display values
  Serial.begin(9600);
  // set the LED pins as outputs
  pinMode(13, OUTPUT);
  for (int pinNumber = 2; pinNumber < 8; pinNumber++) {
    pinMode(pinNumber, OUTPUT);
    digitalWrite(pinNumber, LOW);
  }

  //LED test at startup
  digitalWrite(2,HIGH);
  delay(100);
  digitalWrite(3,HIGH);
  delay(100);
  digitalWrite(4,HIGH);
  delay(100);
  digitalWrite(5,HIGH);
  delay(100);
  digitalWrite(6,HIGH);
  delay(100);
  digitalWrite(7,HIGH);
  delay(500);
  digitalWrite(7,LOW);
  digitalWrite(6,LOW);
  digitalWrite(5,LOW);
  digitalWrite(4,LOW);
  digitalWrite(3,LOW);
  digitalWrite(2,LOW);
  delay(500);

}
void loop() {

  buttonState = digitalRead(button);

  if(previousButtonState != buttonState && buttonState == HIGH){
    tempSensorEnabled = !tempSensorEnabled;
    }
  if(tempSensorEnabled == 1){
    digitalWrite(sensorPin,HIGH);
    }
  else{
    digitalWrite(sensorPin,LOW);
    }
  previousButtonState = buttonState;

  // Make the LED blink
  if (millis() - timer1 > 500){
    heartBeat = !heartBeat;
    digitalWrite (13, heartBeat);
    timer1 = millis();
  }

  // update sensor value at 1Hz and print the values to serial monitor
  if(millis() - timer2 > 1000) {
    sensorVal = analogRead(sensorPin);
    temperature = (5.0 * sensorVal * 100.0) / 1024;
    Serial.print("degrees C:  ");
    Serial.println(temperature);
    timer2 = millis();
  }
  
  // if the current temperature is lower than the roomTemp: turn off all LEDs and blink the LED in pin 2 -> temperature under minimum value
  if (temperature < roomTemp + 2) {
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);

  // Make the LED blink
  if (millis() - timer3 > 500){
    blinkingMIN = !blinkingMIN;
    digitalWrite (2, blinkingMIN);
    timer3 = millis();  
    }
  }
  
  // if the temperature rises 2-3 degrees: turn an LED on
  else if (temperature >= roomTemp + 2 && temperature < roomTemp + 3) {
    digitalWrite(2, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 3-4 degrees: turn a second LED on
  else if (temperature >= roomTemp + 3 && temperature < roomTemp + 4) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(3, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 4-5 degrees: turn a third LED on
  else if (temperature >= roomTemp + 4 && temperature < roomTemp + 5) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 5-6 degrees: turn a fourth LED on
  else if (temperature >= roomTemp + 5 && temperature < roomTemp + 6) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 6-7 degrees, turn a fifth LED on
  else if (temperature >= roomTemp + 6 && temperature < roomTemp + 7) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature goes 7 degrees over the roomTemp: turn on all LEDs and blink the led in pin 7 -> maximum value has been crossed
  else if (temperature >= roomTemp + 7) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
 
   // Make the LED blink
   if (millis() - timer4 > 500) {
     blinkingMAX = !blinkingMAX;
     digitalWrite (7, blinkingMAX);
     timer4 = millis();  
   }
  }
}

Problem is that when the button is not pressed, serial monitor reads the sensor value for 15 degrees C. When the button is pressed again the value is 499 degrees C until I press the button again and it jumps back to 15.

Any idea why that happens?

You set your sensorPin as an OUTPUT (while it should be an INPUT).

Then when enabled it's written HIGH, disabled it's written LOW.

After that you try to read from that pin regardless of whether you have it enabled - so naturally when enabled it now returns 1023, when disabled it returns 0 or values very close to that.

Set it to INPUT, then don't try to write to it but instead take your readings based on whether it's enabled or not.

Thanks marle!

Could you give me an example how to do this:

wvmarle:
..... then don't try to write to it but instead take your readings based on whether it's enabled or not.

I'm kinda new to programming in general so I'm really not familiar with all the terms and ways to do stuff :slight_smile:

Hi,
Welcome to the forum.

Why do you want to disable the sensor?
What reading do you want to see when you have disabled it?

Thanks.. Tom.. :slight_smile:

TomGeorge:
Hi,
Welcome to the forum.

Why do you want to disable the sensor?
What reading do you want to see when you have disabled it?

Thanks.. Tom.. :slight_smile:

Hi Tom!

Later on I'm adding another sensor to the system (haven't decided which one yet). So the idea later is to change which sensor is reading by pushing the button. Since I don't have the sensor yet, I'd like to try this first. :slight_smile:

Hi,

When you say "disable" do you want to turn the sensor OFF or just disregard its output?

Why can't you read both sensors one after the other, you have enough inputs.

If you have limited output display, then you don't need to disable the sensor, just read the other sensor output variable to the display.

Tom... :slight_smile:

TomGeorge:
Why can't you read both sensors one after the other, you have enough inputs.

Hi,

So this is a school project and I can't really bend the rules how to do this :slight_smile:
Here is the requirement for the button:
Button is used to choose which sensor is active. Every time button is pressed, the system should switch to indicate the measured values of the other sensor.

Thanks, Jonathan :slight_smile:

Hi,
I see, all you need to do is when you press the button, you change which input variable you read to your output.

I would say "which sensor is active" is a bad choice of words.

Go back to your teacher/instructor and get clarification.

Tom... :slight_smile:

I would read "active" as "the one that's in use" - regardless of whether it's powered on. Just read from the selected sensor and ignore the other.

Hi,

Okay thanks for the help guys!

TomGeorge:
I see, all you need to do is when you press the button, you change which input variable you read to your output.

wvmarle:
I would read "active" as "the one that's in use" - regardless of whether it's powered on. Just read from the selected sensor and ignore the other.

Any suggestions how to approach these?

As suggested in #9.
Count button presses or so, rotate through your sensors.

wvmarle:
As suggested in #9.
Count button presses or so, rotate through your sensors.

Sure but I'm really not sure how to do it. Could you maybe give an example?

Thanks.

if (digitalRead(button)) {
  selectedSensor++;
  if (selectedSensor > 3) selectedSensor = 1;
}
switch selectedSensor {
  case 1:
    readSensor(sensor1pin);
    break;
  case 2:
    readSensor(sensor2pin);
    break;
  case 3:
    readSensor(sensor3pin);
    break;
}

Do debounce your button (either in hardware or software - plenty of examples out there). I assume same sensor on all pins, so you just have to provide the correct pin and read that sensor. Change the number of sensors to your number.

wvmarle:

if (digitalRead(button)) {

selectedSensor++;
  if (selectedSensor > 3) selectedSensor = 1;
}
switch selectedSensor {
  case 1:
    readSensor(sensor1pin);
    break;
  case 2:
    readSensor(sensor2pin);
    break;
  case 3:
    readSensor(sensor3pin);
    break;
}




Do debounce your button (either in hardware or software - plenty of examples out there). I assume same sensor on all pins, so you just have to provide the correct pin and read that sensor. Change the number of sensors to your number.

Yup I've learnt how to debounce :slight_smile: thanks for the example, I'll give it a go when I get my hands on the 2nd sensor!

wvmarle:
Do debounce your button (either in hardware or software - plenty of examples out there). I assume same sensor on all pins, so you just have to provide the correct pin and read that sensor. Change the number of sensors to your number.

So, I've got the 2nd sensor now and everything seems to be working OK apart from the button. It's working randomly so I think the problem is with the debouncing.

Any ideas what did I do wrong? :slight_smile: :slight_smile:

Here is the whole code:

#include <Servo.h> // include Servo library

Servo myServo; 


int sensorValueTemp;      
int heartBeat = 0;
int blinkingMIN = 0;
int blinkingMAX = 0;
int angle1;                   // angle to be rotated by servo when sensing temperature
int angle2;                   // angle to be ratated by servo when sensing humidity
int buttonState = LOW;
int ledState = 0;
int selectedSensor;
int sensorValHum;

const int humiditySensor = A1;    // pin connected to humidity sensor
const int tempSensor = A0;        // pin connected to temperature sensor
const int button = 11;            // push-button attached to this pin
const int led = 12;               // which sensor is reading; ON=temperature, OFF=humidity

float temperature;
float voltage;
float sensorRH;
float trueRH;

const float roomTemp = 21;

unsigned long timer1;
unsigned long timer2;
unsigned long timer3;
unsigned long timer4;
unsigned long timer5;
unsigned long lastDebounceTime1 = 0;
unsigned long lastDebounceTime2 = 0;

void setup() {
  
  myServo.attach(9,480,2240);                   // (servo attached to pin 9, minimum pulse, servo maximum pulse)
  Serial.begin(9600);                           // open a serial connection to display values

  // set the LED button and sensors as inputs
  pinMode(button, INPUT);
  pinMode(tempSensor, INPUT);
  
  // set the LED pins as outputs
  pinMode(13, OUTPUT);
  pinMode(led, OUTPUT);
  for (int pinNumber = 2; pinNumber < 8; pinNumber++) {
    pinMode(pinNumber, OUTPUT);
    digitalWrite(pinNumber, LOW);
  }
  
  //LED test at startup
  digitalWrite(2,HIGH);
  delay(100);
  digitalWrite(3,HIGH);
  delay(100);
  digitalWrite(4,HIGH);
  delay(100);
  digitalWrite(5,HIGH);
  delay(100);
  digitalWrite(6,HIGH);
  delay(100);
  digitalWrite(7,HIGH);
  delay(500);
  digitalWrite(7,LOW);
  digitalWrite(6,LOW);
  digitalWrite(5,LOW);
  digitalWrite(4,LOW);
  digitalWrite(3,LOW);
  digitalWrite(2,LOW);
  delay(500);
}

void loop() {
  // Make the LED blink
  if (millis() - timer1 > 500){
    heartBeat = !heartBeat;
    digitalWrite (13, heartBeat);
    timer1 = millis();
  }

  buttonState = digitalRead(button);

  if(digitalRead(button)) {
    selectedSensor++;
      if(selectedSensor > 2)
        selectedSensor = 1;
  }

  switch(selectedSensor) {

  case 1:
  analogRead(tempSensor);
  
  if(millis() - lastDebounceTime1 > 100) {
    if((buttonState == HIGH) && (ledState < 0)) {
      digitalWrite(led, HIGH);
      ledState = !ledState;
      lastDebounceTime1 = millis();
    }
    else if((buttonState == HIGH) && (ledState > 0)) {
      digitalWrite(led, LOW);
      ledState = !ledState;
      lastDebounceTime2 = millis();
    }
  }
  
  // update sensor value at 1Hz and print the values to serial monitor
  if(millis() - timer2 > 1000) {
    sensorValueTemp = analogRead(tempSensor);
    temperature = (5.0 * sensorValueTemp * 100.0) / 1024;
    Serial.print("degrees C:  ");
    Serial.println(temperature);
    timer2 = millis();
    
    angle1 = map(temperature, 21, 28, 0, 180); // we map sensorValue between min and max and 0 and 180º
    myServo.write(angle1);
  }
 
  // if the current temperature is lower than the roomTemp: turn off all LEDs and blink the LED in pin 2 -> temperature under minimum value
  if (temperature < roomTemp + 2) {
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);

  // Make the LED blink
  if (millis() - timer3 > 500){
    blinkingMIN = !blinkingMIN;
    digitalWrite (2, blinkingMIN);
    timer3 = millis();  
    }
  }
  
  // if the temperature rises 2-3 degrees: turn an LED on
  else if (temperature >= roomTemp + 2 && temperature < roomTemp + 3) {
    digitalWrite(2, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 3-4 degrees: turn a second LED on
  else if (temperature >= roomTemp + 3 && temperature < roomTemp + 4) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(3, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 4-5 degrees: turn a third LED on
  else if (temperature >= roomTemp + 4 && temperature < roomTemp + 5) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 5-6 degrees: turn a fourth LED on
  else if (temperature >= roomTemp + 5 && temperature < roomTemp + 6) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature rises 6-7 degrees, turn a fifth LED on
  else if (temperature >= roomTemp + 6 && temperature < roomTemp + 7) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, LOW);
  } 
  
  // if the temperature goes 7 degrees over the roomTemp: turn on all LEDs and blink the led in pin 7 -> maximum value has been crossed
  else if (temperature >= roomTemp + 7) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    
   // Make the LED blink
   if (millis() - timer4 > 500) {
     blinkingMAX = !blinkingMAX;
     digitalWrite (7, blinkingMAX);
     timer4 = millis();  
   }
  }
    break;
  case 2:
  analogRead(humiditySensor);

    if(millis() - lastDebounceTime2 > 100) {
    if((buttonState == HIGH) && (ledState < 0)) {
      digitalWrite(led, HIGH);
      ledState = !ledState;
      lastDebounceTime2 = millis();
    }
    else if((buttonState == HIGH) && (ledState > 0)) {
      digitalWrite(led, LOW);
      ledState = !ledState;
      lastDebounceTime2 = millis();
    }
  }
    if(millis() - timer5 > 1000){
    // read the sensor:
    sensorValHum = analogRead(humiditySensor);
    // convert to voltage:
    voltage = (5.0 * sensorValHum) / 1024.0;
    sensorRH = (voltage - 0.958) / 0.03068;
    trueRH = (sensorRH) / (1.0546 - 0.00216 * 21);
    // print the results:
    Serial.print("Humidity: ");
    Serial.print(trueRH);
    Serial.println("%");
    timer5 = millis();

    angle2 = map(trueRH, 0, 100, 0, 180);
    myServo.write(angle2);
  }
   break;  
 }
}

Thanks, Jonathan

I can see a possible problem in your debounce code

if((buttonState == HIGH) && (ledState < 0))

I believe ledState will be either 0 or 1 so the ledState test will always fail.

Perhaps try
i

f((buttonState == HIGH) && (!ledState))