Problemy z komunikacją przez port COM

0

Problem jest nieco głębszy więc zacznę od początku....

W aplikacji którą mam jest możliwość wysłania czegoś na port szeregowy... przy czym cała obsługa wygląda tak, że jest otwierany port, później wysyłane są znaki i port jest zamykany.

w skrócie jest to klasyczny przykład transmisji na tym porcie, w bardzo dużym skrócie kod wygląda tak:

...
FPortHandle := CreateFile(PChar('\\.\COM1'), (GENERIC_READ or GENERIC_WRITE), 0, nil, OPEN_EXISTING, 0, 0);
...
WriteFile(FPortHandle, Buf^, FOutBufSize, Sent, nil);
...
CloseHandle(FPortHandle);

I jeszcze jedno urządzenie nigdy niczego nie zwraca... więc czekanie na informację zwrotną nie ma większego sensu, po prostu ma być to wysłane na port i tyle...

Oczywiście jest konfiguracja parametrów portu, prędkości transmisji itd..., wywoływany są funkcje API FlushFileBuffers, WaitCommEvent.... itd...

I wszystko jest ok na fizycznych portach COM, czy na sterownikach popełnionych przez Microsoft. Problem pojawia się jeżeli jest to interface USB z konwersją na COM... do którego podpięte jest jakieś urządzenie, a sterowniki napisane są przez dostawcę tego cuda...

W przypadku gdy używam portu fizycznego to closehandle zachowuje się poprawnie, dane są kompletne i na drugim komputerze (testowym) dostaję je w całości...

Jednak w przypadku przejściówek USB... pojawia się problem... CloseHandle urywa transmisję nieważne ile zostało w rzeczywistości wysłane...

Przykładowo wysyłam 100 bajtów (tle jest przekazane do WriteFile), dostaję informację, że wszystko jest ok i że zostało zapisane/wysłane 100 bajtów...

jednak na drugim komputerze odbieram tylko cześć danych... rozwiązaniem tymczasowym jest wywołanie delay(100) przed zamknięciem portu... ale... podejrzewam że czas oczekiwania będzie różny w zależności od długości wysłanych danych i zdefiniowanej prędkości transmisji... żadne próby i kombinacje z FlushFileBuffers i WaitCommEvent nie odniosły skutku...

Mało tego... problem nie występuje tylko w Delphi... wyglądana to że jest to ogólny problem w Windowsie

Ten sam problem występuje nawet gdy wysyła się dane z ręki z konsoli...

MODE COM2: BAUD=57600 PARITY=N DATA=8 STOP=1 XON=OFF
Copy /b 1.txt COM2:

Również dane są urwane... niekompletne..
Wina jest na 100% po stronie sterowników różnych producentów przejściówek... tyle, że tych 'złych' jest chyba więcej... na 6 testowanych chyba tylko jedna zachowuje się poprawnie...
Może jest na to jakieś rozwiązanie? Chociaż jak nawet konsola na tym padła...

Szukałem rozwiązań na necie... i echo... nie zauważyłem by ktoś z tym walczył... czy znalazł rozwiązanie...
A dokładanie Delay na przed zamknięciem portu to chyba najgorsza możliwa opcja... tyle, że może się okazać jedyną...

Może ktoś rozwiązał ten problem, bądź wie jak go rozwiązać?

Z gry dziękuje za wszelkie sugestie

Pozdrawiam
Darek

0

Synapse ma coś od obsługi komunikacji szeregowej, może się sprawdzi?

0

Jest coś takiego jak CreateIoCompletionPort(), może tym się pobaw...

0

Używając System.IO.Ports masz wszystko jak na dloni.
Poczytaj to, swietny poradnik:

http://www.dreamincode.net/forums/topic/35775-serial-port-communication-in-c%23/

BTW, pisalem ostatnio program obslugujacy dalmierz, ktory byl podlaczony przez RS422 z przejsciowka USB. Bez problemu

EDIT:
Sory, dopiero teraz zobaczylem tag Delphi.

0

A patrzyłeś czy są jakieś zaawansowane ustawienia tego emulowanego portu COM? Z doświadczenia powiem, że faktycznie takie emulowane porty COM potrafią robić problemy. Mam przypadek że pomimo ustawienia parametrów transmisji na 9600 oraz 8 bitów we właściwościach portu COM po uruchomieniu Windows jest 4800 oraz 7 bitów. Co więcej jak się ustawi np poleceniem mode com1 poprawne wartości, to po pewnym czasie wraca to swoich ustawień. Pomimo, że w ustawieniach portu COM cały czas jest 9600/8bit... Osobiście nie znalazłem rozwiązania i obawiam się, że w Twoim sprzęcie może być podobnie.

0

A funkcję SetCommMask z flagą EV_TXEMPTY próbowałeś użyć?

https://msdn.microsoft.com/en-us/library/windows/desktop/aa363435%28v=vs.85%29.aspx

0

nie wiem dlaczego ale dane są wysyłane w paczkach po 8 bajtów :). Przerabiałem to jakiś czas temu z różnymi przejściówkami. W Delphi przy użyciu TComPort wygląda to tak, że jeśli urządzenie zewnętrzne wyśle ciąg np. ABCDEFGHIJKLMNOPQRSTUVWXYZ to odczytując z portu przy pomocy ReadStr dostanie się
ABCDEFGH
IJKLMNOP
QRSTUVWX
YZ
każda linijka to kolejny odczyt.

Tutaj najlepiej jest jeśli urządzenie wysyła stały znak na końcu ramki (np. #13) - wtedy po prostu trzeba czytać z portu aż będzie cała ramka.

Jeśli chodzi o wysyłanie na urządzenie to nie miałem z tym żadnych problemów

0
Patryk27 napisał(a):

Synapse ma coś od obsługi komunikacji szeregowej, może się sprawdzi?

Sprawdziłem kilka różnych komponentów, bibliotek w tym zachwalany CPort i... na wszystkich jest ten sam problem. Mało tego odszukałem stronę producenta, zastosowałem się do jego zaleceń i... też w przypadku gdy bezpośrednio po wysłaniu danych zamyka się port dane nie docierają kompletne

docxxx napisał(a):

Używając System.IO.Ports masz wszystko jak na dloni.
Poczytaj to, swietny poradnik:

http://www.dreamincode.net/forums/topic/35775-serial-port-communication-in-c%23/

BTW, pisalem ostatnio program obslugujacy dalmierz, ktory byl podlaczony przez RS422 z przejsciowka USB. Bez problemu

EDIT:
Sory, dopiero teraz zobaczylem tag Delphi.

Język nie ma znaczenia, więc zajrzę być może trafię tam na odpowiednie wskazówki, Być może przetestuję to na C# jeżeli zadziała... to wrócę do Delphi :)

0

@Mr.YaHooo

Producentem chipa jest Silicon Labs, sterownik zgłasza się jako silicon labs cp210x. Przy czym wielu producentów przejściówek z tego cuda korzysta... Szukałem jakiś ustawień... ale nic... są tylko standardowe. Wersja Windowsa nie ma znaczenia 7,8,8.1,10... te sprawdzałem.

@abrakadaber

Jeśli chodzi o wysyłanie na urządzenie to nie miałem z tym żadnych problemów</quote>

Z odczytem nie mam problemu... to działa... ale z zapisem i bezpośrednio po nim następującym zamknięciem portu jest problem. Dane się tracą...

@marogo

To była jedna z pierwszych rzeczy jaką sprawdziłem...

0

Jak dla mnie to jest po prostu bug w sterownikach i jeśli nie znajdzie się jakiegoś hacka na to, nic się nie zrobi...

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