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 i odbieranie więcej niż trzech znaków z UART'a.

Villen 17 Kwi 2011 17:54 3710 17
REKLAMA
  • #1 9411392
    Villen
    Poziom 21  
    Witam forumowiczów,

    Na wstępie proszę się nie denerwować: wiem że podobnych tematów było sporo, rozwiązanie podawane co najmniej kilka razy, ale ja mam tu złożenie jakby dwóch problemów.

    Pierwszym jest komunikacja z użyciem RS-232 i modułów radiowych HM-R/T868.
    Drugim odbiór więcej niż trzech znaków i zapisanie ich do zmiennej którą potem można by do czegoś użyć.

    Pierwszy problem polegał na odbiorze dużej ilości zakłóceń przez odbiornik. Da się to rozwiązać nieco prostacką metodą: zauważyłem że jeśli nadajnik cały czas nadaje, to zakłóceń nie ma żadnych. Więc z "nadajnika" wysyłam cały czas znak NULL z tablicy ascii, a w odbiorniku odbiór zaczynam dopiero w chwili, kiedy odebrany znak <> &H00.

    Tylko nie potrafię poradzić sobie z problemem bufora. Potrzebuję przesyłać string'i 6, mac 10cio znakowe. Tymczasem choćbym nie wiem jak próbował odbieram zawsze góra trzy.

    Czy ktoś mógłby szepnąć choćby słowo porady jak to zrobić?
  • REKLAMA
  • REKLAMA
  • #3 9411486
    Villen
    Poziom 21  
    Już piszę:

    Po stronie nadajnika pracuje taki "program" testowy:

    
    Dim tekst as string * 7
    
    tekst = "Tekscik"
    
    Do
    
    print chr(&H00);
    
    If pina.0 = 0 then : print tekst : end if
    
    Loop : End 
    


    Mam podłączone 2 odbiorniki: jeden do RS'a w komputerze, drugi do mikrokontrolera z podłączonym LCD. W terminalu na komputerze po wciśnięciu przycisku wyświetla się "nadany" tekst.

    Po stronie odbiornika:

    
    Do
    
    B = Inkey()
                                                  
       If B <> Chr(&H00) Then
          A = A + B
        End If
    Locate 1 , 1 : Lcd A : Waitms 500 : Cls
    
    Loop : end 
    


    I wyświetla tylko 3 pierwsze znaki nadanego stringa.

    Jak sobie z tym poradzić?
  • #4 9411510
    piotrva
    VIP Zasłużony dla elektroda
    a masz po stronie odbiornika skonfigurowany bufor?
    bo jak nie to to nie ma prawa działać
    jeszcze z tą zacną instrukcją Waitms...
    spróbuj:
    Config Serialin = Buffered, Size = 10

    i jakiego typu zmienne?
    zamieść CAŁE programy
  • REKLAMA
  • #6 9411559
    Villen
    Poziom 21  
    Programy są bardzo króciutkie, napisane tylko do testu, ale dobrze, podaję je.

    Po stronie "nadajnika":

    
    $regfile = "m32def.dat"
    $crystal = 4000000
    $baud = 1200                                                'niski BAUD do testów, ale wiecej w sumie nie potrzebuje
    
    
    Config Lcd = 16 * 2                                         'konfiguracja wyswietlacza
    Config Lcdpin = Pin , Rs = Portb.2 , E = Portb.3 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
    Cursor Off : Cls
    
    Config Porta.0 = Input : Porta.0 = 1
    
    Dim Tekst As String * 7
    
    Tekst = "Tekscik"
    
    
    Do
    Print Chr(&H00);
    
    
    If Pina.0 = 0 Then : Print Tekst : End If
    
    
    Loop : End
    


    
    Print Chr(&H00);

    Jest konieczny, żeby odbiornik nie odbierał całego śmiecia z eteru. Jeśli tylko nadawanie (czegokolwiek) zostanie przerwane, w terminalu widzimy tylko całą masę "krzaków".

    Po stronie odbiornika:

    
    $regfile = "m32def.dat"
    $crystal = 4000000
    $baud = 1200
    
    Config Lcd = 16 * 2                                         'konfiguracja wyswietlacza
    Config Lcdpin = Pin , Rs = Porta.5 , E = Porta.4 , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0
    Cursor Off : Cls
    
    
    
    Config Portd.7 = Output                                     'podanie stanu wysokiego na wejście ENABLE odbiornika
    Portd.7 = 1                                                 'konieczne do jego działania
    
    
    Dim A As String * 10
    Dim B As String * 10
    
    
    
    Do
    
       B = Inkey()
    
          If B <> Chr(0) Then
          A = A + B
          End If
    
          Lcd A : Waitms 500 : Cls : A = ""
    
    
    
    Loop : End


    Waitms jest tylko po to, by można było spokojnie odczytać tekst na wyświetlaczu, jestem świadomy tego, że waitów należy unikać i później na pewno go nie będzie ;)
  • #7 9411585
    piotrva
    VIP Zasłużony dla elektroda
    Spróbuj:
    
    Config Serialin = Buffered, Size = 10
    
  • #8 9411634
    xury
    Specjalista automatyka domowa
    Już chyba wiem.
    Nie możesz porównywać zmiennej tekstowej B do Chr (0), bo zmienna tekstowa kończy się takim znakiem.
    Czytaj przez Inkey do zmiennej typu Byte
    a następnie buduj string tak:
    A= A + Chr (B)
    Czyli zmień zmienną B na typ Byte
  • #9 9411696
    Villen
    Poziom 21  
    Niestety, nic nie pomogło. Znalazłem podobny problem w innym temacie i rozwiązanie do niego: KLIK.

    Jednak u mnie jest problem tego typu, że nadawanie i odbieranie informacji jest ciągłe - jak dostosować bufor, by nie reagował na odbieranie kodu NULL?
  • #11 9411749
    Villen
    Poziom 21  
    A czy mógłbyś podać przykład praktyczny?

    Jest to moje pierwsze starcie z UART'em i jakoś nie bardzo niestety go ogarniam.
  • #13 9411821
    Villen
    Poziom 21  
    Chyba wymyśliłem! :)

    Kod: text
    Zaloguj się, aby zobaczyć kod



    Sposób może mało elegancki, ale jak najbardziej działa i to całkiem sprawnie... Wystarczy do każdej wysyłanej zmiennej dodać znak końca.
  • #14 9411896
    xury
    Specjalista automatyka domowa
    No mało elegancki. Bo to teraz jest trochę inny Input. Skutkuje to brakiem wyjścia z wewnętrznej pętli jeśli nie został odebrany CR.
    Nie uwzględniłeś dodanych znaków LF, które są wysyłane z "automatu" po każdym Print. By temu zapobiec po każdym Print powinieneś dać średnik i chr (13) i średnik.
  • REKLAMA
  • #15 9411992
    Villen
    Poziom 21  
    Już zdążyłem zorientować się że jest to mało elegancki sposób, bo nawet po krótkich testach zaczęły wychodzić "kwiatki" związane właśnie z "ugrzęźnięciem" w wewnętrznej pętli. Ale mimo wszystko to już jakiś krok w przód. Jutro będę dalej eksperymentował i może uda się zrobić coś bardziej eleganckiego.
  • #17 9412108
    Villen
    Poziom 21  
    Nie, jeszcze nie testowałem bo zwinąłem na dzisiaj "warsztat".

    Czy Twój sposób wymaga jakiejś wcześniejszej konfiguracji bufora UART'a?
  • #18 9412746
    xury
    Specjalista automatyka domowa
    Nie zwykły bufor Serialin
    Flaga od entera może się Ci przydać by na przykład po jej ustawieniu przenieść odebrany ciąg gdzie indziej, zresetować flagę i ustawić A= "".
    Zamiast Case Else można by ciąg budować np po:
    Case 65 to 90
    Wtedy do ciągu dodawane były by tylko wielkie litery lub:
    Case 32 to 127 - czyli wszystkie znaki podstawowe bez sterujących.
    I jeszcze wiele innych.
    To tylko jeden ze sposobów używania odczytu USART.

    O wiele lepszym rozwiązaniem jest odczyt przy pomocy Bytematch.
    ale ten sposób na początek Ci wystarczy.
REKLAMA