1

I am wandering how I would make it so the arduino uno will start a timer when button a is pressed and send "Start" or "Begin" or something like that to the console window. after the timer has started when button b is pressed it will mark the time from start of the timer and put it in the console window. After the timer has started when button c is pressed it will mark the time from start of the timer and put it in the console window. So on and so forth until button e, when button e is pressed i need the time to get logged in the console and they say "End" or "Stop" or something and then pause the sequence until I restart the board. This is for a school project and my only issue really is how to log the times On a timer loop persay.

  • What should happen if any of b-e are pressed while timer isn't running? – James Waldby - jwpat7 Mar 9 '16 at 3:21
  • +jwpat7 Preferably Nothing. If anything just say something in the console to dis regard it. – The Arduino Master Mar 9 '16 at 3:31
  • Also, My buttons (I dont know if there is another way) are connected all to 5V and the other end (Through the Switch) goes to say for example Digital Pin 9. And then the next to DP 10. So on. – The Arduino Master Mar 9 '16 at 3:34
1

Ordinarily, posters are expected to say what they've tried so far, and to show the code they've written. However, with a problem as difficult as this one, it seems reasonable to illustrate a complete program.

Note, this program assumes that one side of each button goes to Ground and the other side goes to a digital pin with its input pullup turned on. (If you connect one side to +5V instead of to ground, you will need additional circuitry to sense button presses.) The digital pins that are used are selected by changing the values swA, swB, and so forth, in the third line of the program.

//  jw - 8 Mar 2016 - Program for buttons demo
// Ref: http://arduino.stackexchange.com/questions/21590/arduino-timer-button
enum { swA=8, swB=9, swC=10, swD=11, swE=12}; // Switchbutton lines
enum { nSwitches=5 };
byte buttonPins[nSwitches]={swA, swB, swC, swD, swE};
byte buttonBusy[nSwitches]={  0,   0,   0,   0,   0};
unsigned long startTime;
//--------------------------------------------------------
void setup() {
  for (int i=0; i<nSwitches; ++i)
  // Note, this code assumes one side of button goes to Ground
  // and other side to a digital pin with its input pullup turned on
    pinMode(buttonPins[i], INPUT_PULLUP);
  Serial.begin(115200);
  Serial.println("Program begins");
}
//--------------------------------------------------------
void doButton(byte b) {
  char *blabels[] = {"A, Start", "B", "C", "D", "E, End"};
  if (digitalRead(buttonPins[b]) && !buttonBusy[b]) {
    // The b'th button has freshly turned on.
    unsigned long now = millis();
    if (b>0 && !buttonBusy[0]) // To ignore B-E if A isn't on
      return;
    buttonBusy[b] = 1;
    if (b==0) startTime = now;  // Button A resets timer
    Serial.print("Button ");
    Serial.print(blabels[b]);
    Serial.print(" at time ");
    Serial.println(now-startTime);
    if (b==nSwitches-1) {   // Last Button ends timing, restarts cycle
      for (byte k=0; k<nSwitches; ++k)
        buttonBusy[b] = 0;  // Clear all the busy-flags
    }
  }
}
//--------------------------------------------------------
void loop() {
  for (int b=0; b<nSwitches; ++b)
    doButton(b);
}

Edit: Note that triggering messages on button-release instead of button-press would be relatively easy if buttons didn't bounce.

Before explaining that, let's look at why the above code should work. Assume the cycle (buttons A and later E getting pressed, and possibly some of B, C, D too) lasts at least a couple of seconds. Assume we have ordinary button hardware, and that contacts can bounce for several milliseconds at each make or break. When you press a button the Arduino sees a lot of pin-turning-on events, eventually settling at pin-is-on. When you release a button the Arduino sees a lot of pin-turning-off events, eventually settling at pin-is-off. And finally, assume each button press is long enough that at least one digitalRead() happens while contacts are closed.

Under those assumptions, the very first time in each cycle that we see a given button closed, we know that button has just been pressed. Also, we can plausibly expect closure of button A to register before closures of other buttons, and can expect the closure of E to register after that of other buttons. So we can ignore bounce.

On the other hand, with on-release triggering we need to distinguish whether a pin-turning-off event is due to contact bounce of a button just pressed, or is actually part of a button-release bounce sequence.

Here's a method worth considering if you want to implement trigger-on-release:
• First, add a delay(1) call, in loop(). This will make the code timing less processor-dependent, so it can run on a 48- or 72-MHz system as well as on 16-MHz Unos.
• Each time you detect that button b is on, execute buttonBusy[b] = 40 to start (or restart) a 40-ms timeout. That is, while a button is held down, we keep setting its timeout to 40. (40 ms may be overly conservative. 20 ms should work ok with most switches, and 10 is ok with a lot of them.)
• When you detect that button b is off,
• if buttonBusy[b] is zero, do nothing.
• if buttonBusy[b] > 0, then decrement buttonBusy[b] and test if it now is equal to 1. When it's equal to 1, regard b as released, so do its action.

  • +jwpat7 This suits me perfect! Thanks! But one question. How would I make it so on button release it does this (all buttons are pressed and trigger when released. ) (For my personal Knowlage. ) THANKS!! – The Arduino Master Mar 9 '16 at 4:44
  • See edit re that – James Waldby - jwpat7 Mar 9 '16 at 5:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.