Change State Detection help

I am brand new to Arduino and trying to fumble my way through a last minute Halloween automation. What I am trying to do is have a pressure pad that I made fire a solenoid to blast air. I have tried several different examples and the best I can find to use is the Change State Detection. I changed the program a little so after the pressure pad is stepped on, pin 8 will turn on a relay for 200ms then turn off.

My only issue with the program is that it fires the relay any time a change in state is detected. How would I change the program to only activate the relayPin when the buttonPin goes high rather than any state change?

As a side note, I have checked out Blink Without Delay and I'm just not sure what I would need to change there to make it wait for the input before setting the output.

I also googled but couldn't seem to find what I am looking for, unless I am searching for the wrong thing.

Here is what I currently have.

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int relayPin = 8;       // the pin that the Relay is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(relayPin, OUTPUT);
  // set relay off
  digitalWrite(relayPin, HIGH);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == LOW) 
    {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(200);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;


  // turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  if (buttonPushCounter % 1 == 0) {
    digitalWrite(relayPin, HIGH);
    delay(200);
    digitalWrite(relayPin, LOW);
  } else {
    digitalWrite(relayPin, LOW);
  }

}

Good job using code tags on your first post.

 pinMode(buttonPin, INPUT);

How is the buttonPin (pressure pad) wired? Are you using an external pulldown or pullup resisitor to keep the pin from floating? More typical is to use pinMode INPUT_PULLUP and wire the switch between the Arduino input and GND. The pin will go LOW when the button is pressed.

How would I change the program to only activate the relayPin when the buttonPin goes high rather than any state change?

Your present code is written to activate the relayPin when the switch goes LOW.

if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == LOW)

First thing is to document the wiring of the pressure pad, (decide if you want to change the pinMode to INPUT_PULLUP instead of using external resistors), and understand whether the pressed state is HIGH or LOW. The code to respond to the desired state change is simple, and the delayed start to the solenoid is a simple refinement.

cattledog:

 pinMode(buttonPin, INPUT);

How is the buttonPin (pressure pad) wired? Are you using an external pulldown or pullup resisitor to keep the pin from floating? More typical is to use pinMode INPUT_PULLUP and wire the switch between the Arduino input and GND. The pin will go LOW when the button is pressed.

I have one side of the pressure pad connected to GND and the other side connected to Pin 2 and 5V through a 1k resistor.

cattledog:
Good job using code tags on your first post.

Thanks. I made sure to read the how to use this forum and I am familiar with posting code on a forum for Home Assistant (a home automation OS)

I have one side of the pressure pad connected to GND and the other side connected to Pin 2 and 5V through a 1k resistor.

OK, so the pin should read LOW when the pressure pad is stepped on. Can you confirm this with a simple digitalRead() sketch which looks at pin 2?

Except for your comments (which I have revised) your code appears correct for your wiring. Are you seeing the counter increase when you step off the pad as well as on?

buttonState = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {//pin has changed state
    if (buttonState == LOW) //went from HIGH to LOW
    {
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else { //went from LOW to HIGH
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(200);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

Your relay code does not look correct. The remainder for all counts will be 0 with %1, so the else makes no sense.

if (buttonPushCounter % 1 == 0) {
    digitalWrite(relayPin, HIGH);
    delay(200);
    digitalWrite(relayPin, LOW);
  } else {
    digitalWrite(relayPin, LOW);
  }

In fact, using the push button counter as the trigger does not really make sense, and the code is better changed to use a boolean control variable instead of a counter.

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int relayPin = 8;       // the pin that the Relay is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
boolean runRelay = false;  // add control variable for relay

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);//may want to change to INPUT_PULLUP
  // initialize the LED as an output:
  pinMode(relayPin, OUTPUT);
  // set relay off
  digitalWrite(relayPin, HIGH);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    if (buttonState == LOW)//went from HIGH to LOW
    {
     // buttonPushCounter++;
      Serial.println("on");
      runRelay = true;
      //Serial.print("number of button pushes: ");
      //Serial.println(buttonPushCounter);
    } else { //went from LOW to HIGH
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(200);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;


  // turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  //if (buttonPushCounter % 1 == 0) {
  if (runRelay == true) {
    runRelay =false;
    digitalWrite(relayPin, LOW); //written for active low
    delay(200);
    digitalWrite(relayPin, HIGH);
  } //else {
   // digitalWrite(relayPin, LOW);
  //}
}

If you are seeing the correct state changes and relay actions, we can work on the delayed relay actions.

The way I have it set up now, I am seeing the correct behavior of the relay. The only thing wrong is that any change of state (when the pad is stepped on and when pressure comes off the pad, the relay fires. I will try your last example here shortly when I finish carving pumpkins with the kiddos.

cattledog:

// this constant won't change:

const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int relayPin = 8;      // the pin that the Relay is attached to

// Variables will change:
int buttonPushCounter = 0;  // counter for the number of button presses
int buttonState = 0;        // current state of the button
int lastButtonState = 0;    // previous state of the button
boolean runRelay = false;  // add control variable for relay

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);//may want to change to INPUT_PULLUP
  // initialize the LED as an output:
  pinMode(relayPin, OUTPUT);
  // set relay off
  digitalWrite(relayPin, HIGH);
  // initialize serial communication:
  Serial.begin(9600);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    if (buttonState == LOW)//went from HIGH to LOW
    {
    // buttonPushCounter++;
      Serial.println("on");
      runRelay = true;
      //Serial.print("number of button pushes: ");
      //Serial.println(buttonPushCounter);
    } else { //went from LOW to HIGH
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(200);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

// turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  //if (buttonPushCounter % 1 == 0) {
  if (runRelay == true) {
    runRelay =false;
    digitalWrite(relayPin, LOW); //written for active low
    delay(200);
    digitalWrite(relayPin, HIGH);
  } //else {
  // digitalWrite(relayPin, LOW);
  //}
}

That worked perfectly. Thank you so much. I still have a lot to learn with all this but I definitely needed help here since it was pretty last minute.

That worked perfectly. Thank you so much.

You're welcome.

You still have a few days to go before any ghosts and goblins arrive. Are there any refinements you want?

Do you want to delay the relay/air pulse so it goes off sometime after the pad is stepped on?

cattledog:
Do you want to delay the relay/air pulse so it goes off sometime after the pad is stepped on?

No, I'm going to have the air line on the ceiling directly over the pad.