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

[Delphi 7] Podczas odczytu danych z RS232 widać tylko 1 bajt

nihil_novi 12 May 2010 10:30 1767 5
  • #1
    nihil_novi
    Level 2  
    Witam,

    próbuję czytać dane z pewnego urządzenia podłączonego do portu COM. Posługuję się wielokrotnie już tu opisywanym komponentem TComPort. Również kod obsługujący poszczególne akcje wiele razy się przewinął. Jest tylko taki problem, że w większości przypadków programy w końcu zadziałały tak, jak chciał autor, a u mnie się zacina. Ale do rzeczy:

    Po otworzeniu portu na odpowiednich ustawieniach, wysyłam do niego komendę, która ma spowodować, że urządzenie odeśle swoje odczyty. Robię to standardowo:
    Code:

    procedure TForm1.ButtonSendClick(Sender: TObject);
    var
    Str: String;
    begin
    Str:= #208 + #208 + #208 +#0; //komenda dla urządzenia - 4 bajty
    ComPort.WriteStr(Str);
    end;




    a potem procedurą obsługi zdarzenia OnRxChar próbuję odczytać dane z urządzenia (też powinny przyjść 4 bajty):
    Code:

    procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);
    var
    Str: String;
    begin
    ComPort.ReadStr(Str, Count);
    Memo1.Text := Memo1.Text + Str;
    end;


    Proste i bezbolesne, ale... W Memo pojawia mi się tylko 1 bajt :( !!! Wiem na 100%, że powinny być 4, bo za pomocą innego programu odczytuje się właśnie tyle bajtów (jest to binarka, więc nie wiem, jak to dokładnie zostało obsłużone) i to samo powiedziała mi osoba przekazująca urządzenie (dokumentacji brak). Ten bajt jest taki sam, jak pierwszy z czterech bajtów odczytywany tym drugim programem, więc jest już prawie dobrze, tylko gdzieś giną następne.

    Przebiłem się przez:
    - instalację komponentu,
    - ustalenie parametrów połączenia (robione metodą prób i błędów, być może tu jest jeszcze coś nie tak, co powoduje, że odczyt zatrzymuje się po jednym znaku),
    - znalezienie kombinacji bajtów, która jest rozkazem dla urządzenia (brute force).

    Nie chciałbym polec na ostatnim chyba etapie, kiedy już prawie mam te odczyty...
    Czy ktoś spotkał się z podobnym problemem lub wie, co może być przyczyną?
  • #2
    marcin362
    Level 10  
    Quote:
    procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);

    Masz coś takiego jak Count. Spróbuj w pętli robić
    Quote:
    ComPort.ReadStr(Str, Count);
    Memo1.Text := Memo1.Text + Str;

    Powtarzaj pętlę Count razy.
    Używałem kiedyś ComPort ale jakoś inaczej to robiłem. Jak to nie zadziała to wieczorem sprawdzę w domu jak to było...
  • #3
    utak3r
    Level 25  
    Zawsze, gdy z poziomu Delphi musiałem obsłużyć RSa, korzystałem z tej biblioteki. Sprawdza się doskonale w wielowątkowych aplikacjach, również z użyciem protokołu RS485. Szczerze polecam.
  • #4
    arnoldziq
    Moderator of Programming
    Proszę, zgodnie z regulaminem pkt 11.1, o usunięcie słów PROBLEM lub/i POMOC z tytułu. Prośba dotyczy także wszelkich wariacji typu: kłopot, pomocy, problemy itd.
  • #5
    nihil_novi
    Level 2  
    marcin362 wrote:
    Quote:
    procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);

    Masz coś takiego jak Count. Spróbuj w pętli robić
    Quote:
    ComPort.ReadStr(Str, Count);
    Memo1.Text := Memo1.Text + Str;

    Powtarzaj pętlę Count razy.
    Używałem kiedyś ComPort ale jakoś inaczej to robiłem. Jak to nie zadziała to wieczorem sprawdzę w domu jak to było...
    Nie zadziała, bo po pierwszym (i jedynym) wywołaniu ComPort.ReadStr(Str, Count) zmienna Count ma wartość 1 (sprawdziłem zmieniając "Memo1.Text := Memo1.Text + Str" na "Memo1.Text := Memo1.Text + Str + IntToStr(Count)").

    Chyba, że (teraz mi to zaświtało) proces działa tak:
    - ja wysyłam "rozkaz",
    - urządzenie wysyła 4 bajty,
    - "odpala" się zdarzenie OnRxChar (czyli procedura ComPortRxChar) i wtedy Count ma wartość 4, ale ComPort.ReadStr czyta tylko jeden i przestawia wartość zmiennej Count na 1...

    Ale to chyba niemożliwe... Wieczorem to wezmę na debug... Wczoraj próbowałem:
    1.
    ComPort.ReadStr(Str, 4)
    2.
    ComPort.ReadStr(Str, Count);
    Memo1.Text := Memo1.Text + Str;
    ComPort.ReadStr(Str, Count);
    Memo1.Text := Memo1.Text + Str;
    ComPort.ReadStr(Str, Count);
    Memo1.Text := Memo1.Text + Str;
    ComPort.ReadStr(Str, Count);
    Memo1.Text := Memo1.Text + Str;
    3. pkt 2 w pętli for.

    Za każdym razem w Memo pojawiał mi się tylko pierwszy bajt...


    marcin362 wrote:
    Używałem kiedyś ComPort ale jakoś inaczej to robiłem.
    W dokumentacji komponentu TComPort znalazłem sugestię, żeby posłużyć się komponentem TComDataPacket - też spróbuję wieczorem.


    utak3r wrote:
    Zawsze, gdy z poziomu Delphi musiałem obsłużyć RSa, korzystałem z tej biblioteki. Sprawdza się doskonale w wielowątkowych aplikacjach, również z użyciem protokołu RS485. Szczerze polecam.
    Dzięki, spróbuję...


    arnoldziq wrote:
    Proszę, zgodnie z regulaminem pkt 11.1, o usunięcie słów PROBLEM lub/i POMOC z tytułu. Prośba dotyczy także wszelkich wariacji typu: kłopot, pomocy, problemy itd.
    Zrobione.
  • #6
    Jerzy_W
    Level 14  
    Witam!

    Spróbuj podejrzeć jakie bajty odsyła urządzenie w ten sposób:
    Code:

     procedure TForm_Main.ComPort1RxChar(Sender: TObject; Count: Integer);
    var
      Bajt:Byte;
      i:Byte;
    begin
      for i := 1 to Count do
      begin
        ComPort1.Read(Bajt,1);
        Memo1.Lines.Add(IntToStr(Bajt));
      end;
    end;


    A przy wysyłaniu Stringa dodaj linię:

    Code:

    Memo1.Lines.Clear;


    Pozdrawiam!