Funkcja Copy dla stringa pobranego z portu szeregowego

0

Odbieram dane z wagi poprzez komponent ComPort w następujący sposób:

procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);
var
  Str,waga: String;
begin
ComPort.ReadStr(Str, Count);
waga:=Copy(Str,10,5);
Memo.Text:=Memo.Text+waga;
end;

Waga wysyła ramkę danych w postaci 'SI 0.00 kg', z której potrzebuję wyciąć samą wagę. Napisana powyżej funkcja Copy działając na danych wysyłanych z portu z prędkością 9600 zwraca w Memo ten sam string).

Uruchomienie funkcji Copy w następujący sposób zwraca prawidłowy wynik.

procedure TForm1.Button1Click(Sender: TObject);
var Str:string;
begin
str:='SI         0.00 kg'; //ciąg skopiowany z terminala
Memo.Text:=Copy(Str,10,4);
end;

Wg dokumentacji wagi wysyłany string ma postac

S _ _ _ _ - _ _ _ _ _ _ 8 . 5 _ kg _ _ CR LF //podkreśliniki to spacje

Próba usunięcia znaków końca linii w ten sposób również nic nie daje.

procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);
var
  Str,str2,waga: String;
begin
ComPort.ReadStr(Str, Count);
Str2:=StringReplace(Str,#13#10,'add',[rfReplaceAll]);
waga:=Copy(Str2,12,5);
Memo.Text:=Memo.Text+waga;
end;

dodanie znaczników <code class="delphi"> i `` - Furious Programming

0

Problem z odczytem ramki wysyłanej przez wagę może być związany z tym, że gdy dostajesz zdarzenie OnRxChar, to nie koniecznie musi ci przyjść CAŁA ramka wysyłana przez wagę, a tylko jej część. Brakująca część przyjdzie w następnym zdarzeniu OnRxChar, tak więc najpierw kompletujesz całą ramkę (której długość jest ci znana), a dopiero ją przetwarzasz, np.:

Var
 Ramka: String;

procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);
var
  S, waga: String;
begin
  ComPort.ReadStr(S, Count); //odczyt całej lub części ramki
  Ramka:=Ramka+S; //łączenie kolejnych części ramki w jedną całość
  if length(Ramka)=Dlugosc_ramki then //za Dlugosc_ramki podstawiasz ilość znaków ramki 'S _ _ _ _ - _ _ _ _ _ _ 8 . 5 _ kg _ _ CR LF'
  begin 
    waga:=Copy(Ramka, 10, 5);
    Memo.Text:=Memo.Text+waga;
    Ramka:='';
  end; 
end;
0

dane przychodzą w paczkach po max 8 bajtów. Jeśli chcesz to możesz albo zrobić jak @marogo napisał(a) (z tym, że to nie zadziała w takiej postaci - zamiast sprawdzać czy masz odpowiednią ilość znaków sprawdzaj czy odebrałeś CR LF i jako ramkę traktuj wszystko to co jest pomiędzy kolejnymi CR LF albo użyj TComDataPacket ustawiając jako koniec danych CR LF - wtedy odwali on za Ciebie całą robotę z kompletowaniem ramki

0

Wg mnie powinna zadziałać metoda opisana przez usera Abrakadaber.
Użyj TComDataPacket i przed połączeniem się z portem ustaw mu właściwości

ComDataPacket.StartString = '';
ComDataPacket.StopString = '';

Poza tym sprawdź, czy nie łatwiej operować Ci na stringu jaki zwraca TComDataPacket.OnPacket

0

Pomogło ustawienie StopStringa z poziomu kodu.
Dzięki za pomoc.

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