title: How to determine button press duration with wiringpi in C
body: <p>For a aspberry pi project I have buttons connected to GPIO and I want to take different actions depending on how long a button has been pressed. The following python code (extract) is working as expected:</p>
  
  <pre class="lang-python prettyprint-override"><code>on_button2(channel):
      t1 = time.time()
      # Wait for button release
      while GPIO.input(channel) == 0:
          pass
      duration = time.time() - t1
      print "duration: %f" % (duration)
      if duration &gt; 0.75:
          mpd_client.previous()
      else:
          mpd_client.next()
  
  GPIO.add_event_detect(BUTTON2_PIN, GPIO.FALLING, callback=on_button2, bouncetime=700);
  </code></pre>
  
  <p>I would like to convert this into a C program (don't ask why, I really don't like python and I'm much more familiar with C, so I'd like to do it in C)</p>
  
  <p>Trying to convert this to C with wiringPi, I came up with this, but it is not working as expected:</p>
  
  <pre class="lang-c prettyprint-override"><code>unsigned long btn2_t0;
  
  static void on_button_2_pressed() {
      unsigned long duration, t1;
      int level;
  
      level = digitalRead(BUTTON_2_PIN);
  
      // Debounce button
      t1 = millis();
      if (t1 - btn2_t0 &lt; 700) {
          return;
      }
      btn2_t0 = t1;
  
      // Wait for button being released
      while (digitalRead(BUTTON_2_PIN) == LOW) {
          delay(100);
      }
  
      duration = millis() - t1;
  
      if (duration &gt; 5000) {
          printf("Self destruction sequence initiated!\n");
      }
      else if (duration &gt; 700) {
          player_previous();
      }
      else {
          player_next();
      }
  }
  
  int main() {
      // Setup WiringPi Lib
      wiringPiSetupGpio();
      pinMode(BUTTON_2_PIN, INPUT);
  
      // Register callbacks on button press
      wiringPiISR(BUTTON_2_PIN, INT_EDGE_FALLING, on_button_2_pressed);
  
      for (;;) {
          delay(500);
      }
      return 0;
  }
  </code></pre>
  
  <p>It seems that the loop that should wait for button release is not being executed or that the while-condition is always true, and thus, duration always is zero.</p>
  
  <p>Is the <code>digitalRead(BUTTON_2_PIN)</code> function equivalent to the <code>GPIO.input(channel)</code> in the python code at all?</p>
  
  <p>If somebody could point me in the right direction on how to detect button press (software-debounced) and measure the duration of the button press in C.</p>
  
  <p>Thanks a lot.</p>
  
  <p>EDIT: <strong>Working solution</strong></p>
  
  <p>After playing around a lot and with the help of Francesco Boi I came around with a working solution, although I do not really understand why the compare logic with HIGH / LOW is swapped compared to the python code (I thought that the button press will cause the pin to FALL to LOW and releasing it would RAISE it to HIGH ...)</p>
  
  <pre class="lang-c prettyprint-override"><code>static void on_button_2_pressed() {
  
      unsigned long duration;
      static unsigned long button_pressed_timestamp;
      int level = digitalRead(BUTTON_2_PIN);
  
      if (level == HIGH) { // Why HIGH ?!?
          button_pressed_timestamp = millis();
      }
      else {
          duration = millis() - button_pressed_timestamp;
          button_pressed_timestamp = millis();
  
          if (duration &lt; 100) {
              // debounce...
              return;
          }
          else if (duration &lt; 700) {
              syslog(LOG_NOTICE, "&gt;&gt; NEXT\n");
          }
          else if (duration &lt; 3000) {
              syslog(LOG_NOTICE, "&lt;&lt; PREV\n");
          }
          else {
              syslog(LOG_NOTICE, "!! REBOOT\n");
          }
      }
  }
  
  int main() {
      ...
      wiringPiISR(BUTTON_2_PIN, INT_EDGE_BOTH, on_button_2_pressed);
      ...
  }
  
  </code></pre>