Solved

serial interface

Posted on 1998-08-14
1
411 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: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
  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 learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

792 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