H35H0

      Don't give up on your dreams. Keep sleeping.

Arduino UNO. Simple Veksel
--------------------------

  void setup()
  {
    pinMode( 13, OUTPUT);
    pinMode( 3, INPUT_PULLUP);
  }

  void loop()
  {
    if ( !digitalRead( 3)) digitalWrite( 13, HIGH);
  }

Turning Lights off automatically
--------------------------------

Note: UnoArduSim doesn't compile C. 
      You have to change the construction near .."HIGH),"..

  const long lightOff = 5000;
  unsigned long lightOn;

  void setup()
  {
    pinMode( 13, OUTPUT);
    pinMode( 3, INPUT_PULLUP);
    lightOn = millis();
  }

  void loop()
  {
    if ( !digitalRead( 3))
      digitalWrite( 13, HIGH), lightOn = millis();
    if ((unsigned long)(millis() - lightOn) > lightOff)
      digitalWrite( 13, LOW);
  }

On-Off from the same button. Doesn't work well on real devices
--------------------------------------------------------------

Real button have many LOW to HIGH fronts while pressed once. This is called "bouncing". Hardware or software debouncer needed. ".., delay(100).." plays the role of poor man's debouncer here (to say honestly it is horribly bad solution)

  volatile byte state = LOW;
  volatile byte was3 = HIGH; 
  
  void setup()
  {
    pinMode( 13, OUTPUT);
    pinMode( 3, INPUT_PULLUP);
  }

  void loop()
  {
    byte is3 = digitalRead( 3);
    if ( was3 == HIGH && is3 == LOW)
      digitalWrite( 13, state = !state), delay( 100);
    was3 = is3;
  }
  
Arduino UNO. Buttons on 0, 2, 3. Interrupts
-------------------------------------------

There are other ways to play with 3 buttons and interrupts:

1. Use PCINT interrupts. They react slower, so less debouncing problems.

2. Button "0" -- INT0 (Pin2-GND), Button "1" -- INT1 (Pin3-GND),
   Button "Enter" (Pin2-GND + Pin3-GND, diodes to "AND" wires). 

NOTE: timer interrupts have lower priority than INT0 or INT1, so millis(), delay(), etc.. are frozen during ISR's (interrupt service routine). Also it's bad style to wait while inside ISR, delayMicroseconds is interrupt free, so can be used (bad habit, again).

3. Solution from Arduino Multifunctional Shield [8].
   
4. Using serial INT. Tested on UnoArduSim and real Uno R3 device.

  const int debounce = 50;
  volatile byte s0 = 0;
  volatile byte s2 = 0;
  volatile byte s3 = 0;
  volatile unsigned long m = 0;

  void serialEvent() {
    while (Serial.available()) Serial.read();
    s0 = !s0;
    digitalWrite( 11, s0);
  }

  void int0() {
    unsigned long vm =  millis();
    if ((unsigned long)(vm - m) > debounce) {
      s3 = !s3;
      digitalWrite( 12, s3);
    }
    m = vm;
  }

  void int1() {
    unsigned long vm =  millis();
    if ((unsigned long)(vm - m) > debounce) {
      s2 = !s2;
      digitalWrite( 13, s2);
    }
    m = vm;
  }

  void setup()
  {
    pinMode( 13, OUTPUT);
    pinMode( 12, OUTPUT);
    pinMode( 11, OUTPUT);
    pinMode( 3, INPUT_PULLUP);
    pinMode( 2, INPUT_PULLUP);
    pinMode( 0, INPUT_PULLUP);
    Serial.begin(9600); // intSerial
    attachInterrupt(0, int0, FALLING);
    attachInterrupt(1, int1, FALLING);
  }

  void loop()
  {
  }

------------------------------------------------------------------------

lastUP. +Button 4 as Reset
--------------------------

  const int debounce = 50;
  volatile unsigned long m = 0;

  void allDown() {
    for (int p=11; p<=13; p++) digitalWrite( p, LOW);
  }
  
  void lastUp( int apin) {
    allDown();
    digitalWrite( apin, HIGH);
  }
  
  void serialEvent() {
    while (Serial.available()) Serial.read();
    lastUp( 11);
  }
  
  void int0() {
    unsigned long vm =  millis();
    if ((unsigned long)(vm - m) > debounce) {
      lastUp( 12);
    }
    m = vm;
  }
  
  void int1() {
    unsigned long vm =  millis();
    if ((unsigned long)(vm - m) > debounce) {
      lastUp( 13);
    }
    m = vm;
  }
  
  void setup()
  {
    pinMode( 13, OUTPUT);
    pinMode( 12, OUTPUT);
    pinMode( 11, OUTPUT);
    pinMode( 4, INPUT_PULLUP);
    pinMode( 3, INPUT_PULLUP);
    pinMode( 2, INPUT_PULLUP);
    pinMode( 0, INPUT_PULLUP);
    Serial.begin(9600); // intSerial
    attachInterrupt(0, int0, FALLING);
    attachInterrupt(1, int1, FALLING);
  }
  
  void loop()
  {
    if( !digitalRead( 4)) allDown();
  }

Annex A. digitalPinToInterrupt
..............................

attachInterrupt

  https://www.arduino.cc/en/Reference/attachInterrupt
  
  Board | Digital Pin (Interrupt)
  ------+-----------------------------------
  Uno   | 2(0), 3(1)
  Micro | 3(0), 2(1), 0(2), 1(3), 7(4)

UNO:

  C:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard\
  pins_arduino.h

  #define digitalPinToInterrupt(p)  ((p) == 2 ? 0 : \
                                     ((p) == 3 ? 1 : \
                                      NOT_AN_INTERRUPT))
  
Micro, Leonardo:

  C:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\leonardo\
  pins_arduino.h

  #define digitalPinToInterrupt(p) ((p) == 0 ? 2 : \
                                    ((p) == 1 ? 3 : \ 
                                     ((p) == 2 ? 1 : \
                                      ((p) == 3 ? 0 : \
                                       ((p) == 7 ? 4 : \
                                        NOT_AN_INTERRUPT)))))
  
------------------------------------------------------------------------

Links
-----

1. Nick Gammon Arduino Uno interrupts post.

  http://gammon.com.au/interrupts
  
2. Debouncing a Button with Arduino. Limor Fried code.

  https://programmingelectronics.com
        /tutorial-19-debouncing-a-button-with-arduino-old-version/

3. Отличие INT и PCINT

  http://arduino.ru/forum/apparatnye-voprosy/otlichie-int-i-pcint
  
4. Arduino: How do you reset millis()? by James Lewis

  https://www.baldengineer.com/arduino-how-do-you-reset-millis.html
  
5. Simple Pin Change Interrupt on all pins (official)

  http://playground.arduino.cc/Main/PinChangeInterrupt
  
6. Pin-change interrupts on Arduino (the best article, i believe)

  http://www.geertlangereis.nl/Electronics
        /Pin_Change_Interrupts/PinChange_en.html
        
7. ATMega 328 PCINT Example. by Wollw. 
   (frankensteinXOXO commented on Mar 1, 2016: great)

  https://gist.github.com/Wollw/2598827
  
8. 原理图.pdf (Arduino Multifunctional Shield)

  http://www.baaqii.com/promanage/manual/A1010.zip