Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Computer Controls
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Wiele wątków a jedno Arduino

Factisek 01 Sty 2018 15:47 3672 115
  • #91 01 Sty 2018 15:47
    alienHater
    Poziom 10  

    @Factisek
    Zobacz do tego artykułu :D

    Kurs Arduino II – #9 – wielozadaniowość, opóźnienia z millis()

    Bardzo prosty artykuł. Co ciekawe, powstał dzień po założeniu przez Ciebie tematu.
    Dla twojego zastosowania, wykorzystanie millis() będzie w sam raz.
    W ekstremalnych przypadkach masz jeszcze micros() - uwaga na reset licznika(~70 minut).

    Przecież czujnik podaje dłuższy sygnał od 1 ms. Nie mówiąc o np zwykłym przycisku(monostabilnym), w którym przez kilkanaście ms drgają styki(zabezpieczasz to programowo, wystarczy zapisać czas i dodać założenie do pętli if() ).

    Przerwania zawieszają działanie głównej pętli, dlatego kod do wykonania powinien być jak najprostszy(przy okazji - przerwanie zakłóca działanie millis() z tego co wiem).

    Przerwania powinno stosować się tylko w przypadku zadań priorytetowych. Można się nad tym sprzeczać w badziej skomplikowanych projektach.
    Tutaj kolega potrzebuje prostego rozwiązania i jak sam przyznał, dopiero zaczyna swoją przygodę z Arduino.

  • Computer Controls
  • #92 01 Sty 2018 16:02
    2675900
    Użytkownik usunął konto  
  • #93 01 Sty 2018 16:10
    alienHater
    Poziom 10  

    Możesz to uzasadnić?
    W odniesieniu do sterowania oświetleniem schodowym z wykorzystaniem arduino.

    Po za tym, kluczową kwestią jest to co uznamy za zadanie priorytetowe oraz jak wygląda cały program.

    W tym zastosowaniu, bez problemu można napisać prosty kod, który będzie 100% skuteczny i nie będzie korzystał z przerwań.

    A nawet jeśli ktoś chce z nich skorzystać to kod i tak jest całkiem prosty.

  • #94 01 Sty 2018 16:12
    2675900
    Użytkownik usunął konto  
  • #95 01 Sty 2018 16:24
    alienHater
    Poziom 10  

    Właśnie to zrobiłem, w ostatnim poście.

    Sam cały czas się uczę(arduino) i mam problem ze znalezieniem logicznego uzasadnienia. Dlatego drążę ten temat, nie chodzi mi o jakąś słowną przepychankę.

    Skąd parcie na wykorzystanie przerwań hardwarowych w tak prostych zastosowaniach?
    Chyba tylko po to żeby nabrać dobrych nawyków w skomplikowanych projektach?

    Rozumiem, że przerwanie gwarantuje to, że nie pominiemy żadnego sygnału z "zewnątrz" w wyniku zajęcia procesora innym zajęciem.

    Ale osoba która się uczy, powinna poznać sposoby, jak ten z podanego wyżej linku, aby tworzyć kod który nie łąpie zwiech, wykonując jedną akcję, oraz jak się ich pozbywać.
    Tak, aby kod był wielozadaniowy.

  • #96 01 Sty 2018 16:40
    22053
    Użytkownik usunął konto  
  • Computer Controls
  • #97 01 Sty 2018 16:42
    alienHater
    Poziom 10  

    Tak, dlatego napisałem "z tego co wiem".
    Czytając inne poradniki(nie będę teraz szukał) gdy sam wgryzałem się w ten temat, była wyraźnie podana informacja że przerwania zakłócają działania tej funkcji.
    Zasygnalizowałem tylko, że powinien sobie to sprawdzić, bo info z artykułu może być nieprawdziwe.
    Też wydaje mi się to dziwne skoro to niezależny licznik.

  • #98 01 Sty 2018 16:44
    2675900
    Użytkownik usunął konto  
  • #99 01 Sty 2018 16:49
    22053
    Użytkownik usunął konto  
  • #100 01 Sty 2018 16:55
    alienHater
    Poziom 10  

    Po raz kolejny użyję zwrotu "z tego co wiem".
    Arduino ma hardwarowy rejestr(bufor) do którego zapisywane są dane(przy komunikacji szeregowej). Jeżeli nie użyjemy przerwania od razu gdy pojawią się tam dane ( Serial.available() == 1) nic się nie stanie. Dla przykładu, obecnie korzystam z modułów sparkfun który jak na razie nie ma bibliotek umożliwiających(a na pewno przez długi czas nie miał) wykorzystanie przerwań dla transmisji.

    Jeżeli chodzi o te "dwie drogi" - albo użyjemy przerwań albo millis(). Przepełnienie następuje po kilkudziesięciu dniach i nie ma większego problemu aby uniknąć błędów z tym związanych.

    Zgadzam się z tym, że przy bardziej skomplikowanych projektach wykorzystanie przerwania daje gwarancję prawidłowej pracy, bez potrzeby martwienia się o przebiegi i błedy. Tak jest prościej.

    @R-MIK
    z tego co piszesz wynika, że wpisujesz przerwanie programowe?
    A w tym zastosowaniu można wykorzystać przerwanie sprzętowe. Bez specjalnego kodu. Zmieni się stan na wejściu pinu od przerwań( w zależnośći od modelu arduino ma ich od 1 do kilku), to wywoływana jest krótka pętla która sprawdza stan wejść czujników, wykonuje prostą akcję oraz wraca do pętli głównej.

  • #101 01 Sty 2018 16:57
    drobok
    Poziom 29  

    milis nie jest sprzętowe, bo w przerwaniu jest inkrementowana zmienna, którą zwraca funkcja

  • #102 01 Sty 2018 17:15
    22053
    Użytkownik usunął konto  
  • #103 01 Sty 2018 17:16
    2675900
    Użytkownik usunął konto  
  • #104 01 Sty 2018 17:16
    alienHater
    Poziom 10  

    W takim razie, gdyby głównym zadaniem urządzenia był pomiar czasu, w jaki sposób zabezpieczyć jego pomiar przed jakimikolwiek błędami, w tym użyciu przerwań? Napewno zastosowałbym inny, dokładniejszy oscylator niż ten wbudowany w procesor. Co dalej?

  • #105 01 Sty 2018 17:17
    22053
    Użytkownik usunął konto  
  • #106 01 Sty 2018 17:21
    2675900
    Użytkownik usunął konto  
  • #107 01 Sty 2018 17:29
    alienHater
    Poziom 10  

    R-MIK napisał:

    Przyznam, że 99,99% moich programów zaczyna się od napisania przerwań od timera, najczęściej 1ms (w 8051 było to 10ms bo był koszmarnie wolny i rozbudowane przerwania wywyływane co 1ms zużywały 50% czasu procka).

    Do tej wypowiedzi. Nie uzależniasz przerwania od specjalnego pinu procesora, który bezwzględnie wymusza wykonanie konkretnych akcji.
    Tworzysz własne przerwania prgramowe, które wymuszają akcje co określony odstęp czasu. Tak to rozumiem, mylę się?
    Nie miałem za bardzo wcześniej styczności z takim zastosowaniem(które jest u Ciebie oczywiste w każdym zastosowaniu). Mógłbyś dać mi link w którym znalazłbym opis w jaki sposób prawidłowo tworzyć takie przerwanie? Skoro je stosujesz jest to zapewne rozwiązanie skuteczne.

    Chciałbym mierzyć czas z dokładnością do 1 ms. Np czasy biegu zawodnika. Czujnik startu i stopu.

    Piotrus_999 napisał:
    alienHater napisał:
    Napewno zastosowałbym inny, dokładniejszy oscylator niż ten wbudowany w procesor.
    No widać nawet nie znasz tego arduino - arduino ma kwarc zewnęrzny. Zresztą jego zastosowanie jest iezbędne w 99% przypadków - a zając cenę trudno znaleźć uzasadnienie dla nieużywania.


    Wiem że arduino posiada zewnętrzny RTC. Na pewno w/w moduł.
    Nie wiem czy jest on wykorzystywany z tzw automatu. Prawdopodobnie muszę się z nim skomunikować. Nie jest tak że procek arduino korzysta z własnego oscylatora, a dopiero odpowiednio napisany kod będzie korzystał z RTC?

  • #108 01 Sty 2018 17:33
    drobok
    Poziom 29  

    Praktycznie rzecz ujmując używasz zewnętrznego rtc, albo właśnie milis / micros (bo w avr też byś mierzył ilość przejść timera - i wyjdzie na to samo), najlepiej wziąć jakiś wzorzec czasu np gps albo krajową częstotliwość wzorcową, ew sygnału akustycznego.

    Co do micros https://ucexperiment.wordpress.com/2012/03/17/examination-of-the-arduino-micros-function/
    w skrócie:
    return((timer0_overflow_count << 8) + TCNT0)*(64/16);
    Czyli w praktyce takie milis+wartość timera

  • #109 01 Sty 2018 18:05
    22053
    Użytkownik usunął konto  
  • #110 01 Sty 2018 19:00
    alienHater
    Poziom 10  

    Dzięki, muszę na spokojnie to przeanalizować. Nie znam dokładnie czystego C, w zastosowaniu AVR(nazw rejestrów itd).
    Doinformuję się.

    R-MIK napisał:
    Banał. Nie trzeba używac przechwytywania sprzetowego, które ograniczyłoby pomiar czasu do 65sekund.


    Nie rozumiem dlaczego miałoby go ograniczyć.

    Przykład na pomiarze czasu biegaczy.
    Do tej pory, gdybym miał zmierzyć czas 2 zawodników( 2 czujniki stop i powiedzmy startują na sygnał dźwiekowy, dla uproszczenia).

    Zrobiłbym to w taki sposób:

    1. Włączam sygnał dźwiękowy i zapisuję aktualny czas z millis() do zmiennnej "start".
    2. Osobna pętla sprawdzająca przerwanie sprzętowe(wykrycie zmiany stanu czujnika)
    powoduje sprawdzenie czy to czujnik 1 czy 2,
    zapis aktualnego czasu millis() odpowiednio do zmiennej stop1 lub stop 2.
    powrót do pętli głównej.
    3. W pętli głównej obliczenie czasu biegu stop 1 lub stop2 - start.
    Jeśli obaj skończyli porównanie wartości i wskazanie zwycięzcy.

    Tyle że przerwanie sprzętowe zakłóca millis(). Nie wiem jak bardzo.

    Jeżeli dobrze rozumiem wykorzystanie Twojego kodu, również wymusza przerwanie pętli głownej i wykonanie specjalnego kodu.
    Tyle że sprawdza stan co np 1 ms.

    Co się dzieje jeżeli użyję twoich 4 przerwań z innymi czasami, które nałożą się na siebie? Jedno przerwie drugie? Wykonają się po kolei?

    Dodano po 16 [minuty]:

    Czyli pomiar każdych 10 minut to od 30 do 2 ms błędu. 2 ms całkiem nieźle. Jednak chcę dążyć do idealnej wartości.

    LFTCXO070898 takie cudeńko ma 0,5 ppm. Muszę poczytać jak coś takiego podpiąć, i prawidłowo określić wartość czasu przy wykorzystaniu przerwań.

  • #111 01 Sty 2018 19:32
    22053
    Użytkownik usunął konto  
  • #112 01 Sty 2018 19:41
    alienHater
    Poziom 10  

    R-MIK napisał:
    alienHater napisał:
    Dzięki, muszę na spokojnie to przeanalizować. Nie znam dokładnie czystego C, w zastosowaniu AVR(nazw rejestrów itd).
    Doinformuję się.

    R-MIK napisał:
    Banał. Nie trzeba używac przechwytywania sprzetowego, które ograniczyłoby pomiar czasu do 65sekund.


    Nie rozumiem dlaczego miałoby go ograniczyć.

    Bo Arduinowcy boja sie przerwań a trzba by użyc przerwań od przepełnienia timera.


    Boją się ponieważ są początkujący i brakuje im wiedzy. Obecnie łatwiej zacząć przygodę od takiego arduino, gdzie wszystko jest uproszczone.
    Dziękuję za pomoc. Zrozumiałem co i jak :D
    Od dłuższego czasu nosze się z zamiarem przesiadki na czysty C++. Żeby to zrobić trzeba jednak wiedzieć co ma się "pod maską" i jak tym sterować.

    Przykładowo datasheet z opisem hardwaru mojego sparkfuna ma blisko 600 stron. Zaczynałem od niekorzystania z dedykowanych bibliotek, teraz biorę się na przesiadkę z arduinowej nakładki.

    Nie ma nic od razu, a szybkość kodu napewno wzrośnie.

  • #113 01 Sty 2018 19:45
    22053
    Użytkownik usunął konto  
  • #114 01 Sty 2018 19:53
    alienHater
    Poziom 10  

    R-MIK napisał:
    może trwać przy 16MHz

    Podajesz taktowanie procesora? Xtensa 32 bit LX6 możę pracować z frq do 240MHz. Standardowo chyba 80. Czyli czas przerwania byłby jeszcze krótszy. Faktycznie, powinno się w takim wypadku bez niego obyć.

  • #115 02 Sty 2018 10:42
    22053
    Użytkownik usunął konto  
  • #116 04 Sty 2018 00:34
    alienHater
    Poziom 10  

    Zawartość biblioteki:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kod: c
    Zaloguj się, aby zobaczyć kod


    Opis autora

    Znałem tą bibliotekę wcześniej, stosowałem podobne rozwiązanie(bez bibliotek).

    Wygląda na to, że powyższy kod co "okrążanie" oblicza :
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Jeżeli warunek zostanie spełniony, wystawia true, i zostaną wykonane np pętle "if" w których zostały spełnione wszystkie warunki.

    Wystawienie "true" nie powoduje przerwania pętli loop, wykonanie specjalnych instrukcji i powrót do ostatniej instrukcji.

    Po prostu, instrukcje te zostaną wykonane przy kolejnym obiegu loop.

    Używałem tego podobnie, w mniej więcej ten sposób.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Nie ma to chyba nic wspólnego z DMA, czy też zrzucaniem zadań na peryferia wykonujące konkretne zadania i zwracające np "1" w przypadku wymaganej interwencji procesora(przerwanie loop)?

    Twoje wirtualne timery działają na tej samej zasadzie co powyższa biblioteka?