top of page
Writer's pictureDaniel Van Nattan

State change detection for active LOW inputs

I often point new users to the State Change Detection example. That example is great for teaching about edge detection, but it uses a momentary switch with an external pull-down resistor. Using the same switch, but with the internal pullup enabled and wired to ground is better practice in most cases. You can enable the internal pullup resistor with this line of code:


pinMode(pin, INPUT_PULLUP);

The switch is wired as shown. The resistor is not required if the internal pullup is used, but it may be necessary if the switch is at the end of long wires because a stronger pullup with lower resistor values (min. 1K) is necessary. The ceramic capacitor is optional, but will provide some hardware debounce. If the switch is at the end of long wires, it can also filter noise that can cause false indications. Also shown is the safe way to wire the ever popular 6mm tactile switches.


Here is the code from the example, modified to use the internal pullup and ground for an active LOW switch. Active LOW means that the switch is LOW when closed (pressed) and HIGH when open (released).

/*
The circuit:
   - pushbutton attached to pin 2 from ground
   - the internal pullup on pin 2 is enabled
   - LED attached from pin 13 to ground (or use the built-in LED on most
    Arduino boards)
*/
// this constant won't change:
const byte buttonPin = 2;     // the pin that the pushbutton is attached to
const byte ledPin = 13;       // the pin that the LED is attached to
// Variables will change:
int buttonPushCounter = 0;    // counter for the number of button presses
boolean buttonState = 0;      // current state of the button
boolean lastButtonState = 0;  // previous state of the button
void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT_PULLUP);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {

  static unsigned long timer = 0;
  unsigned long interval = 20;
  if (millis() - timer >= interval) {
    timer = millis();

    // read the pushbutton input pin:
    buttonState = digitalRead(buttonPin);

    // compare the buttonState to its previous stateif (buttonState != lastButtonState)
    {
      // if the state has changed, increment the counter
      if (buttonState == LOW) {
        // if the current state is LOW then the button went from off to on:
        buttonPushCounter++;
        Serial.println("on");
        Serial.print("number of button pushes: ");
        Serial.println(buttonPushCounter);
      } else {
        // if the current state is HIGH then the button went from on to off:
        Serial.println("off");
      }
      // save the current state as the last state, for next time through the loop
      lastButtonState = buttonState;
    }
  }

  // turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  if (buttonPushCounter % 4 == 0) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}

Contributed by groundFungus.



1 view0 comments

Recent Posts

See All

Programming: Controlling a LED with PWM

Pulse Width Modulation (PWM) is a technique used in electronics and microcontroller programming to control the intensity or brightness of...

Programming: Implementing millis()

If you read the previous lesson, we covered the fundamentals of the millis function in general. Let's make our first millis event! Let's...

Programming: Advancing to millis()

When we wrote the blink sketch, we created something called blocking code. In effect, this means that the Arduino will perform a delay,...

コメント


bottom of page