0

I don't know why but when a pin set to input mode receives a high signal, then a low signal, it stays high for a seemingly random amount of time.

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
int thermPin = A5;
int relayPin = 9;
int upButton = 10;
int downButton = 11;
int rawVoltage;
float mv;
float desiredTemp = 20.5;
float currentTemp = 20;
long newSetTime = millis();
long oldSetTime = newSetTime;
long newUpPushTime = millis();
long newDownPushTime = millis();
long oldUpPushTime = millis();
long oldDownPushTime = millis();
int mainDelay = 600;
int flashDelay = 600;
boolean isSetting = true;

void drawCurrentTemp(){
  lcd.setCursor(0, 1);
  lcd.print(currentTemp);
}

void drawDesiredTemp(){
  lcd.setCursor(12, 1);
  lcd.print(desiredTemp);
}

void drawMainScreen(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("TEMP");
  lcd.setCursor(12, 0);
  lcd.print("SET");
  drawCurrentTemp();
  drawDesiredTemp();
}
String setString = "SET";
void flashSet(){
  if(newSetTime - oldSetTime > flashDelay) {
    if(setString == "SET"){
      setString = "   ";
    }else{
      setString = "SET";
    }
    lcd.setCursor(12, 0);
    lcd.print(setString);
    oldSetTime = millis();
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();
  pinMode(relayPin, OUTPUT);
  pinMode(upButton, INPUT);
  pinMode(downButton, INPUT);
  drawMainScreen();
}

void checkInput(){
  if(digitalRead(upButton) == HIGH){
    newUpPushTime = millis();
  } else {
    oldUpPushTime = millis();
  }
  if(digitalRead(downButton) == HIGH){
    newDownPushTime = millis();
  } else {
    oldDownPushTime = millis();
  }
  long upButtonTimePushed = newUpPushTime - oldUpPushTime;
  long downButtonTimePushed = newDownPushTime - oldDownPushTime;
  if(upButtonTimePushed > 1000 && downButtonTimePushed > 1000) {
    oldDownPushTime = millis();
    oldUpPushTime = millis();
    if(!isSetting){
      isSetting = true;
    } else {
      isSetting = false;
      drawMainScreen();
    }
  }
  if(isSetting){
    if(digitalRead(upButton) == HIGH) {
      desiredTemp +=0.5;
    } else if(digitalRead(downButton) == HIGH) {
      desiredTemp -=0.5;
    }
    drawDesiredTemp();
  }
}

void loop() {
  newSetTime = millis();
  if(isSetting) {
    flashSet();
  }
  checkInput();
  Serial.println(digitalRead(upButton));
}
2
  • Could it be because you don't have a pulldown / pullup resistor to force the input into a known state when there is no "signal"...? Show your circuit.
    – Majenko
    Jul 2, 2015 at 12:56
  • yes :) I just found out about the pullup resistors and how exactly the INPUT works its all fixed now thanks :) i just made them pinMode(pin, INPUT_PULLUP);
    – Syntaxis
    Jul 2, 2015 at 13:05

2 Answers 2

4

I ran across this post and thought that a more in depth explanation should be given on why when using digital inputs that more times than not you will need to use the pull-up resistors.

When you define one of the pins to be a input the chip measures the voltage on the pins, if the voltage measures more than half of the VCC voltage the input is off. What happens if you don't use a Pull-up Resistor the chip will measure a seemingly random voltage. This is because of interference from other electronics, radio waves etc.

So what happens when you use a high resistance Resistor (10 - 100 ohms) it forces the voltage to remain high if the pin is not grounded since there is voltage being applied. But when you ground the pin using a Button or whatever the pin is kept under the halfway mark around 0V.

As you mentioned using the code:

pinMode(PIN, INPUT_PULLUP);

enables the internal Pull-Up Resistors in the chip by setting the Pin to a High state like you would defining it as a output. The code above is a newer way of writing:

pinMode(PIN, INPUT);
digitalWrite(PIN, HIGH);

Now there is another reason for seemingly random input signals, which is called "Button Bounce". What happens here is when a User presses the Button there might be a very small time that the Button actually connects then disconnects then finally reconnects. This is because of when the contacts of the Switch come together sometimes they don't connect perfectly, one side of the Switch might connect then be disconnected as the connecting plate levels out before finally connecting as it should.

Below is a Snapshot I found from http://www.gammon.com.au, it shows a bounce from a Osillicope showing the actual Button Bounce:

Button Bounce

To make sure that the user is actually pressing the button use a delay and recheck the Button again to see if it is still pressed. I find that a 500 - 700 microsecond delay works great. I provided a quick example on how to catch a Button Bounce (https://www.arduino.cc):

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // 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 (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;
}

I hope that this explanation will help others out saving them from banging their heads against the wall trying to figure out where these phantom signals are coming from.

1

Comment by Glen Cashen turned into an answer:

I just found out about the pullup resistors and how exactly the INPUT works it's all fixed now thanks :)

I just made them:

 pinMode(pin, INPUT_PULLUP);

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.