ComPort odczyt danych

AD
  • Rejestracja:około 14 lat
  • Ostatnio:3 miesiące
  • Postów:85
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 ->

Kopiuj
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

edytowany 2x, ostatnio: olesio
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

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


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
AD
  • Rejestracja:około 14 lat
  • Ostatnio:3 miesiące
  • Postów:85
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.

edytowany 2x, ostatnio: adnix
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0
Kopiuj
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;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
_13th_Dragon
Poprawione. Jeżeli pytasz o coś na forum nie wyłączaj mózgu. Traktuj podpowiedzi jako schemat nie jako gotowiec.
AD
  • Rejestracja:około 14 lat
  • Ostatnio:3 miesiące
  • Postów:85
0
Kopiuj
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?

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

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


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
lofix
  • Rejestracja:około 23 lata
  • Ostatnio:około miesiąc
  • Lokalizacja:Wdzydze
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.

Kopiuj
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:

Kopiuj
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;

Pozdrawiam. Karol
edytowany 7x, ostatnio: lofix
AD
  • Rejestracja:około 14 lat
  • Ostatnio:3 miesiące
  • Postów:85
0

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

lofix
Kłaniam się. Jeżeli jeszcze zatrzymasz się na jakimś problemie - napisz Ja ostatnio tylko zajmuję się komunikacją via COM Poza tym zainteresowałeś mnie tym RFID :)
lofix
  • Rejestracja:około 23 lata
  • Ostatnio:około miesiąc
  • Lokalizacja:Wdzydze
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?


Pozdrawiam. Karol
AD
  • Rejestracja:około 14 lat
  • Ostatnio:3 miesiące
  • Postów:85
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ć.

edytowany 2x, ostatnio: adnix
AD
  • Rejestracja:około 14 lat
  • Ostatnio:3 miesiące
  • Postów:85
0

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

Kopiuj
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

Kopiuj
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; 
edytowany 3x, ostatnio: adnix

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.