Skocz do zawartości

wojtekizk

Użytkownicy
  • Zawartość

    23
  • Rejestracja

  • Ostatnio

Reputacja

6 Neutralna

O wojtekizk

  • Ranga
    2/10
  • Urodziny 30.04.1961

Informacje

  • Płeć
    Mężczyzna
  • Lokalizacja
    Bydgoszcz
  • Zawód
    informatyk

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

  1. ATR Bydgoszcz, był ALGOL, w ZETO była Odra 1206, poczytaj, poczytaj... to są fakty a nie mity kolego. ZXspectrum był kupiony w Peweksie w 86 Dobra... sam zacząłeś...jak jesteś kolego taki mądry i robisz z siebie GURU to może sam zacząłbyś uczyć, co? Zanim zaczniesz utyskiwać na wykładowców to zobacz jaki materiał na przyszłego magistra do nas trafia? Ludzie nawet podstaw matematyki nie maja, a ja mam ich uczyć algorytmów? Jak mam im mówić o kluczach kryptograficznych RSA, skoro gość nie wie nic o liczbach pierwszych a faktoryzacja liczb to jakieś pojęcie z kosmosu. Napisałeś że programujesz w C, Python i C++ , może więc Ty się pochwalisz czymś "porządnym", bo jak na razie widzę, że porządnie to się Tobie pokićkało kolego. Tłumaczę tak jak potrafię , przykłady są mniej lub bardziej wyszukane, takie aby każdy mógł zrozumieć... nie uczę o konstruktorach i klasach zaprzyjaźnionych już na drugim wykładzie z C++. Uważasz, że nie zgłębiam dość dokładnie, że źle tłumaczę, że sam nie rozumiem? Zgoda. To weź kolego mnie popraw, weź napisz i szczegółowo wyjaśnij dowolny temat... a ja zacznę doszukiwać się luk, i wytykać, że bee, że nie jest porządnie. Zresztą po co te przepychanki, jeśli tym postem pomogłem chociaż jednej osobie coś zrozumieć, skierować na inne tory, wskazać inne rozwiązanie... to już jestem szczęśliwy. Twoje zdanie i opinia to Twoja sprawa, Tobie nie pomogłem i chyba Tobie się nie da
  2. Cały mój pierwszy post to przecież przykład, dość obszerny i szczegółowy.... jeszcze więcej i na gotowo jest tutaj: https://majsterkowo.pl/forum/viewtopic.php?f=38&t=1974 Co mam jeszcze napisać? Jakiś konkretny przykład na zaliczenie dla kilku leniwych studentów? Nie warto, w swoim życiu miałem już studentów, niby coś tam potrafią niby coś wiedzą... a jak dokładnie zapytać, to okazuje się że C++ to dla nich rozmiar stanika jest Od czasu do czasu zaglądam tu i tam, bo pomimo wieku chcę nadal być na bieżąco z nowinkami. Cóż zaczynałem w 1980 r. i wtedy na uczelni królował ALGOL-60, w domu kupiony w Pewexie ZX-Spectrum i wszechobecny Basic. Ech fajne czasy.... Commodore, Amiga , potem pierwszy 386 z koprocesorem Jakie chce pozostawić wrażenie? Nie zależy mi, sam to oceń, przynajmniej się staram... ps. mam wrażenie, że kolega zbyt poważnie podchodzi do tematu... dla mnie to jest hobby, zabawa i ciekawość świata... nic więcej Pozdrawiam
  3. w setupie: co 5 sek. sprawdzam temperaturę, a ew. akcja ON/OFF co np. 1000 i 1200 ms. ciała wszystkich funkcji - dowolna interpretacja obsługi czujnika, a potem to już zwykłe if Naturalnie można to wszystko zrobić w jednej linii ... ale ma być to przykład wykorzystania Timers : ... gdzie TEMPC to zmienna globalna typu int, a PIN 11 ( pinMode(11,OUTPUT); ), podpięty do np. przekaźnika sterującego grzałką , (operator ? - dla chętnych ) Uff... chyba wyczerpałem temat... i jest do zamknięcia wątku. Pozdrawiam
  4. jest mowa o przerwaniach... nie o wątkach Timera Timers jest między innymi po to, aby nie używać delay. Na przykład w jednym wątku zapuszczam jakieś czasochłonne działanie (grzałkę) a w innym sprawdzam np temperaturę i jak jest OK to wyłączam grzałkę. Timers jak słusznie zauważył ethanak nie jest panaceum na wszystkie bolączki tego świata, 8-io bitowy procesor także Prostym językiem, bo to jest forum pasjonatów, majsterkowiczów, zapaleńców, amatorów i wszystkich innych ciekawych świata ... nie tylko informatyków... chyba, że mi coś przez te kilka lat umknęło
  5. w dużym uproszczeniu loop robi swoje pod warunkiem że procesor nie zajmuje się obsługą przerwań...o to mniej więcej mi chodziło w ost. zajawce ps. musisz być aż tak cholernie zasadniczy? pozdrawiam
  6. Jakoś trudno mi jest sobie wyobrazić taką sytuację, aby jakieś zadanie trwało aż tak długo.... jeśli na przykład jakiś pomiar trwa np 750 ms. (słynny czujnik temperatury DS...) to ten pomiar wstawiasz do loopa, niech tam sobie tak potwornie długo mierzy... a np. w innym wątku załączasz silnik, jeszcze w innym sprawdzasz czy np ramię dojechało do okr. pozycji a jeszcze w innym wyłączasz silnik. Loop sobie robi co trzeba.... wtedy kiedy może.... poza obsługą wątków.
  7. 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
  8. 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
  9. Gieneq - nie jestem pewien o co dokładnie chodzi w Twoim zliczaniu / odświeżaniu ale nasuwają mi się 2 konkluzje: 1). Każde wywołanie jakiejkolwiek funkcji, czyli nawet obsługi przerwań, sprzętowych, programowych czy Timerów wiąże się z "zaprzęgnięciem do pracy procesora", który stara się na boku robić coś jeszcze, prawda? Niestety procesor póki co jest jeden, więc na czas obsługi np przerwania robi to, co do niego należy i nie robi niczego w LOOP-ie ! Jeśli procedura obsługi przerwania właśnie zawiera w sobie wiele instrukcji, to procesor musi wykonać sporo więcej taktów (nawet dla procesorów "riskowych"), czyli jednak upływa troszkę czasu, prawda? Wyobraźmy sobie taki oto scenariusz: - w Loop-ie zapuściłeś silnik, który się kręci, powiedzmy 5000 obr/sek. - masz do niego podpięty enkoder i zliczasz impulsy, na przykład przez inkrementację zmiennej licznik...(w pętli loop) , coś w stylu: if(digitalRead(1) ==LOW) licznik ++; - to jeśli wywołasz na boku przerwanie (wykonasz jakieś instrukcje) to silnik będzie się przecież nadal kręcić.... ale już Twoja zmienna w tym czasie nie będzie zwiększać swojej wartości, prawda? czyli ileś tam impulsów przeleci bez echa (i nie pomoże nawet przedrostek volatile) Po powrocie z przerwania licznik będzie się zwiększał. Nie będzie gwarancji, że nic nie uciekło niestety. 2). Wobec powyższego modyfikujesz kod i impulsy z enkodera podpinasz do Pinu INT0 (przerwanie sprzętowe) a w funkcji obsługi zwiększasz wartość zmiennej licznik.... Teoretycznie jest OK, teraz każdy impuls będzie zapisany.... ale czy oby na pewno? Co jeśli w tym czasie będziesz miał podpięte inne przerwania, np . od Timera lub drugi silnik z drugim enkoderem? Nikt nie da Ci gwarancji, że w skutek zajęcia procesora obsługą jednego z 3 przerwań silnik nie wykona maleńkiego obrotu o kąt który zarejestruje enkoder? ...Czyli rodzi nam się kolejny problem - priorytety przerwań, a tutaj bez gruntownego zaznajomienia z architekturą procesora i notą katalogową procka, łącznie z analizą przedstawianych tam wykresów... raczej się nie ujedzie Wcześniej czy później należy bowiem zrozumieć, że mamy oto przed sobą tylko mały procesor 8 bitowy, a marzy nam się na nim wielozadaniowość, z którą nie radzą sobie nawet wypasione 8 rdzeniowe procesory w naszych telefonach, porażka, prawda? Pozdrawiam
  10. 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
  11. 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
  12. Witam Fakt jest kilka co najmniej bibliotek Timers, stąd nieporozumienia. Ta, którą opisałem powyżej jest z 2013 roku, więc jest szansa,że jest jedną z pierwszych. Nie jest to jednak chyba do końca ta sama, która jest opisana na kursie. Zmiana nazwy jest dobrym pomysłem, więc aby uniknąć nieporozumień proponuję spakować sobie ją ponownie w formie ZIP-a pod inna nazwą... i potem "bezczelnie" dołączyć do swojego IDE ups.... trzeba troszkę pogrzebać w pliku *.h zanim to zrobimy niech to będzie mały sprawdzian dla czytelnika tego postu Pozdrawiam
  13. heyah Zakładam, że na początku ten obrót serwa o 30 st. to jest dokładnie ruch "na wprost", potem dla prawo masz 0 a w lewo 60 ( czyli prawo=0, na wprost 30 a w lewo 60)... Zobacz, krok po kroku co robisz w pętli loop: 1. (pierwsze if): nie ma przeszkody -> jedziesz na wprost jest przeszkoda - zatrzymujesz robota, obracasz czujnik w prawo o 30 st., to delay(800) dobrałeś doświadczalne zakładam, że zatrzymałeś robota, bo była przeszkoda, czyli obróciłeś wieżyczkę Twojego Rudego 102 o 30 st. 2. (drugie if) : nie ma przeszkody -> obracasz cały czołg o 30 st. (to delay(400) empiryczny czas na obrót o 30 st. ... i co robisz dalej? ano przechodzisz do trzeciego if-a 3. (trzeci if): tutaj masz obrócony czołg w prawo i wieżyczkę, która obecnie "zezuje" o 30 st. w prawo od pozycji na wprost ???? i jeśli Grigory nie widzi przeszkód ( a może tak być prawda) ... to każesz mu obrócić się w lewo. Wracasz do punktu wyjścia. ???? Czyli cały algorytm jest delikatnie mówiąc nieco skopany Przemyśl dokładnie krok po kroku co robi Twój czołg i zastanów się jak tu uprościć działanie. Czy oby na pewno musisz obracać wieżyczką, i potem wracać z nią do pozycji "na wprost"? Czy może nie lepiej byłoby obracać całym czołgiem, i po obrocie sprawdzić czy można już jechać? Pomysłów jest kilka. aaaa.... i jeszcze coś , może po każdym obrocie czołgu warto by zatrzymać cały czołg, bo kolejny if wykonuje się podczas obrotu Pozdrawiam
  14. Witam Od niedawna wczytuję się w Forum na Forbocie (wcześniej robiłem tylko zakupy) i przez te 5 lat jakoś nie było okazji tu zaglądać. Teraz widzę jak wiele straciłem - kursy programowania Arduino a teraz genialne kursy dla STM i to z biblioteką HAL ... duży szacun Jest już lepiej z polskimi odpowiednikami (i tłumaczeniami prawie dosłownymi) obcojęzycznej literatury, ale taki kurs bez konieczności kupowania drogich i często nietrafionych pozycji jest kopalnią wiedzy dla początkujących w temacie. Arduino, mimo że ma już więcej niż10 lat ciągle jest popularne i budzi zainteresowanie wśród szerokich rzeszy zapaleńców i majsterkowiczów. Gdy robiłem podyplomówkę w ramach akcji (50 + ... tak, to kryteruim to wiek )... to na naszej uczelni nikt z pracowników tejże nawet nie słyszał o projekcie Arduino... a ja wybrałem sobie kontrowersyjny temat "Projekt robota MINISUMO w oparciu o moduł Arduino UNO ". Na szczęście teraz jest już o niebo lepiej. Sami studenci robotyki orientują się w temacie o wiele lepiej od swoich wykładowców Ale do rzeczy... czytając liczne wpisy na Forum zorientowałem się, że spora grupa entuzjastów Arduino wcześniej lub później boryka się z problemem wielozadaniowości. Jakieś 5 lat temu udzielałem się troszkę na forum majsterkowo.pl i tamże popełniłem kilka artykułów mniej lub bardziej przydatnych Chciałbym zainteresować kolegów (i koleżanki oczywiście) zastosowaniem w projektach biblioteki Timers ( nie Timer One ... Timer Tree itp.) Biblioteka Timers jest tak banalnie prosta, że jej autor nawet nie wysilił się na podział jej na pliki *.h i *.cpp, a po prostu umieścił wszystko w pliku nagłówkowym. Przy okazji przypomnę, bo też o tym kiedyś pisałem, jak czytać pliki bibliotek....że w tejże bibliotece i w każdej innej wartościowej...jest także bardzo przydatny pliczek : keywords.txt, dzięki niemu i wpisom w sekcjach KEYWORD1 KEYWORD2 mamy kolorowanie składni przy użyciu zmiennych i funkcji bibliotecznych Biblioteka Timers.zip jest do pobrania i zalokowania w IDE ( bo trudno to nazwać instalacją) w załączniku poniżej. A o to opis najważniejszych funkcji tejże biblioteki: OPIS BIBILOTEKI (skrócony): ---------------------------- Czym biblioteka Timers różni się od biblioteki Timer, TimerOne czy TimerTree? Przede wszystkim prostotą użycia jej w programie. Zasadniczo korzystamy z 4 wygodnych funkcji składowych klasy Timers: 1) Konstruktor - inicjalizacja obiektu klasy Timers. Przykład: Timers <8> akcja; // - Powołujemy do życia obiekt klasy Timers o przykładowej nazwie akcja, który może obsłużyć 8 niezależnych wątków (zdarzeń) 2) Funkcja attach(nr wątku, interfał wywołania, funkcja obsługi), gdzie: - numer wątku, to numer jednego z 8 wcześniej zdefiniowanych w konstruktorze wątków; - interwał - odstęp czasu w ms. W tych odsępach będzie wywoływana funkcja obsługi - funkcja obsługi - nazwa funkcji, jak ma być wykonywana. W tym zakresie funkcja attach jest łudząco podobna do funkcji attachInterrupt. Przykłady: akcja.attach(2,5000,pokazTemp); - co 5 sekund wątek 3 (liczymy od 0) wywołuje funkcję pokazTemp() akcja.attach(0, 1000, pokazCzas); - co 1 sekundę wątek pierwszy wywołuje funkcję pokazCzas() akcja.attach(1,0,flopKierunek); - definiujemy wątek nr 2, ale nie mamy na razie zamiaru z niego korzystać - interwał =0 UWAGA!!! Funkca attach musi być zainicjowana w funkcji setup() dla każdego z wątków. Jeśli nie mamy zamiaru od razu korzystać z danego wątku, to w funkcji attach ustawiamy interwał na 0. 3) Funkcja updateInterval(nr wątku, akt interwał), gdzie: - nr wątku, to numer jednego z 8 wcześniej zdefiniowanych w konstruktorze wątków; - akt interwał - dynamiczna zmiana czasu wywoływania funkcji, w szczególnym przypadku dla interfał=0 wyłączamy obsługę wątku. Przykłady: akcja.updateInterval(2,0); - zatrzymanie obsługi wątku nr 3 akcja.updateInterval(4,189); - zmiana lub ustawienie dla wątku nr 5 czasu wywoływania funkcji obsługi na 189 ms. 4) funkcja process() - wywoływana w pętli loop, uruchamia globalną obsługę wszystkich zadeklarowanych w konstruktorze wątków Przykład: akcja.process(); ...a oto przykładowy program: [/code] #include <Timers.h> // dołączona biblioteka Timers (konieczna do poprawnej pracy ... jest w załączniku) Timers <8> akcja; // na poczatek 8 niezależnych wątków (procesów, zadań, procedur, akcji itp.) int x=1, y=2; // takie zmienne pomocnicze, dla testów; // --- poniżej przykładowe definicje zadań: ------ void zadanie1() { // tutaj obsługa jakieś sekwencji zdarzeń, zapalenie diody, ruch silnika itp } void zadanie2() { // tutaj obsługa jakieś sekwencji zdarzeń dla zadania 2 } void zadanie3() { } void zadanie4() { // analogicznie dla pozostałych zadań } void zadanie5() { } void zadanie6() { } // ------------------------------------------------ void setup() { // Teraz najważniejsze :-) akcja.attach(0, 1000, zadanie1); // Wątek 1: wcześniej zdefiniowana funkcja o nazwie zadanie1, wywoływana co ok 1 sek. akcja.attach(1,0,zadanie2); // anlogicznie dla zadanie2 , ale tutaj na razie nie robimy nic, bo interwał =0;. akcja.attach(2,5000,zadanie3); // zadanie3 wykonuje się co 5 sek. (np. pomiar temperatury) akcja.attach(3,200,zadanie4); // co 200 ms sprawdzamy np stan przycisku akcja.attach(4,189,zadanie5); // a co 189 ms sprawdzamy stan czujnika odległości akcja.attach(5,1211,zadanie6); // a co 1211 ms wysyłamy jakis komunikat na Seriala } void loop() { akcja.process(); // inicjalizacja lub aktualizacja wszystkich procedur(wątków, zdarzeń itp.) if(x==1){akcja.updateInterval(1,300);} // odpalamy akcje dla zadania 2, co 300 ms. if(y!=2) {akcja.updateInterval(4,0);} // zatrzymujemy zadanie 5 } Proszę zauważyć, że w loop nie ma delay.:-) Możemy się zatem skupić na definicji funkcji obsługi zdarzeń, czyli zająć się logiką programu i nie borykać się już więcej z zawieszaniem się obsługi programu. mamy zatem tu namiastkę wielozadaniowości .... nasz minisystem "nasłuchuje" w określonych przez nas odstępach czasu co się wydarzyło i zależnie od sytuacji zajmuje się obsługą zdarzeń. Na co należy uważać? Lepiej aby interwały nie zachodziły na siebie, czyli należy dokładnie przemyśleć i oszacować czasy wykonywania poszczególnych zadań. Nie zalecam użycia w samych funkcjach delay(). Przecież możesz w jednym zadaniu np. uruchomić silnik a w drugim go zatrzymać (zależnie od warunku, który możesz sprawdzać np w zadaniu nr 7 :-). Całkowita dowolność, a jak 8 zadań to za mało to możesz zawsze utworzyć i obsłużyć kolejny obiekt klasy Timers, na przykład taki " Timers <6> akcja2; Jedynym ograniczeniem może być tylko ograniczona pamięć mikrokontrolera Bardziej obszerny przykład zamieściłem 5 lat temu na forum majsterkowo.pl Gorąco zachęcam także do zapoznania się (przejrzeniem źródła Tmers.h)... Leci własnie mecz siatkówki, grają nasze złotka ...więc kończę Pozdrawiam Wojtek Timers.zip
  15. To zadanie nie jest może akurat w temacie programowania.... ale uczy pokory i pełen szacun dla dydaktyki... czekam na odpowiedź
×
×
  • Utwórz nowe...