Антидребезг в прерываниях - программное решение

Тема в разделе "Arduino & Shields", создана пользователем SebLer, 24 сен 2014.

  1. SebLer

    SebLer Нуб

    Всем привет. Уже писал об этой проблеме на ютуб-канале амперки, в 10 уроке от Джереми о прерываниях. Вот, хотел ещё сюда скопипастить.
    Пока копипастил, решил, всё-таки, задачу, но не совсем уверен в правильности решения, поэтому отписываюсь здесь, чтобы узнать мнение опытных ардуинщиков.
    Суть в том, чтобы крутиться в цикле while(), пока не пройдут 5мс используя метод millis(). В итоге проходит не более 7мс (по крайней мере у меня).

    Код (Text):

    int switchPin = 8;
    int ledPin = 11;

    int switchState = LOW;
    int ledState = LOW;
    int currentState = LOW;

    void setup() {
      Serial.begin(9600);
      pinMode(ledPin, OUTPUT);
    }

    void loop() {
      currentState = digitalRead(switchPin);
      long previousMillis = millis();

      if(switchState != currentState) {
          while(millis() - previousMillis <= 5) ;
              currentState = digitalRead(switchPin);
              long currentMillis = millis();
              Serial.print("Previous ");
              Serial.print(previousMillis);
              Serial.print(" Current ");
              Serial.print(currentMillis);
              Serial.print(" Interval ");
              Serial.println(currentMillis - previousMillis);
      }//end if

      if(currentState == HIGH && switchState == LOW)
          ledState = !ledState;
          digitalWrite(ledPin, ledState);
        switchState = currentState;

    }
     
  2. acos

    acos Официальный гик Администратор

    А где прерывания?:)
    По сути - нормальное решение для проверки кнопки. Если ваша задача стояла в том, чтобы обойтись без delay() то всё ок. Обращаю внимание, что Serial.print() в arduino выполняется не асинхронно, и сам вносит иногда существенную задержку. Сравните такой код с вашим)
    Код (C):
    while(millis() - previousMillis <= 5) ;
              currentState = digitalRead(switchPin);
              long currentMillis = millis();
              Serial.print("Previous ");
              Serial.print(previousMillis);
              Serial.print(" Current ");
              Serial.print(currentMillis);
              Serial.print(" Interval ");
              currentMillis = millis();
              Serial.println(currentMillis - previousMillis);
      }
     
  3. SebLer

    SebLer Нуб

    Прерываний нет пока) Хотел сначала потестить, потом перейти ко второй части урока. Но что-то мне подсказывает, что работать всё равно не будет потому, что сообщения в сериал два раза проскакивают.
    P.S. на счёт задержки от сериала - это я ещё при первом тестировании заметил.