[D7+TComPort] Problem z odbiorem paczki danych

0

Witam,

Używam komponentu TComPort do odbioru. Wykorzystuje go w projekcie, który odbiera tylko jeden znak i wszystko działa prawidłowo.

Nowy program działa na razie tak: Urządzenie wysyła co 1 sek. ciąg 3-znakowy (bajtowy). Jest to stały ciąg ABC (tak dla prób poprawności transmisji).
Właściwie to urządzenie będzie wysyłać stałego rozmiaru ciągi z większą częstotliwością i wartości poszczególnych znaków (bajtów) będą się zmieniać.

Dane z portu odbieram (i wyświetlam) w ten sposób:

Var Paczka : String;

procedure TForm1.PokazPaczke;
Begin
  M1.Lines.Add(Paczka);
  M1.Lines.Add('-------');
end;

procedure TForm1.CPortRxChar(Sender: TObject; Count: Integer);
begin
  CPort.ReadStr(Paczka, Count);
  PokazPaczke;
end;

A efekt odebranych ciągów znaków jest taki:

ABC
-------
A
-------
B
-------
C
-------
A
-------
B
-------
C
-------
A
-------
B
-------
C
-------
A
-------
BC
-------
A
-------
BC
-------
A
-------
BC
-------
A
-------
BC
-------
A
-------
BC
-------
A
-------
BC
-------
A
-------
BC
-------
A
-------
BC
-------
A
-------
BC
-------

... paczki są zmiennej wielkości. I nie wiem co jest przyczyną takiego wyniku, a chciałbym ten ciąg (testowy ABC) mieć zawsze w całości, żeby móc go odpowiednio obrobić. Możecie powiedzieć, co muszę poprawić/zmienić, żeby otrzymać to co powinno być, żeby paczki były o stałej długości??

0

Kod działa prawidłowo. Port RS232 nie ma pojęcia „paczki”, tylko jest strumieniem. Paczki to sam musisz sklecać. Ewentualnie zobacz, czy ten TComPort udostępnia jakąś funkcję czy właściwość zwracającą ilość danych przysłanych. Wtedy czekasz z odczytem aż się uzbiera tyle co potrzebujesz. Ale to przy założeniu, że taka funkcja jest.

0
Azarien napisał(a)

Ewentualnie zobacz, czy ten TComPort udostępnia jakąś funkcję czy właściwość zwracającą ilość danych przysłanych. Wtedy czekasz z odczytem aż się uzbiera tyle co potrzebujesz. Ale to przy założeniu, że taka funkcja jest.

no przecież podaje w Count ile jest znaków do odebrania
procedure TForm1.CPortRxChar(Sender: TObject; Count: Integer);

Co do problemu to tak jak pisał Azarien - paczki sam musisz składać. Najlepszym rozwiązaniem jest umieszczenie na końcu każdej paczki jednego, konkretnego znaku, który NIGDY nie będzie mógł wystąpić w samej paczce. Tak robi większość urządzeń pracujących po RS. Co więcej jeśli masz port COM na płycie to w windowsie możesz ustawić rozmiar bufora odczytu i wtedy NIGDY nie dostaniesz na raz więcej danych niż rozmiar tego bufora. Jeśli masz jakiś prostu konwerter USB->RS232 to tam zazwyczaj jest port 8B i tego też nie jesteś w stanie przeskoczyć. Jedyne sensowne rozwiązanie to znak końca paczki.

0
Misiekd napisał(a)

Co do problemu to tak jak pisał Azarien - paczki sam musisz składać. Najlepszym rozwiązaniem jest
umieszczenie na końcu każdej paczki jednego, konkretnego znaku, który NIGDY nie będzie mógł wystąpić
w samej paczce. Tak robi większość urządzeń pracujących po RS. (...) Jedyne sensowne rozwiązanie to
znak końca paczki.

Ok. Rozumiem. Macie rację, Panowie. To jest logiczne.
Dzięki za uświadomienie/przypomnienie istoty transmisji szeregowej.
Jednak co trzy głowy to nie jedna. :)

Tak sobie myślę, że w moim przypadku musiałbym zastosować:

  • stałą kombinację dwóch znaków końcapaczki, bo każdy znak przedstawia wartość w całym zakresie bajta (0-255) albo
  • znak(i)_prefiksu/nagłówka+dane+znak_końca (tu mi to trochę komplikuje, ale da się zrobić),
  • albo zliczać znaki danych i tak porcjować w paczki.

Tak czy siak, jeszcze raz dziękuję Wam za pomoc.
Pozdrawiam serdecznie!

1 użytkowników online, w tym zalogowanych: 0, gości: 1