/* * Task5 * * Demonstrate using an interrupt routine to detect a button press. * This code does debounce the button. * */ // Pin to read for button value #define BUTTON_IN 3 // Boolean to show if pin value has changed // Because this value is changed in the interrupt, must declare as volatile, // which tells the compiler to always read this from memory, not a register volatile bool pinChange; // Communicates from interrupt routine // the setup function runs once when you press reset or power the board void setup() { // Pin to read button state, use internal pull-up to avoid external resistor // This also emulates TTL inputs that float HI. // Use INPUT for normal digital input (emulates CMOS input) pinMode(BUTTON_IN, INPUT_PULLUP); // initialize serial communication at 9600 bits per second: Serial.begin(9600); // Write something out to show we are alive Serial.println(F("Starting...")); // Setup the interrupt handler on pin change // Must be attached to pin 2 or 3 on Nano attachInterrupt(digitalPinToInterrupt(BUTTON_IN), pinChangeRoutine, CHANGE); } // the loop function runs over and over again forever void loop() { // Count how many times the button has been pressed // static means this is not reinitialized every loop static unsigned int nButton=0; // Previous button state (to find changes) static bool lastState; // Get the logical button value (pressed = true) from debounce routine bool buttonValue = buttonState(); // Has this changed? if (lastState != buttonValue) { lastState = buttonValue; // Update last state // If it is now pressed, increment counter and print result if (buttonValue) { ++nButton; Serial.print(F(" The button has been pressed ")); Serial.print(String(nButton)); if (nButton==1) { Serial.println(F(" time")); } else { Serial.println(F(" times")); } } } } // Interrupt handler, this is called via the interrupt handler every // time a change is detected on the button pin. Best to do very little here. void pinChangeRoutine() { pinChange = true; } // Debounce routine, returns best guess of button state bool buttonState() { // 8-bit storage used as shift register of past pin values static byte pinHistory = 0; // Best guess of debounced button value static bool buttonValue = false; // Time (in ms) since Arduino rebooted static unsigned long lastTime = 0; // If no change, just return last value if (!pinChange) return buttonValue; // Check how long since we last read the pin unsigned long currentTime = millis(); if ((currentTime - lastTime) < 4) return buttonValue; lastTime = currentTime; // Read the pin and push value onto buttonHistory pinHistory = (pinHistory<<1); if (digitalRead(BUTTON_IN)) bitSet(pinHistory, 0); // If the value has been stable for the last 8 x 4ms = 32ms, consider it stable // buttonValue reflects whether the button is pressed (true) or not (false) if (pinHistory == 0xFF) { buttonValue = false; pinChange = false; // Reset this to indicate we are in a stable state } if (pinHistory == 0x00) { buttonValue = true; pinChange = false; } return buttonValue; }