Menu
CoddyTech

Zliczanie naciśnięć za pomocą przerwań

Część sekcji Odmierzanie czasu bez delay() ścieżki Arduino w Coddy. Lekcja 15 z 18.

Jak widać było w sekcji Wejścia, przyciski odbijają: przez około milisekundę styki dotykają się, rozłączają i ponownie dotykają — zarówno podczas naciskania, jak i zwalniania. Przerwanie wykrywa każdy styk, więc procedura obsługi przerwania FALLING, która dodaje 1, nalicza jedno kliknięcie kilka razy.

Procedura obsługi przerwania nie może eliminować drgań styków za pomocą delay(): delay() potrzebuje własnego przerwania zegara, a przerwania są wstrzymywane podczas działania procedury obsługi przerwania. Zamiast tego użyj zegara. Zapamiętaj, kiedy nastąpiło ostatnie zliczone naciśnięcie, i ignoruj każde zbocze opadające, które pojawi się zbyt szybko po nim:

unsigned long lastPress = 0;

void onPress() {
  unsigned long now = millis();
  if (now - lastPress >= 200) {
    presses = presses + 1;
    lastPress = now;
  }
}

Odczyt millis() w procedurze obsługi przerwania jest w porządku: zwraca czas, w którym procedura obsługi przerwania się rozpoczęła. Wybierz okno dłuższe niż kliknięcie, tak aby odbicia podczas zwalniania mieściły się w nim, i krótsze niż przerwa między dwoma szybkimi kliknięciami. 200 ms sprawdza się u ludzi.

challenge icon

Wyzwanie

Średni

Ten licznik zlicza każde kliknięcie kilka razy. Zastosuj debouncing wewnątrz onPress():

  • dodaj zmienną unsigned long lastPress
  • zliczaj opadające zbocze tylko wtedy, gdy od lastPress minęło co najmniej 200 ms, a następnie zapisz czas w lastPress

Naciśnij Run, kliknij przycisk kilka razy i obserwuj licznik, a następnie naciśnij Check.

Spróbuj swoich sił

const int buttonPin = 2;

volatile int presses = 0;
int shown = 0;

void onPress() {
  // każde zbocze opadające na pinie jest zliczane, także drgania styków: wyeliminuj je tutaj
  presses = presses + 1;
}

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(buttonPin), onPress, FALLING);
}

void loop() {
  // wypisz licznik za każdym razem, gdy się zmieni
  if (presses != shown) {
    shown = presses;
    Serial.println(shown);
  }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Odmierzanie czasu bez delay()

Poćwicz samodzielnie: Edytor online Arduino