ComPort odczyt danych

0

Zakupiłem urządzenie http://www.meraprojekt.com.pl/mp01613.html do odczytu transponderów.
1.Wrzuciłem na formatkę ComPorta, 2Buttony i Memo
2. Button1 -> Konfiguracja Portu -> Zdarzenie OnClick a w nim ComPort.ShowSetupDialog;
3. Button2 -> Otwarcie Portu -> Zdarzenie OnClick a wnim ComPort.Open;
4. ComPort1 -> Zdarzenie RxChar ->

ComPort.ReadStr(RevS, Count);
  Memo1.Text :=Revs;

Po skompilowaniu programu konfiguruje port wg zaleceń producenta.
Po przyłożeniu transpondera do czytnika w Memo1 powinny pojawiać się odczyty w postaci "890CD9004A".
Powinny ale pojawiają się tylko fragmenty tego stringu np. 890, 890CD, 9004A itp. Raz na kilkanaście prób wskakuje cały kod.
Kombinowałem na różne sposoby ale cały czas to samo.

Myślałem, że to problem urządzenia ale na hyperterminal za każdym razem schodzi pełen kod.
W ustawieniach ComPorta nic nie zmieniałem.

Delphi XE2; ComPort 4.10

0

Zwiększ ReadTimeout.
lub:
Memo1.Text := Memo1.Text + Revs;

0

Docelowo zamierzam zgrywać dane do Edita więc próbuję 1 wersję.

Wg producenta dane format przesyłanych danych: xx xx xx xx xx LF CR
gdzie xx to kolejne bajty kodu transpondera zapisane jako kod ASCII, LF - znak nastepnej linii, CR - znak powrotu. Dwa
ostatnie znaki przesyłane sa jedynie dla czytelniejszego przedstawienia danych np. w terminalu.

Początkowo ustawiłem ReadTotalMultiplier na 12 znaków
ReadTotalConstant=0;
Co 4 odczyt w takim przypadku daje cały kod.

Zdesperowany kolejne próby podejmowałem z ustawieniem ReadTotalMultiplier na 10, 14, 16 i 20.
W ComPort1.ShowSetupDialog wygląda tak: Com12, 9600, 8,1, None, None.

0
var all,part:string;
setlength(all,0);
while true do
begin
  ComPort.ReadStr(part,Count);
  all:=all+part;
  if Pos(#13#10,part)>0 then break;
end;
Memo1.Text:=all;
0
procedure TDodaj_pracownika.ComPort1RxChar(Sender: TObject; Count: Integer);
var
all,part:string;
begin
setlength(all,0);
while true do
begin
  ComPort1.ReadStr(part,Count);
  all:=all+part;
  if Pos(#13#10,part) then break;
end;
Memo1.Text:=all;


end; 

Wywala błąd [DCC Error] dodaj_prac.pas(126): E2012 Type of expression must be BOOLEAN
Możesz krótko wyjaśnić co takiego robi powyższy kod w porównaniu z ustawieniem timeout ręcznie?

0

Patrz komentarz wyżej. Podaj też opis metody: ComPort1.ReadStr(part,COUNT); tu też może być błąd.

0

Może podłącz do TComPort komponent TComDataPacket ?

(Na formę wrzuć 2x TEdit, TButton, TListbox, TComPort i TComDataPacket).
Ewentualnie jak chcesz to wywołuj Setupdialog ComPort.

procedure TMain.btnConnectClick(Sender: TObject);
begin
ComPort1.Port := edtPort.Text;
ComPort1.BaudRate := StrToBaudRate(edtBaudRate.Text);

ComDataPacket1.ComPort := ComPort1;

// Tu możesz zdefiniować od czego ma się zaczynać i na czym kończyć ciąg danych (string)
// Jako przykład podam dane, jakie ja odczytuję z urządzenia GPS:
// $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
// Jak widać mogę wyodrębnić interesujące mnie dane za pomocą:
ComDataPacket1.StartString := '$GPRMC';
ComDataPacket1.StopString := '*';
// Wtedy otrzymuje do obróbki czyste:
// ",123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W"
// Jeżeli nie potrzebujesz tego to przejdź do połączenia z portem.
// ComDataPacket czyta ZTCP cale ciągi właśnie na pdst znaku nowego wiersza. Wiec nie będziesz musiał
// ustawiać StartString i StopString.

  if ComPort1.Connected = true then
    begin
      //Rozlacz;
    end else begin
      //Polacz;
    end;
end;

Następnie we właściwości OnPacket ComDataPacket komponent zwraca Ci string z odczytanymi danymi:

procedure TMain.ComDataPacket1Packet(Sender: TObject; const Str: String);
begin
Listbox1.Items.Add(Str);
//Możesz tez wrzucać sobie String do TStringList i dalej go obrabiać
end;
0

Pomogło ustawienie ComDataPacket.Size=12 oraz StopString=#13.
Dziękuję za pomoc.

0
adnix napisał(a):

Pomogło ustawienie ComDataPacket.Size=12 oraz StopString=#13.
Dziękuję za pomoc.

Sądzę, że nie musisz ustawiać na sztywno długości pakietu odczytanych danych.
No chyba, że na 1000% Twój program będzie zawsze otrzymywał z portu 12 znaków.

Może lepiej odczytuj stringa tylko na pdst StopString (Nie jestem pewien, ale chyba nawet nie musisz ustawiać go w ogóle na "#13"), wrzucaj go gdzieś i tam dopiero sprawdzaj, wycinaj, konwertuj?

0
lofix napisał(a):
adnix napisał(a):

Pomogło ustawienie ComDataPacket.Size=12 oraz StopString=#13.
Dziękuję za pomoc.

Sądzę, że nie musisz ustawiać na sztywno długości pakietu odczytanych danych.
No chyba, że na 1000% Twój program będzie zawsze otrzymywał z portu 12 znaków.

Może lepiej odczytuj stringa tylko na pdst StopString (Nie jestem pewien, ale chyba nawet nie musisz ustawiać go w ogóle na "#13"), wrzucaj go gdzieś i tam dopiero sprawdzaj, wycinaj, konwertuj?

Urządzenie wg dokumentacji zawsze wysyła 12 znaków ale masz rację, że przy jakiś śmieciach program może się wywrócić.
Muszę ustawić stop na #13 bo otrzymanie znaku nowej linii z urządzrnia automatycznie(puste pole start i stopstring)powoduje, że do zmiennej Str za pierwszym razem trafia to co jest przed $13 a po następnym odczycie Str zwraca tę końcówkę plus część następnego odczytu. Nie potrafię tego wyjaśnić.

0

Chyba jednak ustalenie długości łańcucha na stałe może być przyczyną błędów.
Fragment ComDataPacket1Packet.OnPacket()

ShowMessage(RemoveSpaces(Str)
testquery.SQL.Text:='SELECT * FROM Pozycja where id_prac=(SELECT ID FROM PRACOWNICY WHERE KOD='''+RemoveSpaces(Str)+''') and Convert(date,data_przyj)='''+RemoveSpaces(DateToStr(DateTimePicker1.Date))+'''  ';
testquery.ExecSQL;
testquery.Open;
iloscwierszy:=testquery.RecordCount;
ShowMessage('Ilość wpisów w tabeli Prozycja:'+IntTostr(iloscwierszy)); 

Powyższy kod na Windows 7 działa poprawnie, natomiast po przeniesieniu programu na Windowsa XP program wyświetla Message z zawartością Str(poprawny odczyt) ale nie dochodzi już do wyświetlenia powiadomienia z ostatniej linii. Tak jakby polecenie sql zawieszało program. Wersja SQL serwer taka sama.

Funkcja RemoveSpaces

function RemoveSpaces(const s: string): string;
var
len, p: integer;
pc: PChar;
const
WhiteSpace = [#0, #9, #10, #13, #32];

begin
len := Length(s);
SetLength(Result, len);

pc := @s[1];
p := 0;
while len > 0 do
begin
if not (pc^ in WhiteSpace) then
begin
inc(p);
Result[p] := pc^;
end;

inc(pc);
dec(len);
end;

SetLength(Result, p);
end; 

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