Solved

serial interface

Posted on 1998-08-14
1
396 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
Comment Utility
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

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Suggested Solutions

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
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…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

771 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now