|
Question : RS-485 Serial Communications
|
|
I'm trying to communicate with a digital board via RS-485. I can talk to it via RS-422 and RS-232, however, when I try to talk via RS-485, I can not read. I have a thread running that monitors the port for a character received, using WaitCommEvent. I saw a bug reported by Microsoft saying that the RTS_CONTROL_TOGGLE parameter in the DCB structure really didn't toggle and that you had to control RTS manually. So I tried to use the EscapeCommFunction with the SETRTS parameter prior to the WriteFile and then use the CLRRTS parameter immediately after the WriteFile. For some reason I can only write to the device and I never receive a response back. I know the device is responding because I tapped into the wire and redirected the output. There seems to be a timing problem with setting my computer to RTS and then clearing and reading what is coming back. Any help would be greatly appreciated. Code examples are definitely needed.
|
|
Answer : RS-485 Serial Communications
|
|
This could happen if you use the FILE_FLAG_OVERLAPPED while you open your port.
Take a look at the code to figure out how to wait: The code was snipped from the TTY-com sample.
http://msdn.microsoft.com/library/devprods/vs6/visualc/vcsample/vcsmpserialsampleforcommunicationsdemonstration.htm
///----------- start
fWriteStat = WriteFile( idComDev, lpByte, dwBytesToWrite, &dwBytesWritten, &osWrite)?true:false ;
// Note that normally the code will not execute the following // because the driver caches write operations. Small I/O requests // (up to several thousand bytes) will normally be accepted // immediately and WriteFile will return true even though an // overlapped operation was specified
if (!fWriteStat) { if(GetLastError() == ERROR_IO_PENDING) { // We should wait for the completion of the write operation // so we know if it worked or not
// This is only one way to do this. It might be beneficial to // the to place the writing operation in a separate thread // so that blocking on completion will not negatively // affect the responsiveness of the UI
// If the write takes long enough to complete, this // function will timeout according to the // CommTimeOuts.WriteTotalTimeoutConstant variable. // At that time we can check for errors and then wait // some more.
while(!GetOverlappedResult( idComDev, &osWrite, &dwBytesWritten, TRUE )) { dwError = GetLastError(); if(dwError == ERROR_IO_INCOMPLETE) // normal result if not finished continue; else { // an error occurred, try to recover wsprintf( szError, "", dwError ) ; //WriteTTYBlock( npTTYInfo , szError, lstrlen( szError ) ) ; ClearCommError(idComDev, &error, &ComStat ) ; if (error > 0) { wsprintf( szError, "", error ) ; MessageBox(NULL,szError,"",MB_OK); } break; } } } else { // some other error occurred
ClearCommError(idComDev, &error, &ComStat ) ; if((error & CE_BREAK) == CE_BREAK){ MessageBox(0,"The hardware detected a break condition.","RS232",MB_OK); } if((error & CE_DNS) == CE_DNS){ MessageBox(0,"Windows 95 only: A parallel device is not selected.","RS232",MB_OK); } if((error & CE_FRAME) == CE_FRAME){ MessageBox(0,"The hardware detected a framing error.","RS232",MB_OK); } if((error & CE_IOE) == CE_IOE){ MessageBox(0,"An I/O error occurred during communications with the device.","RS232",MB_OK); } if((error & CE_MODE) == CE_MODE){ MessageBox(0,"The requested mode is not supported, or the hFile parameter is invalid. If this value is specified, it is the only valid error.","RS232",MB_OK); } if((error & CE_OOP) == CE_OOP){ MessageBox(0,"Windows 95 only: A parallel device signaled that it is out of paper.","RS232",MB_OK); } if((error & CE_OVERRUN) == CE_OVERRUN){ MessageBox(0,"A character-buffer overrun has occurred. The next character is lost.","RS232",MB_OK); } if((error & CE_PTO) == CE_PTO){ MessageBox(0,"Windows 95 only: A time-out occurred on a parallel device.","RS232",MB_OK); } if((error & CE_RXOVER) == CE_RXOVER){ MessageBox(0,"An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.","RS232",MB_OK); } if((error & CE_RXPARITY) == CE_RXPARITY){ MessageBox(0,"The hardware detected a parity error.","RS232",MB_OK); } if((error & CE_TXFULL) == CE_TXFULL){ MessageBox(0,"The application tried to transmit a character, but the output buffer was full.","RS232",MB_OK); } return ( FALSE ); } } return ( true ) ;
|
|
|
|