0

I am trying to create a circuit with one tactile pushbutton, and LCD and two sensors: 1) temperature, and 2) pulse sensor. When the circuit is on, the LCD initially shows the reading from the temp sensor, when the button is pressed the LCD shows the reading from the pulse sensor.

The code compiles, the LCD shows both of the temperature function and pulse reading work.

I attached a picture of the schematic of the circuit.

The problem is that when the button is pressed, it takes many pushing of the button for the circuit to go from temperature reading to pulse reading. I thought maybe debouncing the button was unnecessary so I tried to write a code without the code, but it made no difference. My coding skills are still in the beginner side but I am trying my best for my coding to make sense. I just need some guidance and advice on what the problem could be and how I can tackle the problem. My code is attached here:

#include <LiquidCrystal.h>
#define BUTTON 2

const int rs = 12, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

//TEMPERATURE
const int tempPin = A0;              // LM35 in A0

int T1=60;

//PULSE
#define USE_ARDUINO_INTERRUPTS true    // Set-up low-level interrupts for most acurate BPM math.
#include <PulseSensorPlayground.h>     // Includes the PulseSensorPlayground Library. 

int PulseWire = A1;                 // Pulse Sensor purple wire connected to analog pin A0
int blinkPin = 13;                // pin to blink led at each beat
int Threshold = 550;           // Determine which Signal to "count as a beat" and which to ignore.
// Use the "Gettting Started Project" to fine-tune Threshold Value beyond default setting.
// Otherwise leave the default "550" value.
PulseSensorPlayground pulseSensor;  // Creates an instance of the PulseSensorPlayground object called "pulseSensor"


//=========BUTTON DEBOUNCE============
boolean lastButton = LOW;     // last button state
boolean currentButton = LOW; // current button state
int switchMode = 1;             //cycle between function
//====================================
void setup()
{

  lcd.begin(16, 2);
  // Configure the PulseSensor object, by assigning our variables to it.
  pulseSensor.analogInput(PulseWire);
  //pulseSensor.blinkOnPulse(LED13);       //auto-magically blink Arduino's LED with heartbeat.
  pulseSensor.setThreshold(Threshold);

  // Double-check the "pulseSensor" object was created and "began" seeing a signal.
  if (pulseSensor.begin()) {
    Serial.println("We created a pulseSensor Object !");  //This prints one time at Arduino power-up,  or on Arduino reset.

  }//end if

}//end void setup()

//Debouncing Function
boolean debounce(boolean last) {
  boolean current = digitalRead(BUTTON);
  if (last != current)
  {
    delay(T1);         //wait #ms
    current = digitalRead(BUTTON); //read it again
  }//end if
  return current;     //return the current value
}//end boolean debounce

void setMode(int mode) {

  //TEMP ON
  if (mode == 1)
  {
    Serial.begin(9600);
    int value = analogRead(tempPin); // read the value from the sensor
    lcd.setCursor(0, 1);
    float millivolts = (value / 1024.0) * 5000;
    float celsius = millivolts / 10;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Temp = "); lcd.print((celsius * 9) / 5 + 32);  lcd.print((char) 223); //turning the celsius into fahrehait
    lcd.print("F");
    lcd.setCursor(7, 2);
    lcd.print(celsius); lcd.print((char) 223);
    lcd.print("C");
    delay(1600);

    lcd.clear();
    delay(T1);
  }//end if TEMP ON

  //RED ON
  else if (mode == 2) {
    {
      Serial.begin(9600);
      int myBPM = pulseSensor.getBeatsPerMinute();  // Calls function on our pulseSensor object that returns BPM as an "int".
      // "myBPM" hold this BPM value now.

      if (pulseSensor.sawStartOfBeat()) {            // Constantly test to see if "a beat happened".
        Serial.println("♥  A HeartBeat Happened ! "); // If test is "true", print a message "a heartbeat happened".
        Serial.print("BPM: ");                        // Print phrase "BPM: "
        Serial.println(myBPM);                        // Print the value inside of myBPM.

        lcd.setCursor(0, 0);
        lcd.print("HeartBeat Found!");
        lcd.setCursor(4, 1);
        lcd.print("BPM: "); lcd.print(myBPM);

        delay(1600);
        lcd.clear();
        delay(T1);
      }//end if
    }//end setMode void function
  }
}
    void loop()
    {
      currentButton = debounce(lastButton); //read debounced state
      if (lastButton == LOW && currentButton == HIGH) /// if it was pressed
      {
        switchMode++;
      }
      //if cycled through the different options,
      //reset the counter to 0
      if (switchMode == 3) switchMode = 1;
      setMode(switchMode);
    }//end loop

enter image description here

I also considered doing a switch case statement, but so far it hasn't worked either. Please let me know some ideas!

Thank you!!

2
  • While we wait for 1 more person to approve the edits made to this question... @LG_18, You need to research what a state machine is and apply that to de-bouncing your button.
    – st2000
    Feb 4, 2019 at 0:10
  • the code that you posted does not compile (@matej made some corrections) ..... i think that the code on your computer also does not compile ...... i also think that you are editing your code, and you think that you are compiling and uploading after the edit, but the compile fails and your arduino does not get updated with a new sketch ..... then you run a test on the arduino and it still behaves as it did before
    – jsotola
    Feb 4, 2019 at 0:58

2 Answers 2

1

Your code has various issues, but the main one is that you can’t use delay() when you’re trying to more than one thing at a time. Delay causes your program to freeze, and not do anything else.

(Basically you should forget about the delay() function and never write any Arduino code that uses it. It is a code smell.)

You need to rewrite your code to record the value of millis() and then check back the next time through your loop function to see if enough time has passed. Do a Google search on “Arduino blink without delay” for an explanation of how to do this. Here’s an example article: https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing

(Note that some solutions suggest that you increment a counter every time through your loop and see if some magic number of counts has gone past based on how frequently you expect your loop to be called. That is a bad approach. You want to use the millis() function.

1
  • Also note that you should not call Serial.begin() more than once in your program. You should put that code in your setup function.
    – Duncan C
    Feb 4, 2019 at 15:06
0

Your loop function needs to call debounce() and setMode() as often as possible, and none of your functions must use delay(). Instead, they compute the time elapsed since the last action, and if it is greater than what you now use as a delay value, perform its next action; otherwise, it should just return.

Just as a curiosity, your present code will probably function (better...) if you press and hold the button until you get a response, instead of press-and-releasing multiple times, hoping to get one. The latter way depends on your pressing the button just as the system is reading it, but the system reads it too infrequently for that to be workable, as you found out. The delay() calls are the reason.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.