Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Delphi- Problem z odczytem danych odbieranych przez RS232

naitsyrk 21 Nov 2008 09:22 1977 11
  • #1
    naitsyrk
    Level 14  
    Mam pewien problem z odczytem danych w delphi nadawanych przez RS232. Do nadawania danych wykorzystałem mikrokontroler który nadaje mi siedmio-znakowy string z częstotliwością co 500ms.
    Do odczytu w delphi wykorzystałem funkcje WIN API od obsługi Rs232, sam odczyt realizowany jest na timerze ustawionym również na 500ms problem polega na tym, że np wartość wysyłana to 55443322 i przy odczycie w delphi czasami występuje pewien błąd a mianowicie czasami ten string odbierany jest poprawnie jednak czasami jest problem i Delphi odczyt zamiast tej napisanej wcześniej wartości np. 5544
    Gdzie może tkwić błąd?
  • #2
    User removed account
    User removed account  
  • #3
    naitsyrk
    Level 14  
    tak wiem uzywałem juz tego komponentu jednak aplikację tą musze wykonac na zajęcia i musze to zrobić uzywając WIN API więc czekam na jakies wasze podpowiedzi pomózcie....
  • #4
    User removed account
    User removed account  
  • #5
    dkow
    Level 14  
    Problem z odczytem danych w delphi może być spowodowany tym że, w momencie uruchomienia (co 500ms) funkcji pobranie danych z bufora COMa, nie są jeszcze skompletowane wszystkie dane. Dobrze by było poczekać jeszcze dłużej niż 500ms i wtedy odzytać dane z bufora (Timery odmieżające 500ms nie są dokładne). Tylko że gdy tak zrobisz powstanie kolejny problem, co będzie gdy do bufora dojdą kolejne dane z następnego pakietu. Problem warto rozwiązać bo wtedy czyni to naszą aplikację odporną na zakłucenia (np wyłączenie się procesora w trakcie transmisji albo pojawieniem się (nie wiadomo z kąd) jeszcze 1 bajtu albo brak 1 bajtu w transmisji, co czasem też się zdaża).
  • #6
    elektryk
    Level 42  
    naitsyrk wrote:
    sam odczyt realizowany jest na timerze ustawionym również na 500ms
    Tu masz błąd rozumowania, timery w urządzeniu i komputerze nie są w żaden sposób zsynchronizowane. Jedyne rozwiązanie dla Ciebie to oczekiwanie w pętli na przyjście znaku (znaków) i zbieranie ich do bufora. Oczywiście trzeba to wykonać w postaci dodatkowe wątku który nie będzie przeszkadzać w normalnym działaniu programu (szczególnie w działaniu GUI).

    oloam wrote:
    dobra rada, skorzystaj z komponentu comport - odwala cala robaote za ciebie
    Dobra rada jest taka że nie używaj kodu którego nie rozumiesz ;)
  • #7
    naitsyrk
    Level 14  
    Elektryk a jak sadzisz czy nie uzywając kodu którego do końca nie rozumiem jestem się w stanie czegoś nauczyć raczej nie.......dlatego liczyłem na jakąś konkretną pomoc a nie gadki w sensie, że jeżeli czegos nie rozumiem to nie powienienem tego uzywac bo to chyba nie jest fachowe podejście do tematu...

    A z ty co napisałes to wiem o tym, że timery te nie są ze sobą zsynchronizowane, jednak myślałem że używajać tej metody przekłamań będzie znacznie mniej, wywnioskowałem to czytajać książkę "RS232 Praktyczne programowanie". Jednak zauważyłem, że moje rozumowanie nie spełnia mojego założenia i domyślam się ze muszę zastosować wielowątkowość tylko, że nie zajmowałem się tym nigdy i nie wiem jak się za to zabrać. Koncecja, która chciałem teraz zastosować to dodanie w mikrokontrolerze znaku początku nadawania i znaczyć koniec ramki, nastepnie sprawdzac czy pojawiał się znak początku działac do omentu aż pojawi się znak końca ramk. Czy założenie to jest słuszne???
  • #8
    elektryk
    Level 42  
    naitsyrk wrote:
    Jednak zauważyłem, że moje rozumowanie nie spełnia mojego założenia i domyślam się ze muszę zastosować wielowątkowość tylko, że nie zajmowałem się tym nigdy i nie wiem jak się za to zabrać.
    W helpie do delphi jest prosty przykład jak ugryźć TThread, doklej do tego otwarcie portu i blokujący odczyt z portu i masz gotowe rozwiązanie.
    naitsyrk wrote:
    Koncecja, która chciałem teraz zastosować to dodanie w mikrokontrolerze znaku początku nadawania i znaczyć koniec ramki, nastepnie sprawdzac czy pojawiał się znak początku działac do omentu aż pojawi się znak końca ramk. Czy założenie to jest słuszne???
    Koncepcja jest prawidłowa, ale jeśli zakładasz że uP przesyła znaki co 500ms to możesz wykorzystać to że jeśli nie będzie nowych znaków przez powiedzmy 400ms to możesz skasować bufor i uznać że najbliższy znak to będzie pierwszy znak pakietu.

    Nie wiem do końca jaki charakter mają dane które odbierasz i co z nimi robisz, napisz coś więcej.
  • #9
    dkow
    Level 14  
    W mikrokontroleże warto dopisać wysyłanie sumy kontrolnej CRC (choć by XOR). To znacznie poprawia poprawność odczytanych danych. Popieram "elektryk"a co do kasowania bufora jeśli nie skompletują się dane w ciągu 400ms. Zastosowałem tego typu sposób w swoim porojekcie i to dobrze działa (wraz z CRC)
  • #11
    naitsyrk
    Level 14  
    mógłby mi ktos cos podpowiedziec???? proszę
  • Helpful post
    #12
    shadoweyes
    Level 20  
    Jeśli wysyłasz dane z układu uP co 500ms to program, który odczytuje dane z bufora, możne sprawdzać czy nie pojawiły się w nim nowe dane i jeśli zostały zapisane nowe dane to wtedy je dopiero odczytać. Na pewno jest coś takiego opisane w książce RS232-praktyczne programowanie. Jesli nie to poszukaj na http://4programmers.net/search.php?q=obs%C5%82uga+portu+szeregowego&c=1 .