Skocz do zawartości

Komunikacja przez UART - dwukrotne wysyłanie ciągu znaków


Pomocna odpowiedź

Napisano

Witam,

Jestem na początku. Proszę o pomoc w zrozumieniu komunikacji z komputerem. Kod banalny, diody migają dopóki nie wciśnięty zostanie przycisk S0, wtedy ma się wyświetlić komunikat. Sekwencja "migania zostaje" wznowiona poprzez wciśnięcie S1.

Program działa, tak, że komunikat wyświetla się, po naciśnięciu S0 i ponownie po naciśnięciu S1.

#define S0 2
#define S1 3
#define L0 8
#define L1 9
bool p_akt;

void setup() {
 p_akt = false;
 pinMode(S0, INPUT_PULLUP);
 pinMode(S1, INPUT_PULLUP);
 pinMode(L0, OUTPUT);
 pinMode(L1, OUTPUT);
 digitalWrite(L0, LOW);
 digitalWrite(L1, LOW);
 attachInterrupt(digitalPinToInterrupt(S0), f_przerw, CHANGE);
 Serial.begin(9600);
 Serial.println("Program is running..");
}

void loop() {

 if (p_akt == false) {
   digitalWrite(L0, HIGH);
   digitalWrite(L1, LOW);
   delay (100);
   digitalWrite(L0, LOW);
   digitalWrite(L1, HIGH);
   delay (100);
 } else {
   Serial.println("S0 is pressed");
   delay(10);
   p_akt = false;
   while (digitalRead(S1) == HIGH) {
   }
 }
}

void f_przerw() {
 p_akt = true;
}

Przerwanie zapinasz na event CHANGE co oznacza że funkcja f_przerw wywoła Ci się dwa razy, w momencie wciśnięcia przycisku i w momencie puszczenia przycisku.

Spróbuj zmienić typ eventu na FALLING.

Przerwanie zapinasz na event CHANGE co oznacza że funkcja f_przerw wywoła Ci się dwa razy, w momencie wciśnięcia przycisku i w momencie puszczenia przycisku.

Spróbuj zmienić typ eventu na FALLING.

Próbowałem z każdym innym eventem i bez zmian. Wyświetlają się dwa komunikaty.

Zawsze dokładnie dwa? Bo zmiana typu wykrywanego zbocza nie pomoże na drgania styków. Musiałbyś dodać ich sprzętowe usuwanie lub dodać jakiś mechanizm w oprogramowaniu (np. wyłączanie przerwania na 50ms po wykryciu pierwszego zbocza).

Lukaszm ma rację, to jest drganie styków, a dziwne zachowanie, że zawsze dwa razy wysyła komunikat wynika stąd, że choć można wyzwolić przerwanie 1-100 razy jednym naciśnięciem przycisku to przerwanie jedynie zmienia flagę i nic więcej nie robi. Wykonanie else trwa tu akurat tyle, że zareaguje tylko jeden dodatkowy raz na te kilkadziesiąt wywołań (wyniki XX przerwań czekają aż skończy się delay 10 i przy następnej okazji else wykonuje się jeszcze raz), a w sumie dwa razy.

Wróciłem, żeby dodać, że rozwiązaniem jest przesunięcie zmiany flagi za delay(10), ale już tak jest więc chodzi o coś innego. Zrobiłem sobie to u siebie, drugi raz drukuje tylko wtedy gdy aktywuje przerwanie, wejdzie w pętlę oczekującą na przycisk S1 i wtedy wcisnę S0 + S1 w tej kolejności. Ale potem nie wchodzi w oczekiwanie na S1 bo zapewne S1 też wielokrotnie drga.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...