Skocz do zawartości

Problem z falstartem w grze


Wapniak

Pomocna odpowiedź

Witam serdecznie
To mój pierwszy temat, ponieważ dopiero uczę się, proszę o łagodne potraktowanie, a przede wszystkim o pomoc/podpowiedź.
Mianowicie chcę rozbudować nw program/grę na refleks pochodzącą z:

https://www.instructables.com/Arduino-Reflex-Tester/

o wykrywanie falstartu. Ponieważ obecnie trzymając button jeszcze przed zapaleniem zielonej diody, gdy zapali się zielona dioda to czas reakcji wynosi 0,01s. Podjąłem próbę i rozbudowałem o "if" sprawdzający czy przytrzymany jest przycisk:

if (digitalRead(btnPin) == HIGH){    
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("   False start!  ");
      lcd.setCursor(0,1);
      lcd.print(" !!!!!!!!");
      digitalWrite(ledPin, LOW);
      delay(2000);
    } 

Niestety rozwiązuje to problem tylko cząstkowo i tylko gdy w momencie zapalenia zielonej diody trzymany jest button to wyświetli "False start".
Jednak wcześniej w przedziale losowym czasu random(500, 5000) czekając na zapalenie zielonej diody - jeśli klikam button to nic się nie dzieje, nie wyświetla falstartu.
Domyślam się, że to dlatego, że wszystko wstrzymuje delay(number), a mój "if" działa dopiero po wykonaniu delay(number). Czytałem, że delay() najlepiej zastąpić millis(), ale za bardzo nie wiem jak w tym przypadku zastosować 😞 a w sieci gównie są przykłady na diodach, bez przerwania procedury w chwili użycia przycisku. Którego może ja nie potrafię przystosować do mojego problemu.

Czy podpowiecie nowicjuszowi czego i jak użyć?

Poniżej cały kod:

include <Wire.h>  
#include <LiquidCrystal_I2C.h>
 
#define ledPin 8 
#define btnPin 4
 
double number;
long sTime;
 
LiquidCrystal_I2C lcd(0x27,16,2);
 
void setup() {
  Serial.begin(9600);
  lcd.begin();  
  lcd.setCursor(0,0);
  pinMode(btnPin, INPUT);
  pinMode(ledPin, OUTPUT);
}
 
void loop() { 
    number = random(500, 5000);
    lcd.print("Wait for the LED"); 
    delay(number);

   if (digitalRead(btnPin) == HIGH){     //jesli trzymany button to falstart
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("   false start! ");
      lcd.setCursor(0,1);
      lcd.print(" !!!!!!!!");
      digitalWrite(ledPin, LOW);
      delay(2000);
    } 
    lcd.clear();
    lcd.print("     PRESS!");
    digitalWrite(ledPin, HIGH);
    sTime = millis();
 
    while (digitalRead(btnPin) == LOW);
 
    lcd.clear();
    lcd.print(" Reaction time: ");
    lcd.setCursor(0,1);
    lcd.print("      ");
    lcd.print((millis() - sTime) / 1000.0);
    lcd.print(" s");
    
    delay(2000);
 
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("  Another test");
    lcd.setCursor(0, 1);
    lcd.print("  in 5 seconds");
    delay(5000);
    lcd.clear();
    digitalWrite(8, LOW);
}

 

Link do komentarza
Share on other sites

No najlepiej millis() uzyc...pasuje tez jakos ten kod przerobic z uzyciem switch()-case naprzyklad...bo tak jak teraz to nie zadziala po prostych przerobkach (taka "wada" millis()), ale jak juz ogarniesz to strasznie sobie zycie ulatwisz😉 

A swoja droga to masz rezystor podciagajacy pin do masy? Bo jesli nie to predzej czy pozniej czekaja Cie problemy...

Link do komentarza
Share on other sites

4 minuty temu, farmaceuta napisał:

No najlepiej millis() uzyc...pasuje tez jakos ten kod przerobic z uzyciem switch()-case naprzyklad...bo tak jak teraz to nie zadziala po prostych przerobkach (taka "wada" millis()), ale jak juz ogarniesz to strasznie sobie zycie ulatwisz😉 

A swoja droga to masz rezystor podciagajacy pin do masy? Bo jesli nie to predzej czy pozniej czekaja Cie problemy...

