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

[Bascom] Bufor serialin i ignorowanie znaku &H0

Villen 07 Maj 2011 19:55 2653 12
REKLAMA
  • #1 9481904
    Villen
    Poziom 21  
    Witam,

    mam dosyć upierdliwy problem z transmisją UART z użyciem modułów radiowych HM-R/T868.

    Problem polega na tym, że jeśli nadajnik nic nie nadaje, to odbiornik odbiera dziwne "śmieci" z eteru. Problem znika w momencie, kiedy będący w zasięgu nadajnik nadaje cokolwiek. Więc w głównej pętli programu umieściłem komendę:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    Która nadaje w kółko pusty znak NULL i nadawanie to jest przerywane tylko w chwili, kiedy przesyłam właściwą, interesującą mnie zmienną string.

    Jednak takie rozwiązanie powoduje problem z konfiguracją i używaniem bufora serialin. Problem polega na tym, że odbierane puste znaki również zapełniają bufor i generują przerwanie, co powoduje nieprawidłowe odbieranie właściwych informacji.

    Czy da się skonfigurować bufor serialin tak, by ignorował puste znaki?

    Będę wdzięczny za każdą sugestię i podpowiedź!
  • REKLAMA
  • #2 9481966
    piotrva
    VIP Zasłużony dla elektroda
    Możesz spróbować zrobić coś z bytematch all (wtedy generuje przerwanie po odebraniu znaku) i zrobić sobie własny bufor, do którego będziesz wpisywał tylko znaki różne od zera
  • #3 9481990
    Fredy
    Poziom 27  
    Zrób transmisję z sumą kontrolną.
  • REKLAMA
  • #4 9482016
    Villen
    Poziom 21  
    piotrva napisał:
    Możesz spróbować zrobić coś z bytematch all (wtedy generuje przerwanie po odebraniu znaku) i zrobić sobie własny bufor, do którego będziesz wpisywał tylko znaki różne od zera

    Czy mógłbyś odrobinę choć przybliżyć temat?

    Wiem jak skonfigurować bufor i bytematch, wiem że należy wtedy utworzyć podprogram
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Domyślam się też, że w tym podprogramie znajdować się powinna instrukcja warunkowa, która jeśli odebrany znak będzie <> 0 to dopisze go zmiennej "bufora" i tak na przykład aż do wystąpienia znaku CR.
    Tylko jak w tym podprogramie odczytywać nadchodzący znak?
  • REKLAMA
  • #5 9482086
    piotrva
    VIP Zasłużony dla elektroda
    za pomocą Inkey()
    a wtedy bufor automatyczny konfigurujesz tak:
    
    Config Serialin = Buffered , Size = 10 , Bytematch = All  
    
  • #6 9482272
    Fredy
    Poziom 27  
    Jest też taka fajna procedurka Ischarwaiting która wskazuje na to że w buforze jest znak odebrany. Jeśli Ischarwaiting =1 to tylko wtedy czytasz znak.
  • #7 9482555
    Villen
    Poziom 21  
    Fredy napisał:
    Jest też taka fajna procedurka Ischarwaiting która wskazuje na to że w buforze jest znak odebrany. Jeśli Ischarwaiting =1 to tylko wtedy czytasz znak.


    Tak, wiem, tylko tak jak pisałem problem stwarzają puste znaki które są nadawane cały czas.

    Na prawdę nikt nie ma żadnego pomysłu jak ten problem rozwiązać?
    Bo mi ich zaczyna brakować i nie mogę sobie z tym pieroństwem poradzić...
  • REKLAMA
  • #8 9484235
    Fredy
    Poziom 27  
    Villen napisał:
    Fredy napisał:
    Jest też taka fajna procedurka Ischarwaiting która wskazuje na to że w buforze jest znak odebrany. Jeśli Ischarwaiting =1 to tylko wtedy czytasz znak.


    Tak, wiem, tylko tak jak pisałem problem stwarzają puste znaki które są nadawane cały czas.

    Na prawdę nikt nie ma żadnego pomysłu jak ten problem rozwiązać?
    Bo mi ich zaczyna brakować i nie mogę sobie z tym pieroństwem poradzić...


    Rozumiem że są to znaki null?
    Czy te znaki są rzeczywiście nadawane? Może twój odbiornik je łyka , zauaważ że instrukcja Bascomowa Inkey nawet jak nie ma znaku w buforze to zwraca właśnie wartość zerową. Dlatego odbiór należy wspomóc Ischarwaiting aby odebrać tylko prawdziwe znaki.
    Może rozwiązaniem byłoby dodanie ifa który będzie blokował te puste znaki. Chyba nie potrzebujesz znaku zerowego?
  • #9 9484300
    Villen
    Poziom 21  
    Tak, są to znaki NULL (o kodzie ascii 0).

    Są na pewno nadawane, ponieważ mam jednocześnie uruchomione dwa odbiorniki - jeden podłączony do mikrokontrolera, drugi przez przejściówkę USB-UART do komputera. Wszystkie transmisje obserwuję jednocześnie w terminalu i w urządzeniu odbiorczym.

    Kombinuję i kombinuję...

    Doszedłem do takiego rozwiązania:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    I na wyświetlaczu obserwuję dokładnie co się dzieje: dopóki "nadajnik" nic nie nadaje (tzn nadaje tylko puste znaki, nazwijmy je "przeciwzakłóceniowymi") to flaga = 0. W momencie kiedy zostanie nadana jakakolwiek informacja, flaga ustawia się na 1, po zakończeniu nadawania i powrocie do nadawania pustych znaków flaga ponownie jest równa 0. Więc ignorowanie pustych znaków zdaje się że działa.

    Nie mogę poradzić sobie jednak z odbiorem tej właściwej, interesującej mnie informacji. Próbowałem tak:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Ale skutkuje to tylko zanikiem czegokolwiek na wyświetlaczu.

    Zupełnie nie mam już pomysłu jak zrealizować sprawny odczyt...

    [EDIT]
    Wydaje mi się, że problem udało się rozwiązać - metoda prosta do bólu. Może odrobinę prymitywna, jednak jak najbardziej poprawnie działająca. Testuję to rozwiązanie od jakiejś godzinki i jeszcze nic się nie zawiesiło czy wykrzaczyło.
    Podpowiem tylko jedną rzecz: jeśli wstawiamy to do już wcześniej napisanego programu, który używa przerwań (np zewnętrznych czy od TIMER'ów) to trzeba zwrócić uwagę na to, by jedno z drugim się nie gryzło. Z uwagi na to, że do bufora ciągle "nadlatują" puste znaki, a bytematch ustawione jest na "all" przerwania generowane przez bufor są bardzo częste co może powodować problemy - ale jeśli obsługi przerwań są napisane dobrze (tzn ich obsługa trwa możliwie krótko) to wszystko działa jak należy.

    Kod: text
    Zaloguj się, aby zobaczyć kod


    U mnie działa bez problemu, nawet po wstawieniu w program który używa dosyć intensywnie innych przerwań (szczególnie zewnętrznych).

    Co powiecie na takie rozwiązanie?
  • #10 9484818
    xury
    Specjalista automatyka domowa
    Dlaczego odbierasz w pętli do loop ?
    Skoro używasz bytematch to czemu tego nie wykorzystujesz ?
    Gdzieś niedawno pisałem o tym. Możesz poszukać, bo tam zamieściłem działający kod. Tymczasem podpowiem Ci algorytm odbioru:
    W podprogramie Serial0charmatch ustawiaj tylko flagę.
    W pętli głównej sprawdzasz czy flaga jest ustawiona i jeśli jest to odczytujesz znak i jeśli jest różny od 0, a także innych znaków, których nie nadajesz to dodajesz go do stringa. Jeśli odbierzesz znak CR kończysz odbiór i przepisujesz rezultat do innej zmiennej. Najlepiej jest to robić za pomocą instrukcji Select Case.
    Np tak:
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #11 9484835
    Villen
    Poziom 21  
    xury - dziękuję za Twoje podpowiedzi, pomagałeś mi też w innym moim temacie. Jednak nie wiedzieć czemu kody proponowane przez Ciebie nie działały kiedy używałem tych nieszczęsnych modułów radiowych. Po spięciu mikroklocków kablem - owszem, wszystko cacy. Jednak moduły RF i ta upierdliwa konieczność nadawania pustych znaków niezbyt chciały współpracować z Twoją propozycją ;)

    I w ostatecznym rozwiązaniu (w edicie mojego ostatniego posta) nie ma już żadnej niepotrzebnej pętli do ... loop until, która tylko skutecznie blokowała program w martwym punkcie :P
  • #13 9484902
    Villen
    Poziom 21  
    W taki sposób, że zaraz po zakończeniu nadawania właściwej zmiennej, z powrotem startuje nadawanie znaków NULL. Tak więc moje rozwiązanie "wyłuskuje" wszystko z pomiędzy tych pustych znaków ;)

    [EDIT]

    A jednak mój sposób zawiódł. Nie tyle że nie działa, co po prostu przerwania od bufora są zbyt częste i mam problemy z napisaniem dalszej części programu tak, żeby działała.

    Próbuję więc zrobić coś na tę modłę:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    A w nadajniku ramkę danych nadaję tak:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    I choć puste znaki ciągle muszą być nadawane, to nie ma bezsensownie i ciągle generowanych przerwań od bufora.
    Za to ponownie mam problem z tym nieszczęsnym odczytem: z tego co zauważyłem, zaraz po włączeniu/resecie odbiornika pierwszy "odbiór" działa bez zarzutu. Ale każdy następny to już całkowicie losowa sprawa ;/...

    Co może powodować takie zachowanie?
    Zaczyna mi brakować sił już :(
REKLAMA