Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

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

nihil_novi 12 Maj 2010 10:30 1587 5
  • #1 12 Maj 2010 10:30
    nihil_novi
    Poziom 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ą?

    0 5
  • #2 12 Maj 2010 11:06
    marcin362
    Poziom 8  

    Cytat:
    procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);

    Masz coś takiego jak Count. Spróbuj w pętli robić
    Cytat:
    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...

    0
  • #3 12 Maj 2010 11:08
    utak3r
    Poziom 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.

    0
  • #4 12 Maj 2010 11:36
    arnoldziq
    Moderator Programowanie

    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.

    0
  • #5 12 Maj 2010 12:05
    nihil_novi
    Poziom 2  

    marcin362 napisał:
    Cytat:
    procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);

    Masz coś takiego jak Count. Spróbuj w pętli robić
    Cytat:
    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 napisał:
    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 napisał:
    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 napisał:
    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.

    0
  • #6 13 Maj 2010 15:16
    Jerzy_W
    Poziom 13  

    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!

    0