Author Topic: Serial port in C in windows works only after using terminal program  (Read 1992 times)

0 Members and 2 Guests are viewing this topic.

Offline jmajaTopic starter

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: fi
There is something strange I can't figure out. Maybe someone can point the obvious mistake I'm making. I'm trying to read lines of serial data (100-110 bytes/line ASCII at 10 Hz at 115200) from my SAMD21 board via USB virtual port in Windows 7. It works just fine, IF I first open the port in e.g. Tera Term (even with wrong baud rate etc.) and then in my program. But if I don't use Tera Term after pluging the USB, I get no characters reading the COM port. No errors either.

So what does Tera Term do that I'm not doing to enable the data flow?

Here is how I open the port:
Code: [Select]
unsigned char open_port(HANDLE *hSerial, unsigned char port)
{
  DCB dcbSerialParams = {0};
  COMMTIMEOUTS timeouts={0};
  char com_port_name[30];

  sprintf(com_port_name, "\\\\.\\COM%d", port);
  *hSerial = CreateFile(com_port_name,
       GENERIC_READ | GENERIC_WRITE,
       0,
       NULL,
       OPEN_EXISTING,
       FILE_ATTRIBUTE_NORMAL,
       NULL);
  if(*hSerial==INVALID_HANDLE_VALUE)
    {
      if(GetLastError()==ERROR_FILE_NOT_FOUND)
printf("Port %s not found\n", com_port_name);
      else
printf("Error opening port\n");
      return 0;
    }
  dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
  if (!GetCommState(*hSerial, &dcbSerialParams))
    printf("Unable to get state\n");
  printf("Rate %ld\n",dcbSerialParams.BaudRate);
  dcbSerialParams.BaudRate=CBR_115200;
  dcbSerialParams.ByteSize=8;
  dcbSerialParams.StopBits=ONESTOPBIT;
  dcbSerialParams.Parity=NOPARITY;
  if(!SetCommState(*hSerial, &dcbSerialParams))
    printf("Unable to set state\n");
  if (!GetCommState(*hSerial, &dcbSerialParams))
    printf("Unable to get state\n");
  printf("Rate %ld\n",dcbSerialParams.BaudRate);

  timeouts.ReadIntervalTimeout=2;
  timeouts.ReadTotalTimeoutConstant=10;
  timeouts.ReadTotalTimeoutMultiplier=0;
  timeouts.WriteTotalTimeoutConstant=0;
  timeouts.WriteTotalTimeoutMultiplier=0;
  if(!SetCommTimeouts(*hSerial, &timeouts))
    printf("Unable to get state\n");
  return 1;
}

Here is how I read it:
Code: [Select]
double read_angle(HANDLE hSerial, DWORD *PZ)
{
   int i=0;
   double angle=-100.0, angle_new;
   DWORD dwBytesRead = 0, PZ_new;
   char szBuff[200];

   *PZ=0;
   if(!ReadFile(hSerial, szBuff, 200, &dwBytesRead, NULL))
     {
       printf("Unable to read\n");
       return -100;
     }
   while(i<dwBytesRead)
     {
       printf("%c", szBuff[i]);
       if(szBuff[i]=='Z' && ((i+5)< dwBytesRead) && (szBuff[i+1]==':'))
{
   if(sscanf(&szBuff[i+2],"%ld",&PZ_new)==1)
     {
       *PZ=PZ_new;
     }
}
       if(szBuff[i]=='e' && ((i+5)< dwBytesRead))
{
   if(sscanf(&szBuff[i+3],"%lf",&angle_new)==1)
     {
       angle=angle_new;
     }
}
       i++;
     }
   return angle;
}
 

Offline KE5FX

  • Super Contributor
  • ***
  • Posts: 1962
  • Country: us
    • KE5FX.COM
Maybe they turn on the DTR and/or DSR lines?  Some devices want that, some don't.
 

Offline Macman

  • Regular Contributor
  • *
  • Posts: 77
  • Country: gb
You need to set the flow control fields in the DCB and possibly also the RTS and CTS states if you are not using hardware flow control.
 

Offline jmajaTopic starter

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: fi
Thanks!

This was all I needed to add:

Code: [Select]
  if(EscapeCommFunction(*hSerial, SETDTR)==0)
    printf("Error Setting DTR\n");
 

Online abyrvalg

  • Frequent Contributor
  • **
  • Posts: 825
  • Country: es
This fix doesn´t cover all cases. You are still depending on some previously set parameters (i.e. enabled Xon/Xoff flow control can produce weird effects after receiving some specific bytes). For a full coverage don't do GetCommState() but fill entire DCB structure, setting all unused modes to FALSE/DISABLED:
https://msdn.microsoft.com/es-es/library/windows/desktop/aa363214(v=vs.85).aspx
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf