ComPort.WriteStr - dziwne zachowanie

Odpowiedz Nowy wątek
2020-06-28 18:49

Rejestracja: 1 tydzień temu

Ostatnio: 1 dzień temu

0

Cześć,

Piszę program do obsługi robota przez USB w Delphi. Wykorzystuję bibliotekę ComPort. W laptopie podłączenie USB do robota poprawnie zgłasza się jako Virtual Port Com. Gdy wysyłam komendę:

ComPort.WriteStr('komenda');

to procesor w robocie w ogóle jej nie zauważa. Natomiast gdy wysyłam z programu Terminal to jest OK.

Ustawienia transmisji mam takie same.

Gdzie może być przyczyna tego problemu?

Pozdrawiam.

edytowany 2x, ostatnio: furious programming, 2020-06-28 18:53

Pozostało 580 znaków

2020-06-29 23:42
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 1 minuta temu

Lokalizacja: Tuchów

2

Nie chcę się wypowiadać za bardzo w tym wątku, dlatego że doświadczenie w temacie komunikacji szeregowej mam praktycznie żadne (nie licząc Arduino, ale to inna bajka). Mimo wszystko – tak na logikę – komunikacja musi być oparta o jakieś metadane lub z góry narzucony stały rozmiar ramki. Urządzenie odbierające dane musi wiedzieć ile ich otrzyma (z góry określony rozmiar bufora), a jeśli nie wiadomo ile tych danych będzie, wymagane jest oznaczenie końca danych znakiem terminatora. Tak działają np. kasy fiskalne.

W sieci masz kupę przykładów i wątków dotyczących ComPort.WriteStr – wszystkie wykorzystują terminator.


edytowany 1x, ostatnio: furious programming, 2020-06-29 23:43

Pozostało 580 znaków

2020-06-30 00:05

Rejestracja: 4 lata temu

Ostatnio: 2 godziny temu

2
furious programming napisał(a):

Mimo wszystko – tak na logikę – komunikacja musi być oparta o jakieś metadane lub z góry narzucony stały rozmiar ramki. Urządzenie odbierające dane musi wiedzieć ile ich otrzyma (z góry określony rozmiar bufora), a jeśli nie wiadomo ile tych danych będzie, wymagane jest oznaczenie końca danych znakiem terminatora. Tak działają np. kasy fiskalne.

Tak jest, większość urządzeń z jakimi miałem do czynienia właśnie tak działały jak piszesz. Ale.... raz się spotkałem z urządzeniem które nie miało takich ramek. Ot po prostu po każdym znaku analizowało komendę i jak była prawidłowa wykonywała ją. Dziwne to było, jednak trzeba było się dostosować. Nadmienię, że to był pomysł architektów systemów wewnętrznych i urządzenie nie wyszło poza firmę. Jednak musiałem gadać z nim i sama integracja trwała długo. Niemniej jednak terminatorem nie musi być znak nowej linii. W drukarkach fiskalnych które miałem obsługiwać taka ramka ma postać:

ESC komenda ESC \

Poza tym bardzo ważne są dokładne ustawienia portu COM, musi się zgadzać z tym co ustawione w urządzeniu.

edytowany 1x, ostatnio: Mr.YaHooo, 2020-06-30 21:26

Pozostało 580 znaków

2020-06-30 01:01
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 1 minuta temu

Lokalizacja: Tuchów

1
Mr.YaHooo napisał(a):

Ale.... raz się spotkałem z urządzeniem które nie miało takich ramek. Ot po prostu po każdym znaku analizowało komendę i jak była prawidłowa wykonywała ją. Dziwne to było, jednak trzeba było się dostosować.

Może nie tyle dziwne, co nietypowe. Sam bym takiego sposobu nie wybrał. Raz, że trzeba by więcej kodu klepać, aby móc poprawnie interpretować nadchodzące dane, a dwa, że testowanie zawartości bufora po każdym otrzymanym znaku jest tak samo wydajne co sortowanie bąbelkowe. No bez sensu.

