Solved

serial interface

Posted on 1998-08-14
1
412 Views
Last Modified: 2012-06-21
i write a monitoring program and i need to read permanent the rs232 port i must receive 4 byte data
on com1. I write fallowing code fragment for initialisation the com1 and send and receive function
but when i send 4 byte data sometimes its ok sometimes not and when i will receive data i receive
everytime 2 byte or 3 byte, what can be wrong with my code,
i send a command message packet to a targetsystem and must wait for answer, how can i synchronize
send and receive sequence, the target system need time to execute the command(about 400 ms).

                 thank you

void MainFrame::OnDeviceSerial()  /*initialisation the serial interface*/
{
 
   
        COMMCONFIG com;
      COMMTIMEOUTS cto;
     
      int ans;
      CString cst;
    CString dw_par;
      CString cw_par;
      CString si_par;
      HANDLE hdl;
      ans=0;
      DCB dcbp;
       MONITORINGApp*  mainapp;
       mainapp=(MONITORINGApp*)AfxGetApp();
     hdl=mainapp->hcomm;
      
       lk = CommConfigDialog( "COM1",GetSafeHwnd( ),&com);/* show the Serial interface dialog for COM2*/
       if(hdl==0){
       hdl=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);/*open com2 for read and write*/
       }
       if(GetLastError()==ERROR_INVALID_HANDLE) AfxMessageBox("INVALIDE HANDLE");
       memset(&cto,0,sizeof(cto));/* init timeout structur for com2*/

      // cto.ReadTotalTimeoutMultiplier=1; /****125*4=500 ms time for read operation*/
      
       cto.WriteTotalTimeoutMultiplier=1;
       SetCommTimeouts(hdl,&cto);/*set timeouts */
       com.dcb.DCBlength=sizeof(com.dcb);
       DCB dcb3=com.dcb;
       GetCommState(hdl,&dcb3);
       SetCommState(hdl,&com.dcb);/*set the com parameter*/
     GetCommState(hdl,&dcbp);/*get the com parameter*/
     comok=1;
      }

================================================
================================================
BOOL transfer::send_msg()
{
BOOL mark;
BOOL send_ok;      
int byte_count;
byte_count=0;
send_ok=false;      
//fwritestat=WriteFile(APPT()->hcomm,&write_buffer,bytes_to_write,&bytes_writen,&oswrite);
      for(int m=0; m<4; m++){
            ::Sleep(50);
            fwritestat=WriteFile(APPT()->hcomm,&write_buffer[m],1,&bytes_writen,&oswrite);
            if(bytes_writen) byte_count++;}
      if(bytes_to_write==(DWORD)byte_count) send_ok=true;
      if(!fwritestat)
      {
            if(GetLastError()== ERROR_IO_PENDING)
            {
                  while(!GetOverlappedResult(APPT()->hcomm,&oswrite,&bytes_writen,TRUE)){
                        dwError=GetLastError();
                        if(dwError==ERROR_IO_INCOMPLETE)
                        {
                              dw_bytes_sent+=bytes_writen;
                              continue;
                        }
                        else{
                              ClearCommError(APPT()->hcomm,&dwerrorflag,&comstat);
                              break;
                        }
                  }
          dw_bytes_sent+=bytes_writen;
              if(dw_bytes_sent!=bytes_to_write) return(FALSE);
            }else{
                  ClearCommError(APPT()->hcomm,&dwerrorflag,&comstat);
                  return(FALSE);
            }
      }
if(send_ok) mark=true;
if(!send_ok) mark=false;      
return(mark);
}



int transfer::receive_msg(LPSTR lpszBlock, int nMaxLength)
{
BOOL fReadStat;
COMSTAT ComStat;
DWORD dwErrorFlags;
DWORD dwLength;
DWORD dwError;
//char szError[10];
OVERLAPPED osRead;
ClearCommError(APPT()->hcomm,&dwErrorFlags,&ComStat);
dwLength=min((DWORD)nMaxLength,ComStat.cbInQue);
if(dwLength>0)
{
      fReadStat=ReadFile(APPT()->hcomm,&lpszBlock,dwLength,&dwLength,&osRead);
      if(!fReadStat)
      {
            if(GetLastError()==ERROR_IO_PENDING)
            {
                  while(!GetLastError()==(APPT()->hcomm,&osRead,&dwLength,TRUE))
                  {
                        dwError=GetLastError();
                        if(dwError==ERROR_IO_INCOMPLETE)
                              continue;
                        else
                        {
                              ClearCommError(APPT()->hcomm,&dwErrorFlags,&ComStat);
                              break;
                        }
                  }
            }
            else
                  dwLength=0;
            ClearCommError(APPT()->hcomm,&dwErrorFlags,&ComStat);
      }
}

rec_data=lpszBlock;

 return(dwLength);

}
0
Comment
Question by:fari
1 Comment
 
LVL 6

Accepted Solution

by:
snoegler earned 200 total points
ID: 1170293
You are using - according to your code - overlapped io.
But you missed to specify FILE_FLAG_OVERLAPPED in your CreateFile() call, so the
OVERLAPPED structure you pass to WriteFile and ReadFile (oswrite) is not used except
the 'Offset' member of the OVERLAPPED structure - and even this one is not valid when
communicating with devices.
If your device supports the status lines like DTR and so on, you don't need to handle the
timeout delays as the device will reject and accept incoming bytes (same behavior when
it is sending). That means ReadFile() won't return until a byte is available, and WriteFile() won't
write a byte when the target buffer is full.

I would simply define these two functions:

BOOL ReadByte(HANDLE hCommFile,BYTE& theChar,DWORD minElapseTime)
{
  DWORD msPrev=::GetTickCount(),actualDelay;
  DWORD nBytesRead;
  ::ReadFile(hCommFile,&theChar,sizeof(BYTE),&nBytesRead,NULL);
  if(nBytesRead!=sizeof(BYTE)) // timeout error
    return FALSE;
  actualDelay=::GetTickCount()-msPrev;
  if( actualDelay<minElapseTime)
    Sleep(minElapseTime-actualDelay);
  return TRUE;
}

BOOL WriteByte(HANDLE hCommFile,BYTE theChar,DWORD minElapseTime)
{
  DWORD msPrev=::GetTickCount(),actualDelay;
  DWORD nBytesWritten;
  ::WriteFile(hCommFile,&theChar,sizeof(BYTE),&nBytesWritten,NULL);
  if(nBytesWritten!=sizeof(BYTE)) // timeout error or something
    return FALSE;
  actualDelay=::GetTickCount()-msPrev;
  if( actualDelay<minElapseTime)
    Sleep(minElapseTime-actualDelay);
  return TRUE;
}

These functions take the argument 'minElapseTime', and if the data is read or written faster
than this delay the functions wait until 'minElapseTime' has elapsed. If you set your
COMMTIMEOUTS to the appropriate values, the functions return FALSE if the delay has been
exceeded.
Of course you could use overlapped io, but then you have to watch for these things:
- specify FILE_FLAG_OVERLAPPED in the CreateFile()
- use the hEvent member of the OVERLAPPED structure:
   WaitForSingleEvent(oswrite->hEvent, theDelayInMsec);
   (The OVERLAPPED member 'hEvent' must be initialized before using
    CreateEvent() - If you don't know the event mechanism then post it, i think many experts
    can give you information on this)

And this is a tip: Structurize your code a bit more ... :)
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

685 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question