title: correctly reading or writing serial port Windows API
body: <p>I have read alot of issues with serial port reading and writing. None so far have helped me figure out what my code is missing. The msdn example for c++ has undefined variables and missing brackets so although i can add brackets it still does not function. Here's what I've got at this point. It appears I can open the port and do the configuration but I cannot read a byte/char of data. I really just want a simple asyncronous serial read/write for aprogram to read from an Arduino.</p>
  
  <pre><code>class MY_SERIAL
  {
  
  HANDLE serialinstance;
  
  DWORD      dwStoredFlags;
  DWORD      dwRes;
  DWORD      dwCommEvent;
  OVERLAPPED osStatus = {0};
  BOOL       fWaitingOnStat;
  //dwStoredFlags = EV_BREAK | EV_CTS   | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR |      EV_RXFLAG | EV_TXEMPTY ;
  
  
  DCB dcb;
  COMMTIMEOUTS timeouts;
  
  COMMCONFIG serialconfig;
  
  
  
  public:
  char inBuffer[1000];
  char outBuffer[100];
  
  PDWORD noBytes;
  
  void close_serial()
  {
      CloseHandle(serialinstance);
  }
  //----------------------------------------------------
  bool open_serial(LPCSTR portNumber)   // serial port name use this format  "\\\\.\\COM10"
  {
  
      serialinstance = CreateFile(portNumber, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
      if(serialinstance == INVALID_HANDLE_VALUE)
      {
          int error = GetLastError();
          printf("ERROR opening serial port  %s\r\n", portNumber);
          if(error == 0x2){printf("ERROR_FILE_NOT_FOUND\r\n");}
          if(error == 0x5){printf("ERROR_ACCESS_DENIED\r\n");}
          if(error == 0xC){printf("ERROR_INVALID_ACCESS\r\n");}
          if(error == 0x6){printf("ERROR_INVALID_HANDLE\r\n");}
          printf("error code %d\r\n", error);
          return false;
      }
      if(GetCommState(serialinstance, &amp;dcb)!= true)
      {
          printf("ERROR getting current state of COM   %d \r\n", GetLastError());
          return false;
      }
      else{printf("debug   read current comstate\r\n");}
  
  
      FillMemory(&amp;dcb, sizeof(dcb), 0); //zero initialize the structure
      dcb.DCBlength = sizeof(dcb);      //fill in length
  
      dcb.BaudRate = CBR_115200;     //  baud rate
      dcb.ByteSize = 8;             //  data size, xmit and rcv
      dcb.Parity   = NOPARITY;      //  parity bit
      dcb.StopBits = ONESTOPBIT;
  
      if(SetCommState(serialinstance, &amp;dcb) != true)
      {
          printf("ERROR setting new state of COM   %d \r\n", GetLastError());
          return false;
      }
      else{printf("debug   set new comstate\r\n");}
      /*
      if (!BuildCommDCB("115200,n,8,1", &amp;dcb)) //fills in basic async details
      {
          printf("ERROR getting port comstate\r\n");
          return FALSE;
      }
      */
      if (!SetCommMask(serialinstance, EV_RXCHAR))
      {
          printf("ERROR setting new COM MASK   %d \r\n", GetLastError());
          return false;
      }
      else{printf("debug   commmask set\r\n");}
      timeouts.ReadIntervalTimeout = MAXDWORD;
      timeouts.ReadTotalTimeoutMultiplier = 20;
      timeouts.ReadTotalTimeoutConstant = 0;
      timeouts.WriteTotalTimeoutMultiplier = 0;
      timeouts.WriteTotalTimeoutConstant = 0;
  
      if (!SetCommTimeouts(serialinstance, &amp;timeouts))
      {
          printf("ERROR setting timeout parameters\r\n");
          return false;
      }
      else{printf("debug   timeouts set\r\n");}
      osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
      if (osStatus.hEvent == NULL)
      {// error creating event; abort
          printf("ERROR creating Serial EVENT\r\n");
          return false;
      }
      else{printf("debug   event created set\r\n");}
      osStatus.Internal = 0;
      osStatus.InternalHigh = 0;
      osStatus.Offset = 0;
      osStatus.OffsetHigh = 0;
      assert(osStatus.hEvent);
      printf("debug   com port setting complete\r\n");
  
  
  
  
  
  
      return true;
  }
  //---------------------------------------------------------
  
  bool read_serial_simple()
  {
      char m[1000];
      LPDWORD bytesRead;
  
  
  
      if (WaitCommEvent(serialinstance, &amp;dwCommEvent, &amp;osStatus))
      {
          if(dwCommEvent &amp; EV_RXCHAR)
          {
              ReadFile(serialinstance, &amp;m, 1, bytesRead, &amp;osStatus);
              printf("data read =   %d,       number bytes read =     %d  \r\n", m, bytesRead);
              return true;
          }
          else
          {
              int error = GetLastError();
              if(error == ERROR_IO_PENDING){printf(" waiting on incomplete IO\r\n");}
              else{printf("ERROR %d\r\n", error);}
              return false;
          }
      }
      return false;
  }
  
  };
  </code></pre>
  
  <p>So I stripped the read function down. I now get a char and it reports reading 1 byte but the value of the char is incorrect. I get a series of 48, 13, 10, and occasionally a 50 value for the byte. However the Arduino is sending a series a 0's then a 128 as verified with TerraTerm. What else do I need here?</p>
  
  <pre><code>bool read_serial_simple()
  {
      unsigned char m = 0;
      DWORD bytesRead;
      if(ReadFile(serialinstance, &amp;m, 1, &amp;bytesRead, &amp;osStatus) == true)
      {
          printf("data read =   %d,       number bytes read =     %d  \r\n", m, bytesRead);
          return true;
      }
      else{
          int error = GetLastError();
          if(error == ERROR_IO_PENDING){printf(" waiting on incomplete IO\r\n");}
          else{printf("ERROR %d\r\n", error);}
          return false;
      }
  
  }
  </code></pre>
  
  <p>So now I can read a byte of data but I cannot write a byte or more to the port. I just get ERROR_IO_PENDING. Can someone help out with this as well. Write function of my class below.</p>
  
  <pre><code>bool write(DWORD noBytesToWrite)
  {
      if(WriteFile(serialinstance, outBuffer, noBytesToWrite, NULL, &amp;osStatus) == true)
      {
          printf("message sent\r\n");
          return true;
      }
      else
      {
          int error = GetLastError();
          if(error != ERROR_IO_PENDING){LastError();}
          return false;
      }
  }
  </code></pre>
  
  <p>I'm calling both functions from main as follows</p>
  
  <pre><code>myserial.open_serial(COM12);
  myserial.outBuffer[0] = 'H';
  myserial.outBuffer[1] = 'e';
  myserial.outBuffer[2] = 'L';
  myserial.outBuffer[3] = 'l';
  myserial.outBuffer[4] = 'O';
  for(int n=0; n&lt;5; n++){printf("%c", myserial.outBuffer[n]);}
  printf("\r\n");
  
  while(1)
  {
      myserial.read();
      myserial.write(5);
      //system("PAUSE");
  }
  </code></pre>
  
  <p>Currently the arduino is set up to read bytes in and repeat them back to the pc. It is doing this fine on the arduino IDE serial monitor so now I just need to get this pc program to write out.</p>