Go Down

Topic: Use button state change to bypass "tricky" boolean logic? (Read 2530 times) previous topic - next topic

themaddhatter

New guy to the 'duinos, and pretty rusty on my traditional electronics & programing *FORTRAN77 BABY!*  :smiley-roll-blue:

I am working on a program idea & am getting a little flustered with the logic side of what I want it to do.  I went searching for an alternative thought process.

What I have are two inputs and an output which may or may not get monitored (based on the programming path taken).

Inputs are an SPST switch & a momentary pushbutton (both with 5V feeds sinking to arduino with pin configured digital), and the output is digital.

What I want the setup to do is this: whenever the state of the spst switch or pushbutton is pressed & released, I want the digital output to send a fixed duration pulse to an off-board machine.

Initially I approached this as a boolean logic argument, but the problems gets muddy in the application, because you need to not only account for the status of each of these inputs, but also the status of the off-board machine (and it's relation to the current button status).

Long story short, I realized it was going to get ugly, so I sought out an alternate solution & found this button state change tutorial http://arduino.cc/en/Tutorial/ButtonStateChange

I believe this type of command will work for me, but I am concerned I may get a "false state change".  For example, when you push down the pushbutton & release, I want the arduino to register this as one event (button cycled) versus two events (button press + button release).  Is there any coding "tricks" I need to put into play here to keep that from happening (essentially eliminating switch bounce)? 

The other problem I run into is that I have one input which is momentary & one which is not.  Does the same button change logic work for both the momentary button and the spst switch?

Any other ideas on how to simply code this would be appreciated.



PaulS

Quote
I believe this type of command will work for me, but I am concerned I may get a "false state change".  For example, when you push down the pushbutton & release, I want the arduino to register this as one event (button cycled) versus two events (button press + button release).

Why? It seems like only the release event is of interest.

Quote
The other problem I run into is that I have one input which is momentary & one which is not.  Does the same button change logic work for both the momentary button and the spst switch?

Yes, but the event of interest is not the same. In the momentary contact case, you could care about the pressed event or the released event. Typically, they are close together.

In the SPST case, there are state changes, but they are not close together. It is the current state, not the changes, that are of interest.
The art of getting good answers lies in asking good questions.

themaddhatter

Thanks PaulS,

Just wanted to make sure my thought process was solid.

Going to wire it up & write it tonight.

themaddhatter

Been playing around with this circuit on my Uno (after dealing with issues on a Nano), and have a bit of a pickle.

Here is the code I have been using (from the ButtonStateChange code on Arduino site)

Code: [Select]
// this constant won't change:
const int  buttonPin = 4;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED 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(ledPin, OUTPUT);
}

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
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
  }
  // save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState;
}


what I am trying to do with this bit of code is to make pin13 go HIGH for half a second every time the button is pressed.  However, what it is actually doing is making pin13 go HIGH for half a second when you press the button, THEN an additional half-second HIGH when released (which is EXACTLY the effect I predicted would happen, and came here originally to try and resolve).

so, how do I structure the code so that a complete momentary press/depress only triggers ONE pulse cycle (and remember that the time in which someone holds the button down can be variable).  If I change the code to

Code: [Select]
  if (buttonState == HIGH) {

Then pin13 will pulse, but will continue pulsing for as long as you hold down the momentary.

Thoughts?

Grumpy_Mike

Code: [Select]
  if (buttonState != lastButtonState  && buttonState == LOW) {

UKHeliBob

Code: [Select]
  if (buttonState != lastButtonState) {
This line triggers the output whenever there is a change be it from HIGH to LOW or vice versa.  Add a check so that the output is triggered when there has been a change of state AND that the current input state is HIGH or LOW, whichever you want.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

themaddhatter

Thanks folks.

Dropped in the and statement, uploaded, and now it will only trigger on the release of the pushbutton (rather than both events).

Appreciated.

tmh


Go Up