Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

serial interface

Posted on 1998-08-14
1
Medium Priority
?
417 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 400 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

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

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

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
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 how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

971 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