heh tylko ja właśnie nie za bardzo wiem jak w moim przypadku użyć millis() 😞 ale poszperam przykłady z switch()-case i może mnie oświeci

tak, rezystor 10k od tact-switcha podłaczony do GND 🙂

Link do komentarza
Share on other sites

Chodzi o coś w stylu:

    lcd.print("Wait for the LED"); 
    
    unsinged long waitUntil = millis() + random(500, 5000); //czas końcowy = teraz + losowa liczba milisekund
    while (millis() < waitUntil) {
        if (digitalRead(btnPin) == HIGH){     //jesli trzymany button to falstart
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("   false start! ");
            lcd.setCursor(0,1);
            lcd.print(" !!!!!!!!");
            digitalWrite(ledPin, LOW);
            delay(2000);
            
            return;
        } 
    }

 

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

  

include <Wire.h>  
#include <LiquidCrystal_I2C.h>
 
#define ledPin 8 
#define btnPin 4
 
int number;
long sTime;
 
LiquidCrystal_I2C lcd(0x27,16,2);
 
void setup() {
  Serial.begin(9600);
  lcd.begin();  
  lcd.setCursor(0,0);
  pinMode(btnPin, INPUT);
  pinMode(ledPin, OUTPUT);
}
 
void loop() { 
  delay(2000);
    number = random(500, 5000);
    lcd.clear();
    lcd.print("Wait for the LED"); 
    
 while(number) {
   if (digitalRead(btnPin) == HIGH){     //jesli trzymany button to falstart
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("   false start! ");
      lcd.setCursor(0,1);
      lcd.print(" !!!!!!!!");
      digitalWrite(ledPin, LOW);
      return;
    } 
   number--;
   delay(1);
   }
    lcd.clear();
    lcd.print("     PRESS!");
    digitalWrite(ledPin, HIGH);
    sTime = millis();
 
    while (digitalRead(btnPin) == LOW);
 
    lcd.clear();
    lcd.print(" Reaction time: ");
    lcd.setCursor(0,1);
    lcd.print("      ");
    lcd.print((millis() - sTime) / 1000.0);
    lcd.print(" s");
    
    delay(2000);
 
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("  Another test");
    lcd.setCursor(0, 1);
    lcd.print("  in 5 seconds");
    delay(5000);
    lcd.clear();
    digitalWrite(8, LOW);
}
 

 Dostane pewnie opierdziel za takie wynalazki skoro byla mowa o millis() i o tym jakim zlem jest delay()...ale co tam😜

Link do komentarza
Share on other sites

E tam - delay jest po to żeby z niego korzystać tam gdzie trzeba. A opierdziel to sam sobie dasz jak przeanalizujesz co się stanie, jeśli uruchomisz to na ESP32 i przytrzymasz klawisz na jakieś dwie sekundy 😉

Link do komentarza
Share on other sites

blokujesz program na czas kiedy przycisk jest wciśnięty, można to zrobić lepiej dzięki funkcji millis(); i maszynie stanów, choć pewnie arduino ma już jakąś funkcję debounce

Edytowano przez _LM_
Link do komentarza
Share on other sites

15 minut temu, etet100 napisał:

Na pewnym etapie wiedzy jest to jak jak najbardziej tak.

Nigdzie nie pisałem że konstrukcja jest "nie tak" - jedynie że należy jej unikać (niezależnie od etapu wiedzy). Podobnie zresztą jak delay - do czegoś służy, tylko trzeba stosować umiejętnie. O goto już przez grzeczność nie wspomnę...

Link do komentarza
Share on other sites

Każdy początkujący w końcu dojdzie do tego momentu, kiedy będzie chciał robić kilka rzeczy jednoczesnie i wtedy zdaje sobie sprawę, że na funkcji delay tego nie zrobi. To jest dla niektórych dość trudny moment, jak nie programować liniowo. 

Link do komentarza
Share on other sites

Moim zdaniem niema na co czekać tylko od razu stosować takie rozwiązania. Niewiele jest kursów internetowych które od razu pokazują jak nie blokować programu wszechobecnymi delayami, a tłumaczą czym jest i do czego służy timer programowy i maszyna stanów. Tak samo z bibliotekami np: od adafruit - czujnik który mógłby zrobić pomiar i konwersję w kilkanaście ms, robi to znacznie dłużej bo program wiecznie na coś czeka. 

  • Lubię! 1
Link do komentarza
Share on other sites

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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.