C++ RS232 ReadTimeout

Wszystko co dotyczy tworzenia i optymalizacji stron internetowych oraz programowania
yanan

Użytkownik
Posty: 3
Rejestracja: 02 lip 2013, 22:07

C++ RS232 ReadTimeout

Post02 lip 2013, 22:11

Witam

Mam problem z transmisją przez RS232.
Jeżeli mikrokontroler i komputer są połączone to normalnie wysyłają dane.
Jednak jeżeli jeden z przewodów nie są połączone wówczas program "wisi" na procedurze ReadFile(). Pod linuxem wszystko działa i elegancko wychodzi z programu zgłaszając błąd transmisji. Pod windows-em (Visual studio c++) program się nie kończy w przypadku nie podłączenia przewodów rx i/ lub tx.
Jak należy sobie z tym poradzić?
Czytałem manuala, ale jakoś nie chce to działać i już tracę siły z tym czymś...
Liczę na jakąkolwiek pomoc

wysyłam listing i pozdrawiam

Kod: Zaznacz cały

unsigned int RS232::Read(void *buf, unsigned int size) {
#ifdef WIN32
   DWORD cnt;
 
   if ( ReadFile(handle, buf, size, &cnt, NULL) == FALSE )
      return -1;
   return cnt;
#else
   return read(handle, buf, size);
#endif
}


Inicjalizacja portu

Kod: Zaznacz cały


bool RS232::Open(const char *name, unsigned int baudRate, bool parity, unsigned char stopBits) {
#ifdef WIN32
   handle = NULL;
   handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
   if ( handle == INVALID_HANDLE_VALUE )
      return false;
 
   // com-port initialization
   DCB dcb;
   dcb.DCBlength = sizeof(DCB);
   if( !GetCommState(handle, &dcb) ) {
      Close();
      return false;
   }
 
   dcb.BaudRate = baudRate;               // baudrate (in bauds)
   dcb.fBinary = true;                     // binary mode
   dcb.fOutxCtsFlow = false;               // disable the CTS sygnal listening
   dcb.fOutxDsrFlow = false;               // disable the DSR sygnal listening
   dcb.fDtrControl = DTR_CONTROL_DISABLE;   // disable the DTR-line
   dcb.fDsrSensitivity = false;            // ignore state of the DSR-line
   dcb.fNull = false;                     // allow zerro-bytes input
   dcb.fRtsControl = RTS_CONTROL_DISABLE;   // not use the RTS-line
   dcb.fAbortOnError = false;               // disable abort on error
   dcb.ByteSize = 8;                        // 8 bits per byte
   dcb.Parity = parity ? 1 : 0;            // paricy checking
   dcb.StopBits = stopBits;               // stop-bits
 
   // load DCB to port
   if( !SetCommState(handle, &dcb) ) {
      Close();
      return false;
   }
 
   // set timeouts
   COMMTIMEOUTS timeouts;
   timeouts.ReadIntervalTimeout = 0;         // timeout beetwen to chars
   timeouts.ReadTotalTimeoutMultiplier = 0;   // general reading operations timeout
   timeouts.ReadTotalTimeoutConstant = 0;      // constant for the general reading operations timeout
   timeouts.WriteTotalTimeoutMultiplier = 0;   // general writing operations timeout
   timeouts.WriteTotalTimeoutConstant = 0;   // constant for the general writing operations timeout
   if( !SetCommTimeouts(handle, &timeouts) )   {
      Close();
      return false;
   }
 
   // setup sizes of TX/RX quenes
   if ( SetupComm(handle, 1024*2, 1024*2) == FALSE ) {
      Close();
      return false;
   };
 
   // clear the reading buffer
   if ( PurgeComm(handle, PURGE_RXCLEAR) == FALSE ) {
      Close();
      return false;
   };
#else
   int baudr = getBaudrateValue(baudRate);
   if ( baudr == 0 ) {
      perror("invalid comport baudrate\n");
      return false;
   }
   handle = open(name, O_RDWR | O_NOCTTY | O_NDELAY);   
   if( handle == -1 ) {
      perror("unable to open comport");
      return false;
   }
 
   int error = tcgetattr(handle, &old_port_settings);
   if ( error == -1 ) {
      close(handle);
      perror("unable to read portattr");
      return false;
   }
   memset(&new_port_settings, 0, sizeof(new_port_settings));  // clear the new struct
 
   new_port_settings.c_cflag = baudr | CS8 | CLOCAL | CREAD;
   if ( parity )
      new_port_settings.c_cflag |= PARENB;
   new_port_settings.c_iflag = IGNPAR;      // Ignore characters with parity errors.
   new_port_settings.c_oflag = 0;
   new_port_settings.c_lflag = 0;
   new_port_settings.c_cc[VMIN] = 0;      // block untill n bytes are received
   new_port_settings.c_cc[VTIME] = 0;     // block untill a timer expires (n * 100 mSec.)
   error = tcsetattr(handle, TCSANOW, &new_port_settings);
   if ( error == -1 ) {
      close(handle);
      perror("unable to adjust portsettings ");
      return false;
   }
 
#endif
   return true;
}


Awatar użytkownika
cosik_ktosik

