• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 945
  • Last Modified:

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.
0
jstephe1
Asked:
jstephe1
  • 2
1 Solution
 
Gus012498Commented:
How did you interface your PC to the RS-485 line? Can you recevie data if you try to loopback?

Regards,
Gus
0
 
jstephe1Author Commented:
Actually, I've somewhat figured it out.  Before I do the WriteFile, I set the RTS with the EscapeCommFunction.  After the WriteFile, I clear the RTS.  What I did is to add a Sleep(20) after the WriteFile.  It seems as if the code is just too fast and is clearing the RTS before the write is complete.  Is there a way to make sure the output buffer is empty before I clear the RTS?  I would rather not use a Sleep function.
0
 
Gus012498Commented:
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, "<CE-%u>", dwError ) ;
                              //WriteTTYBlock( npTTYInfo , szError, lstrlen( szError ) ) ;
                              ClearCommError(idComDev, &error, &ComStat ) ;
                              if (error > 0)
                              {
                                    wsprintf( szError, "<CE-%u>", 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 ) ;

0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now