How to print the state of a pin only when it is changed

I want to get the state of a pin and print it in the serial monitor but only when it has changed.

i tried doing it like this:

int valve = 4;
int savedState;
int valveState;

void setup() {
  Serial.begin(115200);
  pinMode(valve, INPUT);
  savedState = digitalRead(valve);
}

void loop() {
  if (digitalRead(valve) != savedState) {
    savedState = digitalRead(valve);
    Serial.println(valveState);
  }
}

it doesent work like I want it to though, it prints one state 100 times and it isnt even when the state has changed.

any help will be greatly appriciated!

Take a look at the "state change" sketch from the examples menu in the IDE.

1 Like

Just a comment,
valveState isn’t being used in your code !

1 Like

This will be fooled by switch bounce:

Try this:

void loop() {
  valveState = digitalRead(valve);
  if ( valveState != savedState) {
    savedState = valveState;
    Serial.println(valveState);
  }
}

It is now!
:nerd_face:

In the OP, It's being printed - but nothing ever updates it!

What is connected to pin 4?
Which pin is the valve connected to?
What changes the state of the valve pin?

thank you i will

currently im just connecting pin 4 to ground.

another variant that needs just a single line of code for printing info

#define dbgc(myFixedText, variableName) \
  { \
    static long lastState; \
    if ( lastState != variableName ){ \
      Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }


int valve = 4;
int savedState;
int valveState;

void setup() {
  Serial.begin(115200);
  pinMode(valve, INPUT);
  savedState = digitalRead(valve);
}

void loop() {
  dbgc("my fixed text",digitalRead(valve) );
}

best regards Stefan

if you have connected a typical mechanical button then this knowledge applies

1 Like

So, a mechanical switch. Use INPUT_PULLUP on pinMode rather than just INPUT

Hello iviyan

Welcome to the worldbest Arduino forum ever.

Consider:

uint8_t valve = 4;
void setup()
{
  Serial.begin(115200);
  pinMode(valve, INPUT_PULLUP);  // connected to GND
}
void loop()
{
  // memory to save old state
  static uint8_t stateOld = HIGH;
  // read current state
  uint8_t stateNew = digitalRead(valve) ? LOW : HIGH;
  // detect state changes
  if (stateOld != stateNew)
  {
    // q&d debounce
    delay (20);
    // check current state changes
    if (stateNew != digitalRead(valve) ? LOW : HIGH)
    {
      stateOld = stateNew;
      Serial.print(F("valve ")), Serial.println(stateOld ? "becomes open" : "becomes closed");
    }
  }
}

Have a nice day and enjoy coding in C++.

You are seeing the switch bounce mechanically for about 2 ms.

What we do to fix it in software is wait until the pin reads the same for 2 ms or more (more especially for dirty switches) or just ignore the pin for a while and assume it is stable since it usually always will be if you wait long enough.

Making and improving your own debouncer is a bit of a rite. I check for stable state for ~3.5 ms before my button handler shows a stable state change.

You can get bounce-free sensing from light (often invisible near-IR) reflect or block or from magnetic sensor or magnetic switch, Hall types.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.