Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA w 2025? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 12 kwi 2025, o 21:21


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 20 ] 
    Autor Wiadomość
    PostNapisane: 9 mar 2021, o 20:59 
    Offline
    Użytkownik

    Dołączył(a): 25 gru 2012
    Posty: 128
    Pomógł: 0

    Witam,
    Mam taki oto kod - dlaczego w tym przypadku wyświetlacz LED (8xLED) miga ?
    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    a w takim przypadku nie miga:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Dlaczgo jak wyswietl(); i odczytajTemperatury(); są wywoływane w osobnych ifach (pierszy kod) to LED miga ?
    A gdy wyswietl(); i odczytajTemperatury(); są wywoływane w jednym ife (drugi kod) to LED nie miga ?
    Dzięki za odpowiedzi.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 10 mar 2021, o 10:37 
    Offline
    Użytkownik

    Dołączył(a): 01 mar 2021
    Posty: 28
    Pomógł: 2

    Nie wiem, ale coś może być w tych funkcjach. ?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 10 mar 2021, o 11:49 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 29 sty 2015
    Posty: 190
    Pomógł: 11

    Zbyt dużo czasu mikrokontroler spędza w procedurze odczytajTemperatury(). Można zrobić profilingm, aby to sprawdzić. Być może procedura ta blokuje multiplexowanie (bo chyba, w taki sposób obsługiwany jest wyświetlacz). Proszę powiedzieć coś więcej o odczytajTemperatury();



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 10 mar 2021, o 15:48 
    Offline
    Użytkownik

    Dołączył(a): 18 kwi 2013
    Posty: 181
    Lokalizacja: Kraków
    Pomógł: 30

    A jakie wartości mają nadane zmienne test i test1?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 10 mar 2021, o 23:35 
    Offline
    Użytkownik

    Dołączył(a): 25 gru 2012
    Posty: 128
    Pomógł: 0

    "A jakie wartości mają nadane zmienne test i test1?" Nawet jak przypiszę wartości test=0 i test1=0 to nic nie zmienia. Nadal jak funkcje są w osobnych ifach to jest migotanie wyświetlaczy.

    Oto wywoływane funkcje:
    void odczytajTemperatury(void):
    W jednym przerwaniu ~2.5ms wykonywany jest jeden case (zwykle case skłąda się z: wysłanie polecenia -> zmiana czujnika -> wysłanie polecenia).
    Kiedyś mierzyłem i każdy case mieścił się w 2.5ms. Chyba będę musiał jeszcze raz to pomierzyć, jeżeli nikomu nic nie przyjdzie do głowy.

    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Oraz funkcja wyswielt(): Wysiwetlacz to jest taki moduł do którego wysyłamy 2 bajty. PIerwszy bajt aktywuje dany wyświetlacz a drugi bajt to dane na ten wyświetlacz.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 11 mar 2021, o 18:39 
    Offline
    Użytkownik

    Dołączył(a): 11 sty 2015
    Posty: 166
    Pomógł: 24

    A nie zrobiłeś przypadkiem ISR wewnątrz pętli while() ?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 11 mar 2021, o 19:18 
    Offline
    Użytkownik

    Dołączył(a): 25 gru 2012
    Posty: 128
    Pomógł: 0

    auers napisał(a):
    A nie zrobiłeś przypadkiem ISR wewnątrz pętli while() ?

    Nie. Nie zrobiłem ISR wewnątrz pętli. W moim pierwszym poscie jest błąd. Ostatnia klamra powinna być nad ISR. Sorry ale chciałem umieścić, to co najistotniejsze i źle usunąłem klamry.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 11 mar 2021, o 19:58 
    Offline
    Użytkownik

    Dołączył(a): 11 sty 2015
    Posty: 166
    Pomógł: 24

    Szukasz błędu nie tam gdzie trzeba.
    To na pewno nie if'y są przyczyną twoich problemów.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 mar 2021, o 23:23 
    Offline
    Użytkownik

    Dołączył(a): 25 gru 2012
    Posty: 128
    Pomógł: 0

    auers napisał(a):
    Szukasz błędu nie tam gdzie trzeba.
    To na pewno nie if'y są przyczyną twoich problemów.

    Właśnie chyba nie do końca. Taki oto kod:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Daje taki output. Nie wiem dlaczego, co jakiś czas następuje zmiana kolejności wykonywania ifów (pomarańczowa ramka).
    Obrazek
    Ta zmiana kolejności wykonywania ifów w rzeczywistości powoduje migotanie LED. Dlaczego ta zamiana występuje ? Zawsze wykonywane są oba ify, tylko czasami następuje zmiana kolejności ich wykonywania.
    Takie zachowanie też tłumaczy dlaczego migotania nie ma gdy funkcje odczytTemperatury(); i wyswietl(); umieszczone są w jednym ifie.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 mar 2021, o 07:19 
    Offline
    Użytkownik

    Dołączył(a): 25 lip 2013
    Posty: 2595
    Pomógł: 128

    Jakie masz ustawione próbkowanie analizatora?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 mar 2021, o 10:33 
    Offline
    Użytkownik

    Dołączył(a): 25 gru 2012
    Posty: 128
    Pomógł: 0

    micky napisał(a):
    Jakie masz ustawione próbkowanie analizatora?


    Sample rate: 12MS/s

    Ale samo próbkowanie to jedno. Drugą kwestią jest to, że widać ten efekt poprzez migotanie LED.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 mar 2021, o 10:53 
    Offline
    Użytkownik

    Dołączył(a): 11 sty 2015
    Posty: 166
    Pomógł: 24

    qutrit napisał(a):
    Ta zmiana kolejności wykonywania ifów w rzeczywistości powoduje migotanie LED. Dlaczego ta zamiana występuje ? Zawsze wykonywane są oba ify, tylko czasami następuje zmiana kolejności ich wykonywania.

    Sama zmiana kolejności sterowań przekaźnikami, przy takim kodzie jest możliwa.
    Jeżeli przerwanie wykona się po pierwszym if'ie najpierw wywoła się obsługa przekaźnika2, a w następnym obiegu pętli dopiero obsługa przekażnika1.

    ------------------------ [ Dodano po: 36 minutach ]

    Powinieneś trochę zmienić podejście do obsługi zadań związanych z wyświetlaczem i odczytem danych.
    Jeżeli masz wyświetlacz LCD, który obsługujesz przez multipleksowanie, to priorytetem jest obsługa tego wyświetlacza a nie odpytywanie temperatury.
    W zależności od czujnika i czemu to ma służyć, temperaturę możesz odpytać np. raz na sekundę (przy DS18B20 i tak nie wiele szybciej możesz to zrobić). Szkoda zakłócać wyświetlacz obsługą DS'a.
    Same if'y zostaw tak jak masz i będzie dobrze.
    Ustaw tylko wartość test1 nie na 1 a np. na 400 i daj znać jaki jest efekt.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 mar 2021, o 12:31 
    Offline
    Użytkownik

    Dołączył(a): 25 gru 2012
    Posty: 128
    Pomógł: 0

    Spróbuję to rozwiąć.
    Podstawa czasu 2.5ms jest graniczną dla wyświetlacza (8 sztuk 7segmentów). Każdy case x: z odczytTemeratury(); (kod powyżej) zajmuje ~0.5ms - więc spokojnie się mieści w podstawie czasu 2.5ms

    Powinno być tak:
    pierwszyIF -> wyswietl(); + drugiIF->odczytTemeratury(); + pozostały czas do następnego przerwania. I tak powinno być cały czas.

    Ale jeżeli:
    pierwszyIF->wyswietl(); + drugiIF->odczytTemeratury(); + pozostały czas do następnego przerwania
    I teraz jeśli z jakiś powodów znowu:
    drugiIF->odczytTemeratury(); [to 'zabiera on' 0.5ms] + pierwszyIF->wyswietl(); + pozostały czas do następnego przerwania

    Dwa 'drugieIFy' powyżej trwają łącznie 3ms i to już jest widoczne jako migotanie.
    Albo inaczej pisząc na wykonanie 'pierwszychIFów' powyżej trzeba czekać powyżej 3ms, co jest już widoczne jako migotanie.
    Powyższe zachowanie jest wynikiem zmiany kolejności wykonywania IFów. Ale jak pisałem powyżej, one nie są 'gubione' tylko wykonywane są tak jakby w losowy sposób ale zawsze oba.

    Nie wiem czy bardziej wyjaśniłem czy zamotałem ale starałem się jak mogłem.

    ------------------------ [ Dodano po: 14 minutach ]

    auers napisał(a):
    qutrit napisał(a):
    Ta zmiana kolejności wykonywania ifów w rzeczywistości powoduje migotanie LED. Dlaczego ta zamiana występuje ? Zawsze wykonywane są oba ify, tylko czasami następuje zmiana kolejności ich wykonywania.

    Sama zmiana kolejności sterowań przekaźnikami, przy takim kodzie jest możliwa.
    Jeżeli przerwanie wykona się po pierwszym if'ie najpierw wywoła się obsługa przekaźnika2, a w następnym obiegu pętli dopiero obsługa przekażnika1.

    ------------------------ [ Dodano po: 36 minutach ]

    Powinieneś trochę zmienić podejście do obsługi zadań związanych z wyświetlaczem i odczytem danych.
    Jeżeli masz wyświetlacz LCD, który obsługujesz przez multipleksowanie, to priorytetem jest obsługa tego wyświetlacza a nie odpytywanie temperatury.
    W zależności od czujnika i czemu to ma służyć, temperaturę możesz odpytać np. raz na sekundę (przy DS18B20 i tak nie wiele szybciej możesz to zrobić). Szkoda zakłócać wyświetlacz obsługą DS'a.
    Same if'y zostaw tak jak masz i będzie dobrze.
    Ustaw tylko wartość test1 nie na 1 a np. na 400 i daj znać jaki jest efekt.


    wlacz/wylaczPrzekaznikx() - służuły mi teraz to podłaczenia analizatora. Same przekaźniki na ten czas były oczywiście odłączone. Tylko nazwy funkcji pozostały.
    Generalnie muszę odczyt temepratury podzielić na fragmenty, bo na raz się nie da. Tzn. wykonując wszystkie komendy raz/sekunde będę miał migotanie co sekunde (może i rzadziej niż teraz ale za to bardziej widzoczne).
    "Ustaw tylko wartość test1 nie na 1 a np. na 400 i daj znać jaki jest efekt." Coś podobnego realizuję w 'case KONWERSJA_CZAS' w funkcji odczytTemeratury() (kod powyżej) ale też zamieszczam poniżej:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    To znaczy zanim przejdzie mi do następnego case ( w tym przypadku powrót do case RESET:) to ten case KONWERSJA_CZAS wykona się 400 razy. Co w sumie i tak sprowadza się do odczytu temepratury co ~1sekunde.
    Jak zauważyłem to zmiana kolejności wykonywania IFów następuje głównie w momencie wysyłania/odbierania danych z DSa. Przyczym jak pisałem powyżej IFy nie są gubione.
    Tak jak pisałem powyżej. Jeżeli to migotanie w jakiś sposób zależałoby od funkcji wyswietl(); i odczytTemeratury(); to efekt byłby widoczy również w sytuacji gdy obie funkcjie umieszcze są w jednym IFie. A w tym przypadku efekt migotania nie występuje. Pojawia sie tylko po umieszceniu tych funkcji w osobnych IFach.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 mar 2021, o 12:57 
    Offline
    Użytkownik

    Dołączył(a): 11 sty 2015
    Posty: 166
    Pomógł: 24

    Cytuj:
    Powyższe zachowanie jest wynikiem zmiany kolejności wykonywania IFów. Ale jak pisałem powyżej, one nie są 'gubione' tylko wykonywane są tak jakby w losowy sposób ale zawsze oba.

    Już Ci napisałem z czego to wynika.

    Aby się tego pozbyć możesz zrobić tak:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Oczywiście musisz zmienić procedurę odczytu temperatury.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 mar 2021, o 20:07 
    Offline
    Użytkownik

    Dołączył(a): 25 gru 2012
    Posty: 128
    Pomógł: 0

    auers napisał(a):
    Cytuj:
    Powyższe zachowanie jest wynikiem zmiany kolejności wykonywania IFów. Ale jak pisałem powyżej, one nie są 'gubione' tylko wykonywane są tak jakby w losowy sposób ale zawsze oba.

    Już Ci napisałem z czego to wynika.

    Aby się tego pozbyć możesz zrobić tak:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Oczywiście musisz zmienić procedurę odczytu temperatury.


    No właśnie nie zabardzo widzę z czego to wynika :roll: To co napisałeś jest obejściem problemu. Podobne obejście przedstawiłem powyżej tj:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    To też działa bardzo dobrze (temperatury się odczytują wyświetlacz nie miga) i nie muszę nic zmieniać. Tak miałem zanim napisałem ten post.

    Chciałbym aby ktoś mi wyjaśnił to, to co napisałem w poście -> "Napisane: wczoraj, o 23:23". W skrócie: dlaczego dwa IFy które nic nie robią (oprócz 'delay' aby było widać w analizatorze) wykonują się w losowy sposób ?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 mar 2021, o 20:13 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 26 sty 2016
    Posty: 1168
    Lokalizacja: Kraków
    Pomógł: 93

    Nie wykonują się w losowy sposób! "Zmiana" jest wtedy, kiedy "wyzeruje" Ci się zmienna test1 pomiędzy sprawdzeniem warunków, czyli if(!test) -> przerwanie, w którym test=0 i test1=0 -> if(!test1)


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 mar 2021, o 20:26 
    Offline
    Użytkownik

    Dołączył(a): 11 sty 2015
    Posty: 166
    Pomógł: 24

    Spróbuję jeszcze raz Ci to wyjaśnić.
    Przerwanie timera może wystąpić w dowolnym momencie pętli głównej.
    Jeżeli trafisz, że wywoła się przed 1 if'em lub za 2-gim to wszystko jest zgodnie z twoim założeniem, najpierw wywoła się if nr 1 potem nr 2.
    Natomiast jeżeli przerwanie trafi się pomiędzy if'ami. Pierwszy if się już nie wykona. W międzyczasie zmieniają się wartości zmiennych timer. Drugi If' już jest spełniony i wywołuje funkcje z drugiego warunku, w twoich przypadkach obsługa odczytu temperatury. Następuje kolejny obieg pętli i dopiero wtedy wykonuje się pierwszy z if'ów z obsługą wyświetlacza.
    Stąd oba if'y zawsze się wykonują. Kolejność uzależniona od miejsca w którym wywoła się przerwanie.
    Dla zobrazowania wstawiam info o miejscu przerwania w kodzie:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Niestety w twoim przypadku czas wykona procedury odczytu temperatury zakłóca wówczas obsługę LCD.


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 15 mar 2021, o 16:36 
    Offline
    Użytkownik

    Dołączył(a): 01 mar 2021
    Posty: 28
    Pomógł: 2

    A gdybyś funkcję wyświetl () umieścił w procedurze obsługi przerwania? Wtedy zawsze wykona się w odpowiednim czasie ?

    ------------------------ [ Dodano po: 6 minutach ]

    W zasadzie to mógłbyś obydwie funkcje umieścić w przerywaniu


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 15 mar 2021, o 18:17 
    Offline
    Użytkownik

    Dołączył(a): 11 sty 2015
    Posty: 166
    Pomógł: 24

    adamma25 napisał(a):
    W zasadzie to mógłbyś obydwie funkcje umieścić w przerywaniu

    Nie jest to dobre rozwiązanie. Czas wykonywania przerwania powinien być jak najkrótszy.
    W przypadku AVR'ów, gdzie nie można ustawić priorytetów przerwań, kod umieszczony w przerwaniu blokuje inne przerwania.
    Przy bardziej wymagających projektach takie podejście może być źródłem problemów.
    W przypadku tego projektu, obsługę LCD w przerwaniu ze względu na wysoki priorytet da się jeszcze obronić, natomiast wrzucanie do przerwania jeszcze obsługi odczytu temperatury nie jest już najlepszym pomysłem. (Co nie znaczy, że to nie będzie działać).
    Rozwiązanie autora z jednym if'em jest lepszym rozwiązaniem. Eliminuje problem migania LCD, a nie blokuje innych przerwań o ile takich używa.


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 15 mar 2021, o 21:58 
    Offline
    Użytkownik

    Dołączył(a): 25 gru 2012
    Posty: 128
    Pomógł: 0

    Tak. Panowie właśnie uświadomiliście mi, że przerwania to 'rzecz' sprzętowa i mogą wystąpić w dowolnym momencie pętli while(1). Nie wiem co mi się ubzdurało, że zakładałem, że przerwanie zawsze powinno być na początki while(1). A co za tym idzie IFy zawsze powinny być wykonywane w takiej kolejności jakiej są napisane.

    Więc wyglądało to tak, że np. dwa razy pod rząd mógł wykonać się odczyt temperatury (co zajmowało ~3ms) i było to już widoczne jako migotanie. A że zdarza się dość często to i migotanie jest widoczne. Za jakiś czas mogły wykonać się dwa wyświetlnia pod rząd (co akurat nie miałoby konsekwencji). Czasami mogły wykonywać się pokolei itd... Generalnie wszystkie możliwie kombinacje z których najgorsza ze względu na wyświetlanie jest kombinacja w której następuje odczyt temperatury 2x pod rząd.

    W moim przypadku używam tylko tego jednego przerwania, więc rzeczywiście mógłbym wstawić 'wyświetlanie' do przerwania, ale dla czytelności pozostawię je w while(1) w IFie (czyli tak jak miałem przed napisaniem tego posta).
    Myślę, że na tą chwilę wszystko jest jasne.
    Dzięki.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    Wyświetl posty nie starsze niż:  Sortuj wg  
    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 20 ] 

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 6 gości


    Nie możesz rozpoczynać nowych wątków
    Nie możesz odpowiadać w wątkach
    Nie możesz edytować swoich postów
    Nie możesz usuwać swoich postów
    Nie możesz dodawać załączników

    Szukaj:
    Skocz do:  
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO