none
Serial communication not working. ReadFile() has a problem.

    Question

  • Hi All,

    Currently I try to use serial communication (XBee) to communicate between the PC and the robot via vc++. I have done the same thing via MATLAB. So there is no problem for the hardware.

    After I write commands to poll data, I can not receive any data. The interface requirement is: 

    Baudrate: 57600
    Flow control: ”Hardware” for XBee, ”None” for
    USB cable adapter
    Databits: 8, 1 startbit, 1 stopbit, no parity

    Please give me your help.

    // This is the main DLL file.
    #include "StdAfx.h"
    #include <iostream>
    #define WIN32_LEAN_AND_MEAN //for GetCommState command
    #include "Windows.h"
    #include <WinBase.h>

    using namespace std;

    int main(){
      
      char init[]="";

      HANDLE serialHandle;

      // Open serial port
      serialHandle = CreateFile("\\\\.\\COM8", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    // Do some basic settings
      DCB serialParams;
      DWORD written;
      DWORD read;
      char buffer[1];
      char data[103];
      int t=0;
      int jj=0;
      //serialParams.DCBlength = sizeof(serialParams);

      if((GetCommState(serialHandle, &serialParams)==0))
      {
    printf("Get configuration port has a problem.");
        return FALSE;
       }

       GetCommState(serialHandle, &serialParams);
       serialParams.BaudRate = CBR_57600;
       serialParams.ByteSize = 8;
       serialParams.StopBits = ONESTOPBIT;
       serialParams.Parity = NOPARITY;

       //set flow control="hardware"
       serialParams.fOutX=false;
       serialParams.fInX=false;
       serialParams.fOutxCtsFlow=true;
       serialParams.fOutxDsrFlow=true;
       serialParams.fDsrSensitivity=true;
       serialParams.fRtsControl=RTS_CONTROL_HANDSHAKE;
       serialParams.fDtrControl=DTR_CONTROL_HANDSHAKE;
       //suggest to apply
       //serialParams.fBinary=true;
       //serialParams.fParity=true;

       if (!SetCommState(serialHandle, &serialParams))
       {
      printf("Set configuration port has a problem.");
           return FALSE;

       }


       GetCommState(serialHandle, &serialParams);

       // Set timeouts
      COMMTIMEOUTS timeout = { 0 };
      timeout.ReadIntervalTimeout = 100;
       timeout.ReadTotalTimeoutConstant = 100;
       timeout.ReadTotalTimeoutMultiplier = 100;
       timeout.WriteTotalTimeoutConstant = 100;
       timeout.WriteTotalTimeoutMultiplier = 100;

       SetCommTimeouts(serialHandle, &timeout);

       if (!SetCommTimeouts(serialHandle, &timeout))
       {
      printf("Set configuration port has a problem.");
           return FALSE;

       }
       

    bool err1;
       
       //clear the buffer
    PurgeComm(serialHandle,PURGE_RXCLEAR);


      //write >*>p0x0004 to poll IMU_CalcData from robot
       
    BYTE test[]={62,42,62,112,4};
        WriteFile(serialHandle, test,5,&written,NULL);
     
      do {
    data[jj]=0;
    err1=ReadFile (serialHandle,&data[jj],1,&read, NULL);
    cout<<read;
    cout<<(int)data[jj];
    cout<<err1;
        cout<<"\n";
    if (read!=0) 
    {
      jj++;
       
    }
    t++;
    Sleep(10);
     } while (t<100); 
       
       CloseHandle(serialHandle);
       
       return 0;
    }







    • Edited by AmoodZ Friday, January 10, 2014 9:23 PM
    Friday, January 10, 2014 4:56 PM

Answers

  • David : That is why I said to use Async which is an event.  There are two basic type of applications

    1) Master/Slave : The client sends a command requesting data and the server responds.  Normally the responses are fixed size and you won't have an issue with buffer size, but may run into a timing issue if microprocessor can't handle the amount of data and speed of the response.  The UART in the PC doesn't have a large buffer so the PC has to empty the UART buffer before it over flows.  Handshaking also depends on the instrument to recognize the handshaking and a lot of devices don't handle the handshaking correctly.  So even if you did use handshaking you will still get error with some devices.

    For simply interfaces the Read method will work properly when the PC isn't busy doing a lot of processing and when the data rate and amount of data is small.  In all other cases using Asyn Method I have always gotten the code to run error free using Async provided there wasn't bugs in the device I connected to.  I have seen a lot of kludgy code because people were trying to use the PC to fix bugs in devices.

    2) Chat applications and devices that constantly sends data : Both these type applications should use Async.  Chat applications because you can read and write simultaneously.  Constant read applications because you need to do other processing in the PC while the data is being received. 


    jdweng

    Monday, January 13, 2014 7:23 AM
  • Disable both hardware and software handshaking.  It is obsolete.  Also take out any timing code it is also problematic.  Instead if you have problems intermittent data errors use async read (using events) instead of Read.  I've been writing programs like this for 40 years and know serial communications extremely well.


    jdweng

    Saturday, January 11, 2014 11:05 AM

