Skocz do zawartości
wojtekizk

Temat rzeka - przepis na MENU

Pomocna odpowiedź

Witam

Cóż temat wałkowany pewnie z tysiąc razy i pewnie drugie tyle z nas ma lub miało z tym problem 🙂

Aby nie kopiować i dublować publikowanych postów odsyłam chętnych do tutoriala, który popełniłem wcześniej na innym forum.
Mam nadzieję, że moderator nie policzy mi tego za kryptoreklamę, zwłaszcza że to jeden z moich własnych postów 🙂

link:

https://majsterkowo.pl/forum/viewtopic.php?f=38&t=7878

zapraszam do lektury

...i pozdrawiam 

Wojtek

Edytowano przez wojtekizk
  • Lubię! 1
  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

@wojtekizk Bardzo ciekawy opis i bogaty merytorycznie. Podobnie jak post o bibliotece timers. Przyjemnie się czyta takie wpisy bo można z nich wydobyć ciekawe informacje.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

@wojtekizk świetna sprawa, dziękuję i jak znajdę chwilę spróbuję rozgryźć Twoją bibliotekę, a może nawet pokuszę się na własne pomysły. W moim projekcie 

opieram się na nasłuchiwaniu w głównej pętli czy ktoś wcisnął enkoder, jeśli tak, to główny program jest przerywany, a wykonuje się to co tam ktoś zadał. 

Pytanie, bo na razie nie mam czasu usiąść nad tym, Twoja biblioteka opiera się na timerze który ileś razy na sekundę sprawdza przyciski, a po wybraniu jakiejś funkcji, timerem "wciska" ją w loopa? 

Kto mi wytłumaczy po chłopsku co to przerwania od timera? To co napisałem? 

Bo do obsługi obrotu enkodera, używam zdaje się attachInterrupt(), a to zdaje się przerwania procesora.... si? 

Edytowano przez SOYER

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
Cytat

Pytanie, bo na razie nie mam czasu usiąść nad tym, Twoja biblioteka opiera się na timerze który ileś razy na sekundę sprawdza przyciski, a po wybraniu jakiejś funkcji, timerem "wciska" ją w loopa? 

Przerwania Timera de facto nie są przerwaniami stricte "sprzętowymi".

Przerwanie sprzętowe "nasłuchuje" na pinie do niego przypisanym. Jeśli zmieni się stan takiego PINU np. z LOW na HIGH, to wtedy procesor przerywa działanie pętli LOOP  i wskakuje do procedury (funkcji) obsługi takiego przerwania. Jak już zrobi swoje, to procesor zdejmuje sobie ze stosu i z odpowiednich rejestrów potrzebne mu informacje ( które sobie wcześniej zapisał), po to aby sprawnie powrócić do LOOP-a.
Innymi słowy - jak wcisnąłeś np. przycisk (który jest podpięty do wcześniej przypisanego i skonfigurowanego PINU przerwania INT0 lub INT1), to wykonuje się przerwanie sprzętowe, czyli funkcja, którą sobie napisałeś na tę okoliczność (wciśnięcia przycisku) właśnie.

Natomiast przerwanie Timera (właściwie powinno się mówić "od Timera") to po prostu cykliczny skok do podprogramu (funkcji) w ściśle określonych odstępach czasu. Na przykład jeśli skonfigurujesz Timer i powołasz go do żywota w programie, to program np. co 300 ms sam będzie wykonywał przerwanie "od Timera", czyli wykonywał ciąg instrukcji zdefiniowanych w funkcji obsługi tego przerwania właśnie. Nic się w LOOP-ie nie dzieje. A ściślej, to co tam się wyrabia, zostaje tam "zamrożone" na czas obsługi przerwania i potem loop dalej sobie robi co powinien. Jeśli zapuściłeś silnik, zapaliłeś Leda itd., to on nadal się kręci , Led nadal świeci i ani jedno ani drugie nie wie, że w tym czasie co 300ms program cyklicznie wykonuje sobie coś jeszcze 🙂 Jedyny warunek: - funkcja obsługi przerwania musi wykonywać się maksymalnie szybko, czyli na pewno unikamy w niej delay() i staramy się robić możliwie najmniej, tak aby maksymalnie skrócić ilość instrukcji (cykli procesora).

W przytoczonym przykładzie w przerwaniu Timera, sprawdzam co naciśnięto i w instrukcji switch - case i dokonuję wyboru odpowiedniego działania 🙂

 Na szczególna uwagę zasługuje tu sposób w jaki wywołuję funkcję obsługi wciśnięcia klawisz OK: 

case 5: My.items[poz].ItemAkcja();       // wciśnieto klawisz OK - wywołujemy funkcję przypisaną do akt. pozycji w menu.

... i tutaj trzeba "zerknąć" do definicji klasy MyMenu ... bowiem tam jest zdefiniowany wskaźnik do funkcji, po którą sięga konstruktor definiując element MENU.

