почему мой дебаунсер не работает?

#c #debouncing

#c #дебаунсинг

Вопрос:

Я пытаюсь написать дебаунсер, который будет возвращать только допустимый аргумент (> 0), если он был дебатирован (-1 четыре прыжка). Я уже придумал это, но он всегда возвращает -1, почему мне интересно:

 #include <stdio.h>
#include <time.h>
#include <unistd.h>

#define BOUNCETIME  500000000 //(500ms)

#define SetTime(x)     clock_gettime(CLOCK_REALTIME, (x));  // set time

static struct timespec tset;
struct timespec tnow;

int DeBounce(unsigned int arg)
{  
  static int val = -1;
  long long nsec = 0;
  if (val < 0) {
    val = arg;
    SetTime(amp;tset);  
    return arg;    
  } else {
    SetTime(amp;tnow);
    if (tnow.tv_nsec < tset.tv_nsec)
      nsec = tnow.tv_nsec   1000000000;
    else
      nsec = tnow.tv_nsec;
    if (tnow.tv_nsec - tset.tv_nsec > BOUNCETIME) {
      printf("arg okayn"); 
      val = -1;
      return arg;
    }
    else 
      printf("bounce, ignore!n");
      return -1;
  }

}

int main (void) 
{
  printf("#1 %dn",DeBounce(0));
  usleep(1);
  printf("#2 %dn",DeBounce(1));
  usleep(200);
  printf("#3 %dn",DeBounce(1));
  sleep(1);
  printf("#4 %dn",DeBounce(1));
}
  

вывод, который я получаю, это:

 $ ./debounce 
#1 0
bounce, ignore!
#2 -1
bounce, ignore!
#3 -1
bounce, ignore!
#4 -1
$
  

Ответ №1:

usleep(600); составляет 600 микросекунд. Но ваш период дебаунса составляет 500 миллисекунд.

Кроме tnow.tv_nsec - tset.tv_nsec того, неверно, поскольку tv_nsec это не полное значение времени, а только количество наносекунд, прошедших со второй. Правильный способ вычисления прошедшего времени в наносекундах выглядит примерно так:

 (tnow.tv_sec * 1.0e-9   tnow.tv_nsec) - (tset.tv_sec * 1.0e-9   tset.tv_nsec)
  

Комментарии:

1. Есть и другая проблема, простое вычитание tnow.tv_nsec — tset.tv_nsec не будет работать должным образом, поскольку tv_nsec — это просто количество наносекунд, прошедших за секунду.

2. @nos Да, сейчас обновляю ответ (просто отвлекся на несколько минут).

3. @kaylum да, следовательно, последний аргумент должен быть принят, а не отменен, но он тоже отменяется…

4. @cerr Почему должно приниматься последнее значение? usleep Недостаточно долго, чтобы период дебаунса не истек.

5. @cerr Вы не учитываете компонент seconds, tv_sec . Вы предполагаете, что дело tnow.tv_nsec < tset.tv_nsec приравнивается к секундам, которые перевернулись. Но это неверно, поскольку секунды могут перевернуться даже в другом случае. Вы должны tv_sec каким-то образом посмотреть.