All replies

  • Disable both hardware and software handshaking.  It is obsolete.  Also take out any timing code it is also problematic.  Instead if you have problems intermittent data errors use async read (using events) instead of Read.  I've been writing programs like this for 40 years and know serial communications extremely well.


    jdweng

    Saturday, January 11, 2014 11:05 AM
  • Disable both hardware and software handshaking.  It is obsolete.  Also take out any timing code it is also problematic.  Instead if you have problems intermittent data errors use async read (using events) instead of Read.  I've been writing programs like this for 40 years and know serial communications extremely well.


    jdweng

    Thanks for your reply. I am a c++ newbie. Could you provide me more details? Do you mean I should commend out all the flow control set part and timeouts set part? Is there any sample for Async Read I can learn from? BTW, I am running it in the Windows environment.
    Saturday, January 11, 2014 9:15 PM
  • Handshaking is obsolete?  How is that possible?  Even using events, Windows it not a real time OS and thus your code is not guaranteed to run in any finite time period.  If your read code is pre-empted for whatever reason, without handshaking the source will continue to send and eventually overrun any buffer you might have? 
     
    I might well be wrong, but if I am, I want to know why.
     
    Thanks,
    David
    Monday, January 13, 2014 5:25 AM
  • David : That is why I said to use Async which is an event.  There are two basic type of applications

    1) Master/Slave : The client sends a command requesting data and the server responds.  Normally the responses are fixed size and you won't have an issue with buffer size, but may run into a timing issue if microprocessor can't handle the amount of data and speed of the response.  The UART in the PC doesn't have a large buffer so the PC has to empty the UART buffer before it over flows.  Handshaking also depends on the instrument to recognize the handshaking and a lot of devices don't handle the handshaking correctly.  So even if you did use handshaking you will still get error with some devices.

    For simply interfaces the Read method will work properly when the PC isn't busy doing a lot of processing and when the data rate and amount of data is small.  In all other cases using Asyn Method I have always gotten the code to run error free using Async provided there wasn't bugs in the device I connected to.  I have seen a lot of kludgy code because people were trying to use the PC to fix bugs in devices.

    2) Chat applications and devices that constantly sends data : Both these type applications should use Async.  Chat applications because you can read and write simultaneously.  Constant read applications because you need to do other processing in the PC while the data is being received. 


    jdweng

    Monday, January 13, 2014 7:23 AM
  • Thanks for the additional info, Joel.  A few years ago I was faced with writing code using a FTDI USB serial port, the device connected to it did not implement handshaking, and I tried all possible manner of Windows serial port mechanisms (including polling, events, and completion ports) to achieve error free transfer and did not succeed.  

    I could always lose data when e.g. causing the PC to access data on a hard drive which had spun down.  It seems when the hard drive was spinning up, the entire PC was frozen including my serial port code.  Also, in low memory situations, your code might be paged out and need to be paged in to handle the event.  While this is happening, you could lose data.  This is what I meant that Windows has never been a real time OS and if there is no mechanism to halt the data being sent (handshaking), you will eventually lose data.

    So how do you prevent data loss in this case?

    Thanks,
    David

    Monday, January 13, 2014 6:01 PM