Nie mniej jednak terminatorem nie musi być znak nowej linii.

Nigdzie nie pisałem, że musi nim być konkretnie CR lub LF (albo sekwencja CRLF). :P


edytowany 5x, ostatnio: furious programming, 2020-06-30 01:05
Tak, faktycznie błędnie założyłem w kontekście wysyłania przez Terminal i zatwierdzania Enterem wysyłki komendy. - Mr.YaHooo 2020-06-30 21:27

Pozostało 580 znaków

2020-06-30 05:57

Rejestracja: 1 tydzień temu

Ostatnio: 1 dzień temu

0

Tylko, że jak pisałem z Terminala odbiera, a z ComPortu NIE. Gdyby z Terminala nie odbierał, to błąd byłby po stronie urządzenia/robota.
Poza tym ramka ma zmienną długość, ale ma znaki początku i zakończenia ramki.

edytowany 1x, ostatnio: Markoni, 2020-06-30 05:58

Pozostało 580 znaków

2020-06-30 12:22

Rejestracja: 1 tydzień temu

Ostatnio: 1 dzień temu

0

Zainstalowałem API Monitor i w funkcji SetCommState ustawienia dla Terminala i ComPort są te same. Różnica jest tylko w wReserved, XonLim, XoffLim.
Często mam też problemy z otwarciem portu: SetCommState=Error: 87.
Ale w Terminalu otwiera się zawsze.

Jak można usunąć problem z SetCommState=Error: 87?

edytowany 1x, ostatnio: Markoni, 2020-06-30 12:49

Pozostało 580 znaków

2020-06-30 21:31

Rejestracja: 4 lata temu

Ostatnio: 2 godziny temu

0

@Markoni ten błąd niestety jest dość parszywy. Przyczyna może być różna od śmieci które się pojawiają podczas tworzenia struktury DCB poprzez błędne parametry których nie obsługuje port. Zatem osobiście próbowałbym ustawić dokładnie takie same parametry jak Terminal który nie ma problemu z połączeniem.

Swoją drogą błąd 87 masz podczas otwarcia portu, czy wykonania funkcji SetCommState Generalnie sprawdź czy masz mniej więcej podobnie jak tutaj https://docs.microsoft.com/pl[...]-resource?redirectedfrom=MSDN przepisz to na Delphi i sprawdź czy zadziała, podstawiając swoje parametry.

Osobiście nigdy podczas obsługi portu COM nie spotkałem się z tym błędem, więc trochę ciężko mi doradzić.

Pozostało 580 znaków

2020-06-30 22:29

Rejestracja: 1 tydzień temu

Ostatnio: 1 dzień temu

0

Błąd pojawia się podczas otwierania portu.

Pozostało 580 znaków

2020-07-01 21:49

Rejestracja: 4 lata temu

Ostatnio: 2 godziny temu

0

W takim razie być może źle tworzysz nazwę pliku który otwierasz jako port COM. Ciężko coś powiedzieć bez kodu. Fajnie by było abyś dał jakiś przykład jak otwierasz oraz ustawiasz parametry portu.

Pozostało 580 znaków

2020-07-01 22:25

Rejestracja: 1 tydzień temu

Ostatnio: 1 dzień temu

0

Prawdę mówiąc to otwieram klasycznie, przez wprowadzenie parametrów transmisji do TComPort, podania numeru portu i komendę ComPort.Open.
Jak powinno się "profesjonalnie" otwierać port COM?

Pozostało 580 znaków

2020-07-01 23:23
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 1 minuta temu

Lokalizacja: Tuchów

1
Markoni napisał(a):

Prawdę mówiąc to otwieram klasycznie, przez wprowadzenie parametrów transmisji do TComPort, podania numeru portu i komendę ComPort.Open.

Wklej kod zamiast opisywać jak on wygląda…


Pozostało 580 znaków

Odpowiedz

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