logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[AT16][C] Wątki/timer zamiast delay?

tmazur 31 Maj 2011 12:44 3332 24
REKLAMA
  • #1 9562375
    tmazur
    Poziom 10  
    Witam,

    Mam obsługę termometru, która znajduje się w pętli głównej programu. Jest tam również obsługa przycisków i innych rzeczy. Problem tkwi w tym, że odczyt temperatury z termometru trwa 750ms, po wysłaniu komendy program czeka 750ms przed odczytem temperatury. Wciśnięcie przycisku, które trwa krócej niż 750ms najczęściej skutkuje brakiem reakcji programu na wciśnięcie przycisku. Myślałem o dwóch możliwych rozwiązaniach:

    1. Wykorzystać timer1 z przerwaniem generowanym co 2s
    2. Wykorzystać wątki(widziałem na forum tematy o wątkach na AVR)

    Wydaje mi się, że oba rozwiązania niejako omijają problem zamiast go naprawić. Czy istnieje inny sposób?
  • REKLAMA
  • #2 9562390
    tadzik85
    Poziom 38  
    Jeśli masz na myśli pseudo wielowątkowość która omawiana jest w jednym z tematów jest to najlepsze i poprawne rozwiązanie.
  • Pomocny post
    #3 9562868
    tmf
    VIP Zasłużony dla elektroda
    ad 2. Nie ma jak strzelać z armaty do wróbla. A po co czekać te 750ms? Nie prościej zrealizować obsługę termometru asynchronicznie, np. w przerwaniu, a temperaturę odczytywać ze zmiennej uaktualnianej przy kolejnych odczytach? A więc rozwiązanie 1 jest ok. Z tym tylko zastrzeżeniem, że samo wysłanie komendy konwersji, lub odczyt temepratury też trwa, nie aż 750ms, ale te 1-2ms musisz liczyć i wziąć pod uwagę, że tyle będzie trwała obsługa przerwania. Chyba, że... ale to już temat na inny wątek :)
  • Pomocny post
    #4 9562885
    asembler
    Poziom 32  
    A już tak najprosciej bez armat, czołgów i bombowcós. to zamiast 750ms oczekiwania wystarczy czekać 250x3ms. Czyli o ile mnie zrozumiałes co 3 ms sprawdzasz klawisz a co 3x250ms odczytujesz temperature - inaczej mówiac tworzysz pętle ob licznik 0-250 w której umieszczasz program obsług kalwisza i opóźnienie 3ms.
  • #5 9563128
    tmazur
    Poziom 10  
    @tmf Nie do końca jestem pewien czy zrozumiałem. Miałem na myśli obsłużyć w przerwaniu 1. wysylanie komendy pomiaru 2. delay 750ms 3. odczyt temperatury. Tylko w sumie to nie jestem pewien czy dając delay w przerwaniu program główny będzie się wykonywał w tym czasie? Chyba nie. Domyślam się że chodzi o wykonanie polecenia pomiaru w petli glownej, a odczytu w przerwaniu. Do tego jakas flaga ze czekamy na odczyt pomiaru(zeby nie wyslac 500 polecen pomiaru zanim zdazymy odczyt pierwszy). Tylko jak to zrealizować?

    @asembler Wydaje mi się że to rozwiązanie odpada jeśli mam program, który nie wykonuje się w takim samym czasie w kazdym cyklu. Aczkolwiek będzie to chyba działać bardzo fajnie w przerwaniu wykonywanym np. co 10ms, wystarczy ustawić aby tylko przy niektórych wywołaniach wykonywało pomiar/odczyt i wtedy nie potrzebuję żadnego opóźnienia.
  • #7 9563173
    tmazur
    Poziom 10  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #8 9563179
    asembler
    Poziom 32  
    tmazur napisał:

    @asembler Wydaje mi się że to rozwiązanie odpada jeśli mam program, który nie wykonuje się w takim samym czasie w kazdym cyklu. Aczkolwiek będzie to chyba działać bardzo fajnie w przerwaniu wykonywanym np. co 10ms, wystarczy ustawić aby tylko przy niektórych wywołaniach wykonywało pomiar/odczyt i wtedy nie potrzebuję żadnego opóźnienia.

    A jakie ma znaczenie czy opóźnienie całkowite wyniesie 750 czy 1000mS wazne zeby klawisz dziala i odczyt tempertury też co zostało spelnione.
  • #11 9563272
    tmazur
    Poziom 10  
    @asembler Wydaje mi się że można to zrealizować znacznie sprawniej. 750 czy 1000ms nie robi różnicy, ale w programie mam oczekiwanie na puszczenie przycisku po jego wciśnięciu. Co się stanie jeśli ktoś wciśnie przycisk i będzie go trzymał kilka sekund? Odczyt temperatury już chyba nie będzie poprawny.

    @dondu Czyli rozumiem, że w tym timerze zrobię obsługę zarówno termometra jak i przycisku? Myślałem o tym żeby zrobić w nim obsługę samej temperatury. Jeżeli chcę oczekiwać na zwolnienie przycisku po jego wciśnięciu to chyba nie mogę zrobić tego w przerwaniu. No chyba że czegoś nie zrozumiałem. Przerwań się nie boje, w programie jest już zastosowany jeden licznik do realizowania całkiem niezależnego zadania. Na marginesie wydaje mi się że udzielałeś się w wątku nt. tamtego timera. ;)

    @piotrva Atmega16, ostatnio mam manię skracania wszystkiego :)
  • Pomocny post
    #12 9563299
    dondu
    Moderator na urlopie...
    tmazur napisał:
    Czyli rozumiem, że w tym timerze zrobię obsługę zarówno termometra jak i przycisku?

    Jak najbardziej.


    tmazur napisał:
    Jeżeli chcę oczekiwać na zwolnienie przycisku po jego wciśnięciu to chyba nie mogę zrobić tego w przerwaniu. No chyba że czegoś nie zrozumiałem.

    Oczekiwanie w tym przypadku będzie polegało na tym samym co wykrywanie jego przyciśnięcia tylko stany sprawdzane będą przeciwne - to naprawdę proste. Zacznij pisać a my pomożemy.

    tmazur napisał:
    Przerwań się nie boje, w programie jest już zastosowany jeden licznik do realizowania całkiem niezależnego zadania.

    Tym bardziej idź w tę stronę.

    tmazur napisał:
    Na marginesie wydaje mi się że udzielałeś się w wątku nt. tamtego timera. ;)

    :)
  • REKLAMA
  • #13 9563302
    asembler
    Poziom 32  
    tmazur napisał:
    @asembler Wydaje mi się że można to zrealizować znacznie sprawniej. 750 czy 1000ms nie robi różnicy, ale w programie mam oczekiwanie na puszczenie przycisku po jego wciśnięciu. Co się stanie jeśli ktoś wciśnie przycisk i będzie go trzymał kilka sekund? Odczyt temperatury już chyba nie będzie poprawny.


    A co się ma dziać? Będzie się działo dokładnie to co zaprogramujesz
    Na przykład tak: Wykrycie wcisnietego klawisza ustawia flagę i wykonuje program obsługi, po wykonaniu programu wraca do pętli a ponieważ flag jest ustawiona wiec nie wchodzi drugi raz w obsługę aż do skosowania flagi. Kasowanie flagi oczywiscie nastepuje poprzez wykrycie puszczenia klawisza.
    Ja widac nie musisz wcale oczekiwac w pętli na puszczenie klawisz a jedynie badac co 3ms czy klawisz jest puszczony.
  • #15 9563356
    tmf
    VIP Zasłużony dla elektroda
    Właściwie to nawet timera nie potrzebujesz. Po prostu zapodajesz konwersje i tyle. Temperaturę czytasz w dowolnym momencie - jeśli konwersja nie będzie jeszcze zakończona to po prostu odczytasz poprzednią wartość temperatury, jeśli się w międzyczasie zakończy to odczytasz bieżącą.
  • #16 9563396
    asembler
    Poziom 32  
    tmf napisał:
    Właściwie to nawet timera nie potrzebujesz. Po prostu zapodajesz konwersje i tyle. Temperaturę czytasz w dowolnym momencie - jeśli konwersja nie będzie jeszcze zakończona to po prostu odczytasz poprzednią wartość temperatury, jeśli się w międzyczasie zakończy to odczytasz bieżącą.


    Nie wiem czy to zadziała przy parasite power.
  • #17 9563420
    tmazur
    Poziom 10  
    @dondu W takim razie korzystam z tego co zaproponowałeś + flagi które opisał @asembler

    @tmf Z początków zabawy z termometrem pamietam ze miałem cały czas temp. podajże 85C z powodu błędnie dobranego czasu konwersji. Termometr był zasilany, nie parasite. Oczywiście mógłbym odfiltrować tą wartość... Widać że możliwości jest znacznie więcej niż sądziłem. :) Niestety nie znajdę czasu żeby się tym praktycznie zająć przed weekendem.

    Jeszcze jedno pytanie, trochę nie na temat. Czy drgania styków powinno się eliminować poprzez "_delay_ms(80);", czy istnieje lepszy sposób?
  • #18 9563424
    tmf
    VIP Zasłużony dla elektroda
    Przy PP raczej nie. Z drugiej strony zastanawiam się po co ludzie tak namiętnie stosują PP, trudno mi sobie wyobrazić rozsądną sytuację w której 3 drut byłby takim problemem, będę wdzięczny za przykłady :)

    Dodano po 2 [minuty]:

    tmazur napisał:
    @dondu W takim razie korzystam z tego co zaproponowałeś + flagi które opisał @asembler

    @tmf Z początków zabawy z termometrem pamietam ze miałem cały czas temp. podajże 85C z powodu błędnie dobranego czasu konwersji. Termometr był zasilany, nie parasite. Oczywiście mógłbym odfiltrować tą wartość... Widać że możliwości jest znacznie więcej niż sądziłem. :) Niestety nie znajdę czasu żeby się tym praktycznie zająć przed weekendem.

    Jeszcze jedno pytanie, trochę nie na temat. Czy drgania styków powinno się eliminować poprzez "_delay_ms(80);", czy istnieje lepszy sposób?


    Z tymi 85 stopniami to problem musiał być w czymś innym. W normalnym trybie zasilania odczyt można dokonać w każdej chwili, po prostu nie dojdzie do uaktualnienia rejestrów przed zakończeniem konwersji.
    Co do debouncingu - sposobów jest wiele. Jeśli delay ci przeszkadza, to wykorzystaj USART jeśli masz wolny. Jeśli już wykorzystujesz timer to przy okazji można go wykorzystać do debouncingu.
  • #19 9563472
    asembler
    Poziom 32  
    Przykładów mnoży elektroda: trudno uszkodzić czujnik podłaczając parasite a przy 3 przewodach lamenty co drugi post w tej sprawie
    Druga sprawa to trzy druty to już tłok przynajmniej dla mnie nawet RS puszczam po 2 drutach.
    Trzeci przykład przy dwóch drutach mamy dodatkowy switch w każdym punkcie pomiaru temp więc nie trudno sobie wyobrazić zastosowan tegoż
  • #21 9563758
    tmf
    VIP Zasłużony dla elektroda
    asembler napisał:
    Przykładów mnoży elektroda: trudno uszkodzić czujnik podłaczając parasite a przy 3 przewodach lamenty co drugi post w tej sprawie
    Druga sprawa to trzy druty to już tłok przynajmniej dla mnie nawet RS puszczam po 2 drutach.
    Trzeci przykład przy dwóch drutach mamy dodatkowy switch w każdym punkcie pomiaru temp więc nie trudno sobie wyobrazić zastosowan tegoż


    W jaki sposób puszczasz RS na dwóch drutach?
    Co do przykładu trzeciego - to prawda przy założeniu, że nie możemy puścić 4 drutów :)
  • REKLAMA
  • #22 9563791
    piotrva
    VIP Zasłużony dla elektroda
    asembler napisał:
    Przykładów mnoży elektroda: trudno uszkodzić czujnik podłaczając parasite a przy 3 przewodach lamenty co drugi post w tej sprawie
    Druga sprawa to trzy druty to już tłok przynajmniej dla mnie nawet RS puszczam po 2 drutach.
    Trzeci przykład przy dwóch drutach mamy dodatkowy switch w każdym punkcie pomiaru temp więc nie trudno sobie wyobrazić zastosowan tegoż

    1. dlatego ludzie uszkadzają, bo 75% z nic nie doczytuje napisu w datasheecie "BOTTOM VIEW" i myślą, że to widok z góry - sam chyba ze 3 razy pomagałem w tematach, w których czujnik uszkodzono właśnie z tego powodu
    2. co do RS232 to ja nie radze puszczać po 2 kablach. Bo a nuż trafi się inna masa w różnych układach i będziesz miał na pinach 2 układów dużą różnicę napięć => układy się mogą uszkodzić. Dodatkowe zwarcie masy spowoduje że w takiej sytuacji co najwyżej pójdą bezpieczniki w zasilaczu
    3. co do samych DS18x20 to myślę, że ludzie dlatego podłączają je na 3 pinach bo zwykle początkujący mają problemy ze zwróceniem uwagi na strong pull-up na czas konwersji i potem narzekają, że im krzaki wychodzą zamiast pomiarów
    Reasumując kwestię dallasów: i tak źle i tak niedobrze dla początkujących użytkowników, którzy chcą wszystko zrobić zbyt szybko...

    Co do debouncingu to skoro masz już timer w programie to najlepiej wykorzystać jego przerwania ovf do zliczania jednostek czasu i potem w programie sobie bez zatrzymywania sprawdzasz debouncing.
  • #23 9563903
    janbernat
    Poziom 38  
    Uparcie twierdzę że _delay() powinno być ukryte przed poczatkującymi.
    Procesor ma chociaż jeden timer.
    W przerwaniu od timera można wstawić jedną- albo mnóstwo flag.
    Inkrementować, dekrementować- jak kto lubi.
    W pętli głównej sprawdzać- i jak coś jest- to robić.
    To jest najprostsza implementacja pseudowielowątkowości.
    Przecież to nie są układy wieloprocesorowe- i tak nie obsłużą kilku wątków na raz.
    mirekk36 znalazł że to się nazywa Round Robin- najprostsza implementacja.
    A pewna dyscyplina przy programowaniu zostanie.
    No i zrozumienie że czas nie jest tak do końca metafizyczny- jak coś pracuje to czas robi się realny.
  • #24 9563994
    asembler
    Poziom 32  
    piotrva napisał:

    2. co do RS232 to ja nie radze puszczać po 2 kablach. Bo a nuż trafi się inna masa w różnych układach i będziesz miał na pinach 2 układów dużą różnicę napięć => układy się mogą uszkodzić. Dodatkowe zwarcie masy spowoduje że w takiej sytuacji co najwyżej pójdą bezpieczniki w zasilaczu

    Nie rozumiem? Ty sądzisz że te dwa druty to oba sygnałowe bez przewodu masy?
    Tego to bym nie wymyslił.
REKLAMA