Buttons & Switches

First off thanks in advance for advice! I'm attempting to get buttons and switches to work together. The project is a forging hammer. The components consist of a foot pedal momentary switch, a momentary button that is activated by momentum (this button is pressed when the hammer hits the part, but it stays connected until the hammer changes directions) a relay that controls the solenoids to the air ram. We want to activate and hold the foot pedal switch, the hammer extends (turn on relay) mates with part (activates switch on the hammer) turns off relay (retracts hammer). This is where things get complicated, we want the program to run once while the foot pedal is activated, and not run again until the foot pedal is released and pressed again. Depending on the material being forged, the foot pedal will be reactivated while the switch on the hammer is still activated.

we want the program to run once while the foot pedal is activated, and not run again until the foot pedal is released and pressed again.

In the IDE examples (File, Examples, Digital) there is an example called State Change Detection that shows how to do as stated in the quote. You can execute code only when the switch changes state from HIGH to LOW or from LOW to HIGH.

To use that edge detection wound the foot pedal need to be pressed twice? I was tinkering with edge detection last night and wasn't getting the results I was looking for. It could be my lack of programming knowledge is to the reasoning behind the need to double press the foot pedal.

State change detection should do what you describes in the quote. Post your code, maybe we can make it work.

Can you provide a schematic showing how the switch is wired?

Edge detection is part of debounce code.

Since switches bounce, Your code needs to check the switch repeatedly over something such as 10 milliseconds, and only when it has been closed every time it is checked over that period, it is flagged as being closed.

The piece of code which does this checking (I do not have my code repository with me at present) is designed to return a TRUE value only when the switch is determined to now be closed when it previously was not; so it only does so once; as long as the switch remains closed, the code which is executed every pass through the main loop() does not return TRUE until the switch has been found to be consistently open over a similar 10 ms period and then is closed again.

I will post the code in a few hours ...

OK, here is full code for button/ switch de-bouncing and independent LED flashing.

It uses the button to reliably toggle one LED on and off, while the other two LEDs independently flash at different rates.

Note that this code is modular - by duplicating the timer count variables and the calls to "butndown" and "timeout", you can monitor as many buttons or switches and generate as many flash sequences as you require. (The flash sequences do not have to have equal on and off times, either.)

// Blink without "delay()" - multi!  With button de-bounce.

const int led1Pin =  13;    // LED pin number
const int led2Pin =  10;
const int led3Pin =  11;
const int button1 =  4;
int led1State = LOW;        // initialise the LED
int led2State = LOW;
int led3State = LOW;
char bstate1 = 0;
unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check 
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);      
  pinMode(led2Pin, OUTPUT);      
  pinMode(led3Pin, OUTPUT);      
  pinMode(button1, INPUT);      
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (led1State == LOW) {
      led1State = HIGH;
    }
    else {
      led1State = LOW; 
    } 
    digitalWrite(led1Pin, led1State);
  } 

  // Act if the latter time (ms) has now passed on this particular counter,
  if (timeout(&count2, 300UL )) {
    if (led2State == LOW) {
      led2State = HIGH;
    }
    else {
      led2State = LOW; 
    } 
    digitalWrite(led2Pin, led2State);
  } 

  if (timeout(&count3, 77UL )) {
    if (led3State == LOW) {
      led3State = HIGH;
    }
    else {
      led3State = LOW; 
    } 
    digitalWrite(led3Pin, led3State);
  } 
}