Administrator
Posty: 21399
Rejestracja: 13 lis 2008, 01:17
Lokalizacja: Szczecin
Kontaktowanie:

C++ RS232 ReadTimeout

Post02 lip 2013, 22:31

Ale coś mi tutaj nie pasi, a w zasadzie nie widzę momentu czytania.
Możesz podesłać link do dokumentacji z której korzystasz?

Ja opisałem swoje przygody tutaj http://www.hotfix.pl/c-c++-winapi-komun ... 2-a334.htm
na dole jest też komentarz co do problemu z otwieraniem portu.
Hotfix
Pozdrawiam, cosik_ktosik :)

yanan

Użytkownik
Posty: 3
Rejestracja: 02 lip 2013, 22:07

C++ RS232 ReadTimeout

Post05 lip 2013, 12:46

Korzystam z manuala od Microsoftu

Dostępne tylko dla zarejestrowanych użytkowników

Po dzisiejszych testach program zatrzymuje się na

Kod: Zaznacz cały

unsigned int RS232::Read(void *buf, unsigned int size) {
#ifdef WIN32
   DWORD cnt;

// Tutaj się zatrzymuje

   if ( ReadFile(handle, buf, size, &cnt, NULL) == FALSE )
      return -1;
   return cnt;
#else
   return read(handle, buf, size);
#endif
}


Jak daje bez if-a to też wisi na readfile tak jakby czekał aż coś przyjdzie przez RS-a, a przecież wiem, że nic nie ma prawa wtedy przyjść i tym sposobem program nie ma warunku stopu. Wcześniej napotkałem na artykuł, który wkleiłeś, ale i tak nie działa. Cieszę się, że starasz się pomóc, bo wszyscy na uczelni jak patrzą na oprogramowanie, które się komunikuje z peryferiami to mają miny zakłopotanego chomika, a sam niczego nie wymyślę...

Jeszcze kombinowałem z timeoutem, ale spowolniło to odczyt (w trybie "normalnym") a w trybie w którym nie ma prawa odczytać nadal wisi.


Jak wysyłamy dane to zawsze można je odczytać. Czytanie to klasyczny ReadFile. Odczytajmy sobie 15 znaków

ReadFile(hNumPort, lpBuffor_read, 15, &RS_ile, 0);


Odczytać coś z portu okazało się, że to tak łatwo powiedzieć, gorzej z wyjątkami... :)

Pozdrawiam

-- 05 lip 2013, 12:45 ---

Przepisałem program do javy, więc daruje sobie WINAPI w C++

Awatar użytkownika
cosik_ktosik

Administrator
Posty: 21399
Rejestracja: 13 lis 2008, 01:17
Lokalizacja: Szczecin
Kontaktowanie:

C++ RS232 ReadTimeout

Post06 lip 2013, 00:12

Działa już czy mam analizować?
Hotfix
Pozdrawiam, cosik_ktosik :)

yanan

Użytkownik
Posty: 3
Rejestracja: 02 lip 2013, 22:07

C++ RS232 ReadTimeout

Post06 lip 2013, 14:20

W c++ nie udało mi się napisać tego timeoutu. Przeczytałem, że musi być napisana obsługa asynchronchroniczna (I/O OVERLAPPED), a nie jak było synchronicznie. Tylko wtedy da się wprowadzić timeout, ale już tego napisać nie potrafię... kombinuję napisać to w javie chyba, że podpowiesz jak to napisać w c++, bo nikt z kim na ten temat mówiłem nie potrafił mi do tej pory pomóc, a był to jedyny mankament programu :cry:

Dostępne tylko dla zarejestrowanych użytkowników

zgred125

Użytkownik
Posty: 1
Rejestracja: 25 sie 2014, 01:29

C++ RS232 ReadTimeout

Post27 sie 2014, 15:42

Witam

Dostane chyba medal górnika roku za odgrzebywanie starych postów. Czy komuś udał się opanować ten TIMEOUT?
Mam problem z atmegą 382P, która wysyła dane po RS232 tylko w przypadku kiedy zostanie o to poproszona przez program albo w momencie zaistnienia pewnych czynników zewnętrznych w każdym razie nieregularnie i bez żadnego wzoru. Program piszę w C++ Builder 6 do sprawdzania czy mC nie przysłał nowych danych oraz do obróbki ich używam timera z interwałem 500ms. Kiedy podczas wykonywania swojego kodu program napotka Readfile(...) to zwyczajnie zawiesza się na tym czekając, aż coś przyjdzie z mC. Jeżeli zdarzyło by się tak, że w momencie zawieszenia coś by jednak przyszło program odwiesi się zrobi to co ma zrobić i zawiesi się przy kolejnym wyzwoleniu timera poleceniu Readfile - aż coś nie przyjedzie znowu :-). Najśmieszniejsze w tym wszystkim jest to, że uruchomienia np. SerialMonitora w Arduino IDE, otwarcie portu na którym ma pracować program i zamknięcia go w jakiś sposób powoduje ustawienie TIMEOUT na danym porcie COM i mój program przestaje się zawieszać aż do restartu komputera :-)

Bardzo proszę o pomoc w ogarnięciu tematu bo do całego projektu brakuje mi tylko tego.



  • Reklama

Wróć do „Webmastering i programowanie”



Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 13 gości