Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Arduino Leonardo przycisk bez delay

Piooner 27 Feb 2015 08:41 3681 30
IGE-XAO
  • #1
    Piooner
    Level 10  
    Witam mój problem polega na tym że
    po naciśnięciu przycisku wszystko działa tak jak chce ale gdy dodam krótki fragment kodu
    Code: cpp
    Log in, to see the code
    w celu opóźnienia silnika żeby zmienić np kierunek obrotu to już nie działa program wiem że przeszkadza mi delay. Ale cokolwiek nie robię (noInterrupts(); ,break czy timery nic nie działa) Podpowie mi ktoś czego użyć żeby to zadziałało?:)


    Code: cpp
    Log in, to see the code
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • IGE-XAO
  • #2
    EuroGenio
    Level 18  
    Co Ci konkretnie nie działa?
  • #3
    Piooner
    Level 10  
    Odpalę program działa ale przycisk trzeba dłużej przytrzymać zgaśnie wszystko i później koniec nie uruchomię przyciskiem chodź bym nie wiem jak długo go trzymał wydaję mi się że
    long debounceDelay = 50; i zwykły delay
    mieszają tu sprawę i nie wiem jak to obejść.
  • #5
    EuroGenio
    Level 18  
    Kolega szczywronek mnie uprzedził.
    Zarówno delay() jaki i millis() potrzebują przerwań do działania.
    Oczywiście możesz to obejść samemu programując timery.
    Ale wcześniej czy później i tak będzie potrzebował przerwań.
    Co chciałeś uzyskać wyłączając przerwania?
  • #6
    Piooner
    Level 10  
    Dalej nie rozumiem, najprostszy program do migania diody ma delay i nie ma nigdzie przerwań ?
    więc co muszę zrobić żeby mi to działało?
    noInterrupts
    i Interrupts muszą być w innym miejscu żeby przycisk wszystko włączał i wyłączał?
    bo teraz jest chyba tak że stosując 5 razy delay(1000) program czeka 5 sekund razem z long debounceDelay = 50; i wtedy szaleję wszystko ?
  • IGE-XAO
  • #7
    EuroGenio
    Level 18  
    W przykładzie Blink są używane przerwania właśnie na potrzeby procedury delay() do odmierzania czasu.
    Domyślnie w Arduino przerwania są włączone.
    Zostaw przerwania w spokoju (nie wyłączaj ich).
    Jak ma działać Twój program, co chcesz uzyskać?
  • #8
    Piooner
    Level 10  
    Mam taki program
    Code: cpp
    Log in, to see the code

    po wciśnięciu przycisku silnik przestaję się kręcić,wciskam kręci się działa.
    po dopisaniu kodu
    Code: cpp
    Log in, to see the code
    w celu zmniejszenia prędkości odpalam program przycisk raz tylko działa wyłącza wszystko i koniec.Nie umiem sobie z tym poradzić.
  • #9
    EuroGenio
    Level 18  
    W którym miejscu to wstawiłeś?
    Co to znaczy wszystko wyłącza?
    - silnik zatrzymuje się?
    - wiesza się uC?
    - nie działają przyciski?
    Opisz co się dzieje dokładniej, pokaż schemat połączeń.
  • #10
    Piooner
    Level 10  
    Code: cpp
    Log in, to see the code


    taki jest program,
    wcisnę raz przycisk silnik staję
    i koniec nie włączę go już ponownym wciśnięciem przycisku.
    podłączenie musi być dobre skoro usuwam z programu to
    Code: cpp
    Log in, to see the code
    i wszystko śmiga silnik się kręci przycisk staję przycisk kręci tak jak chce.
    Wiesza się uC o co chodzi?
  • #11
    EuroGenio
    Level 18  
    1. Czy masz zewnętrzny rezystor podciągający do GND lub Vcc pin 2?
    Jeśli nie, a sterujesz zwieraniem do masy to zastosuj pinMode( buttonPin, INPUT_PULLUP), u Ciebie jest pinMode( buttonPin, INPUT) i jeśli nie zrobiłeś zewnętrznego podciągania to pin sobie "fruwa w powietrzu" raz dając HIGH a raz LOW w dowolnym momencie kiedy nie jest zwartu do któregoś bieguna. Dlatego prosiłem o schemat...
    2. Zostaw włączone przerwania!!! Wykasuj / nie używaj poleceń: noInterrups() ani interrups();
    3. Zmniejsz te szalone wartości delay() na końcu do jakiś 200-300 ms

    Program ożyje...
  • #12
    Piooner
    Level 10  
    Po zastosowaniu 3 punktów program nadal nie działa tak jak powinien, a co do punktu 3 czemu szalone wartości? nie mogę sobie ustawić delay tak żeby silnik kręcił się 2 sekundy z jedną prędkością a 5 sekund z inną ?
  • #13
    EuroGenio
    Level 18  
    Twój program po wprowadzeniu wspomnianych zmian działa o tyle że reaguje na przycisk.
    Możesz sobie zmieniać dowolnie prędkość i czas jej trwania ale jeśli użyjesz do tego delay() to blokuje działanie całego programu.
    Tak się nie robi.
    Skoro nie potrafisz na razie użyć przerwań to użyj delay() o małej wartości ale w pętli, gdzie m.in. będziesz sprawdzał stan klawiszy i ew. robił inne rzeczy.
  • #14
    toomus
    Level 12  
    Funkcja delay() to czyste zło! Musisz to przerobić na non-blocking, tak jak masz to zrobione wcześniej w programie - loop() nie może się zatrzymywać.
  • #15
    Piooner
    Level 10  
    Ale jak to zrobić bez delay ? jak kod mogę zastosować?
  • #16
    toomus
    Level 12  
    Poniższe dwa programy robią to samo:

    Wersja z delay()
    Code: cpp
    Log in, to see the code


    Wersja non-blocking
    Code: cpp
    Log in, to see the code


    Chyba rozumiesz teraz dlaczego delay() to zło Jeśli nasłuchujesz czujników, albo masz w programie kod, który musi się wykonywać w innych odstępach czasu i w wielu innych przypadkach, z delay() jest to niewykonalne. Po prostu nie używać.
  • #17
    Piooner
    Level 10  
    Chyba już powoli zaczynam to rozumieć ale dalej nie wiem jak to wykorzystać na swoim przykładzie mam prosty program
    po wciśnięciu przycisku silnik kręci się wciskam nie kręci się
    ale gdy chce dodać komendę żeby po upływie 2 s jego prędkość się zwiększyła to nie działa to tak jak powinno
    Code: cpp
    Log in, to see the code

    gdzie tu błąd ?
  • #18
    EuroGenio
    Level 18  
    Kolega zapisał Ci symbolicznie wykonanie warunkowe procedury myFunction().
    Głównie chodzi o to że nie ująłeś w nawiasy całego bloku.
    Powinno być tak:
    Code: cpp
    Log in, to see the code
    Ponadto musisz zapamiętać wartość millis() wcześniej (np. w setup() ) aby porównywać;
    Code: cpp
    Log in, to see the code
    Inaczej oczekujesz, że jedno przewinięcie pętli da Ci te 2000 ms
  • #19
    Piooner
    Level 10  
    Program działa wielkie dzięki ale mam jeszcze jedno pytanie ;)
    po upływie tych 2000ms silnik kręci się już z szybszą prędkością nawet gdy wyłączam przyciskiem i włączam dalej kręci się z tą szybszą prędkością
    (rozumiem że to przez millis bo ona nalicza czas od początku włączenia arduino)
    dopiero reset pomaga.
  • #20
    EuroGenio
    Level 18  
    Nigdzie w programie nie zmieniasz prędkości silnika przyciskiem!
    Prędkość jest tylko zwiększana po upływie określonego czasu.
    Powinieneś użyć zmiennej zawierającej stan przycisku do zmiany prędkości.
  • #21
    Piooner
    Level 10  
    tak wiem nie oto mi chodziło chcę żeby było tak jak po wykorzystaniu delay
    czyli:
    Code: cpp
    Log in, to see the code

    silnik co 5 sekund zmienia swoją prędkość

    bo gdy jest tak:
    Code: cpp
    Log in, to see the code

    to silnik kręci się (100) tylko przez pierwsze 2 sekundy a później chodzi na 230 do Never Ending Story :)

    Wszystko oczywiście chodzi po wciśnięciu przycisku raz po drugim razie jest stop.
    na delay już dawno bym to zrobił no ale właśnie wtedy nie działa przycisk tak jak należy.
  • #22
    EuroGenio
    Level 18  
    Quote:
    to silnik kręci się (100) tylko przez pierwsze 2 sekundy a później chodzi na 230 do Never Ending Story
    Zastanów się...
    Musisz zaingerować w warunki w pętli.
    Podałem Ci zmienną która może na to wpływać.
    Nie musi to być zmienna.
    Może to być właśnie upływający czas.
    Czyli jeśli upłynęło ileś czasu to zmień prędkość na inną...
    Przecież masz już przykład odmierzania czasu w kodzie...
    I na delay() przycisk nie będzie działał...
    Sorry, ale wygląda na to, że nie rozumiesz jak działa Twój dotychczasowy kod.
  • #23
    Piooner
    Level 10  
    Czyli muszę przekształcić tylko ten kod
    Code: cpp
    Log in, to see the code

    żeby timer odliczył 2 sekundy załączył else np.na 5 sekund
    potem wykonał by (np. 5 sekund if) i tak w koło.
    Wtedy by to działało tak jak na dwóch delay-ach.
    Dobrze to rozumiem?
  • #24
    EuroGenio
    Level 18  
    Jeśli chcesz uzyskać tylko naprzemienną zmianę prędkości, to wystarczy, że dodasz pod kodem warunek:
    Code: cpp
    Log in, to see the code
    gdzie x = czas wykonywania bloku if {} + czas bloku else {}
    Spowoduje to przypisanie do zmiennej timer nowego czasu do porównań i znów będzie wykonywany blok if{}, i tak w kółko
  • #25
    Piooner
    Level 10  
    działa tylko else (50)
    Code: cpp
    Log in, to see the code
  • #26
    EuroGenio
    Level 18  
    No i gdzie Ty przypisujesz nowy czas ?!
    Powinno być tak:
    Code: cpp
    Log in, to see the code
    Zwróć uwagę na prawidłowe wstawianie klamerek otaczających blok.
  • #27
    Piooner
    Level 10  
    Code: cpp
    Log in, to see the code


    mam ustawić timer na 7000 tak jak jest
    tu:
    Code: cpp
    Log in, to see the code

    ? bo dalej to nie działa,nie pojmuję tych timerów a chyba nie mam wyjścia bo na boolean też mi nie wychodzi.
  • #28
    EuroGenio
    Level 18  
    Podałem Ci gotowy kod.
    Nigdzie nie używasz timerów a tylko mierzysz czas jaki upłynął od uruchomienia mikrokontrolera ( funkcja millis() ) i porównujesz z zapamiętanym poprzednio w zmiennej o nazwie timer
  • #29
    Piooner
    Level 10  
    Wklejam wysyłam
    silnik 2 sekundy kręci się z małą prędkością później przyśpiesza i tak zostaję więc nie działa
    Code: cpp
    Log in, to see the code


    Myślałem jeszcze o wykorzystaniu blinkwithoutdelay
    Code: cpp
    Log in, to see the code


    tylko w jaki sposób przekształcić kod żeby
    zamiast
    Code: cpp
    Log in, to see the code
    było
    Code: cpp
    Log in, to see the code
    w ten sposób na przemian też mógł bym sterować prędkością.
  • #30
    EuroGenio
    Level 18  
    Sorry pomyłka:
    Zamiast
    Code: cpp
    Log in, to see the code
    powinno być:
    Code: cpp
    Log in, to see the code

    BlinkWithoutDelay miga diodą na tej samej zasadzie.