W ciele biblioteki MyMenu jest zaszyty ten mechanizm przekazywania nazwy funkcji do obsługi określonego elementu menu. Użytkownik nawet nie musi wiedzieć, co się tam dzieje.... ale powinien !... i tutaj zachęcam do zerknięcia do tej biblioteki właśnie 🙂

Nawiasem mówiąc noszę się z zamiarem napisania osobnego postu na temat bardzo fajnej techniki używania w naszych programach wskaźników do funkcji 🙂

Przydałby się także jakiś tutorial na temat samego używania class, bo wszyscy to robimy, a tylko niewielu wie o co tu chodzi. W końcu zapis : int x=0; to przecież powołanie do życia obiektu klasy integer, o nazwie x i przypisanie temu obiektowi wartości 0. Prawda ?

Pozdrawiam

Edytowano przez wojtekizk
  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

Ok, dzięki. 

55 minut temu, wojtekizk napisał:

Jedyny warunek: - funkcja obsługi przerwania musi wykonywać się maksymalnie szybko, czyli na pewno unikamy w niej delay() i staramy się robić możliwie najmniej, tak aby maksymalnie skrócić ilość instrukcji (cykli procesora).

Czyli do obsługi menu jak znalazł. 

Krótko, ileś razy na sekundę nakazujemy procesorów sprawdzać, czy jest wciśnięty któryś przycisk, jeśli tak to używając switch case wydajemy mu kolejne polecenie. 

Sprawa robi się bardziej skomplikowana, w oprogramowaniu, w przypadku podmenu na każdej pozycji menu głównego... Czy może jest banalna, tylko ja tego nie widzę? 

Jeszcze jedno skąd ten okres czasu, timera, wziąć? Doświadczalnie? 

 

Udostępnij ten post


Link to post
Share on other sites
11 minut temu, SOYER napisał:

Sprawa robi się bardziej skomplikowana, w oprogramowaniu, w przypadku podmenu na każdej pozycji menu głównego..

Chyba nieco przesadziłeś z tą komplikacją.

Dla każdej pozycji możliwe są:

a) wykonanie funkcji związanej z daną pozycją (może to być wejście do następnego poziomu menu)

b) przełączenie na inną pozycję na tym samym poziomie

c) powrót do pozycji wywołującej na wyższym poziomie (nie jest konieczny, może być realizowany jako funkcja związana z pozycja "powrót")

Co tu skomplikowanego?

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

🙂 może kol. ethanak nieco przesadził w drugą stronę ... z tą odpowiedzią w krótkich żołnierskich słowach, ale chyba coś w tym jest 🙂

Jak konfiguruje się Timery - to temat na osobny post... w przykładowym programie masz to w setup()... kwestia ustawień odpowiedzialnych rejestrów, podziału preskalera ...i tyle 🙂 a tak na poważnie trzeba się nieco zaznajomić z architekturą samego procka ... lub jeśli nie chcesz sięgać tak daleko to szukaj w gotowcach i pomocy

Pozdrawiam

Edytowano przez wojtekizk

Udostępnij ten post


Link to post
Share on other sites
20 minut temu, ethanak napisał:

Chyba nieco przesadziłeś z tą komplikacją.

Dla każdej pozycji możliwe są:

a) wykonanie funkcji związanej z daną pozycją (może to być wejście do następnego poziomu menu)

b) przełączenie na inną pozycję na tym samym poziomie

c) powrót do pozycji wywołującej na wyższym poziomie (nie jest konieczny, może być realizowany jako funkcja związana z pozycja "powrót")

Co tu skomplikowanego?

Tak, mnie się bardziej rozchodziło o to, że musimy już tworzyć zmienne, pamiętać, w któremu miejscu jesteśmy i jak poszczególne klawisze zmieniają swoją funkcję. Oczywiście jest to do ogarnięcia, sam mam kilka podmenu w swoim projekcie. 

Faktycznie zasada jest ta sama, różnicą w podejściu, jest sam sposób wywołania, od timera, a nie sprawdzanie warunku w każdym obrocie pętli... 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
Cytat

że musimy już tworzyć zmienne, pamiętać, w któremu miejscu jesteśmy i jak poszczególne klawisze zmieniają swoją funkcję. 

Właściwie nie musimy robić aż tak wiele... to tylko kwestia skórki za wyprawkę.... można zmodyfikować bibliotekę tak aby zdefiniować w niej klasę pochodną np. ObslugaMenu, która będzie dziedziczyć po MyMenu, zaś w samej klasie zdefiniować całą obsługę Nawigacji. W funkcji obsługi klawiatury zwracać tylko wskaźnik do obiektu nowej klasy ...i po kłopocie. Jednak ktoś musi to zrobić... a na potrzeby prostego menu nie warto się w to chyba bawić 🙂... zwłaszcza że kompilator / konsolidator całą naszą żmudną pracę obróci w małego HEX-a 🙂

Cytując klasyka (postać Filozofa w "Rejsie") : "nie można być jednocześnie twórcą i tworzywem"  🙂

Pozdrawiam

Edytowano przez wojtekizk

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Napisz odpowiedź...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...