Thread: Windows Serial programming

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    16

    Windows Serial programming

    I need to program some software to be able to send and receive serial msgs. I've looked at a lot of places on the net, and on MSDN, and here is some code i got from most places on the net.

    Code:
    #include	<windows.h>
    #include	<stdlib.h>
    #include	<stdio.h>
    #include	<string.h>
    #include	<commdlg.h>
    //#include	<windef.h>
    
    int nread,nwrite;
    
    
    void main()
    {
    	HANDLE hSerial;
    	COMMTIMEOUTS timeouts;
    	COMMCONFIG dcbSerialParams;
    	char *words, *buffRead, *buffWrite;
    	DWORD dwBytesWritten, dwBytesRead;
    
    	hSerial = CreateFile("COM9",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    
    	if ( hSerial == INVALID_HANDLE_VALUE) 
    	{
    		if (GetLastError() == ERROR_FILE_NOT_FOUND)
    		{
    			printf(" serial port does not exist \n");
    		}
    		printf(" some other error occured. Inform user.\n");
    	}
    
    
    	//DCB	 dcbSerialParams ;
    	//GetCommState( hSerial, &dcbSerialParams.dcb);
    	if (!GetCommState(hSerial, &dcbSerialParams.dcb)) 
    	{
    		printf("error getting state \n");
    	}
    
    	dcbSerialParams.dcb.DCBlength = sizeof(dcbSerialParams.dcb);
    
    
    	dcbSerialParams.dcb.BaudRate = CBR_9600;
    	dcbSerialParams.dcb.ByteSize = 8;
    	dcbSerialParams.dcb.StopBits = ONESTOPBIT;
    	dcbSerialParams.dcb.Parity = NOPARITY;
    
    	dcbSerialParams.dcb.fBinary = TRUE;
    	dcbSerialParams.dcb.fDtrControl = DTR_CONTROL_DISABLE;
    	dcbSerialParams.dcb.fRtsControl = RTS_CONTROL_DISABLE;
    	dcbSerialParams.dcb.fOutxCtsFlow = FALSE;
    	dcbSerialParams.dcb.fOutxDsrFlow = FALSE;
    	dcbSerialParams.dcb.fDsrSensitivity= FALSE;
    	dcbSerialParams.dcb.fAbortOnError = TRUE;
    
    	if (!SetCommState(hSerial, &dcbSerialParams.dcb)) 
    	{
    		printf(" error setting serial port state \n");
    	}
    
    
    	GetCommTimeouts(hSerial,&timeouts);
    	//COMMTIMEOUTS timeouts = {0};
    
    	timeouts.ReadIntervalTimeout = 50;
    	timeouts.ReadTotalTimeoutConstant = 50;
    	timeouts.ReadTotalTimeoutMultiplier = 10;
    	timeouts.WriteTotalTimeoutConstant = 50;
    	timeouts.WriteTotalTimeoutMultiplier= 10;
    
    	if(!SetCommTimeouts(hSerial, &timeouts)) 
    	{
    		printf("error setting port state \n");
    	}
    
    
    
    
    
    	//****************Write Operation*********************//
    	words = "This is a string to be written to serial port COM1";
    	nwrite = strlen(words);
    
    	buffWrite = words;
    	dwBytesWritten = 0;
    
    	if (!WriteFile(hSerial, buffWrite, nwrite, &dwBytesWritten, NULL)) 
    	{ 
    		printf("error writing to output buffer \n");
    	}
    //printf("Data written to write buffer is \n %s \n",buffWrite);
    
    
    
    //***************Read Operation******************//
    	//buffRead = 0;
    	dwBytesRead = 0;
    	nread = strlen(words);
    
    	if (!ReadFile(hSerial, buffRead, nread, &dwBytesRead, NULL)) 
    	{
    		printf("error reading from input buffer \n");
    	}
    	printf("Data read from read buffer is \n %s \n",buffRead);
    
    
    	CloseHandle(hSerial);
    
    }
    Then I found this while searching the forums.
    RS-232 for Linux and WIN32
    Its a library for Linux and Win32 RS-232. Even with that I cant open a serial port and I get an error. I've tested the port with hyperterminal and even restarted my PC thinking that hyperterminal didnt close the port properly. I'm using a USB-to-serial adapter and it comes up as a serial port in device manager.
    I am doing this all on Win7x64. Is that the problem? But all the software compiles perfectly. It just doesnt seem to open the port on my software, either using the code above, or the libraries.

    EDIT: My USB-to-serial adapter is COM9, and my Arduino board is COM6. I just plugged in the Arduino board, and the software cant even open COM6.
    Last edited by yohanevindra; 09-19-2011 at 10:03 AM.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Exactly which error messages is it printing?

    Unless you have 8 other com ports it's unlikely your device is COM9:

    You need to look up each of your file functions on msdn and make sure your syntax is correct. Especially the Read() and Write() functions...

    Also after each error message your code should abort... not fall into the next error message.
    Last edited by CommonTater; 09-19-2011 at 10:08 AM.

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    16
    When I run my code, it starts of with the "serial port does not exist" error. And then even when I run the library (for which I inserted the link) it gives the error "unable to open the com port". I've tried different COM port numbers and its all the same.

    In device manager, my USB-to-serial adapter comes up, and it says COM9 next to it, so I'm guessing it is COM9. I've seen a few places where you need to use the device name but I thought that was only if the COM value was greater than 10. How do you refer to the device name in code?especially when you're trying to open a COM port?

    My Read and Write codes are correct. My main problem lies in the fact that I cant open a COM port, with my code, or even the RS-232 library.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    I have no idea... I found a pdf file that has what appears to be your code in it, but even that doesn't help.

    My best guess is that your usb comport isn't working properly.
    Last edited by CommonTater; 09-19-2011 at 01:52 PM.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Have you tried to communicate using Hyperterminal? Using Hyperterminial you should be able to use the File Properties connect using box to determine the available com ports.

    Jim

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    16
    I can communicate perfectly on hyperterminal. when i connect the TX and RX pins together, I get what i typed..

    the code that you found in that pdf is what is around the net..plus there's that library that I found, which basically uses kind of the same code..

    assume my code is wrong, but then even the library of serial com in the link above doesnt work.

    RS-232 for Linux and WIN32

    do you know another way of referencing the com port rather than using its number?using its device name?

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I can communicate perfectly on hyperterminal. when i connect the TX and RX pins together, I get what i typed..
    What com port is Hyperterminal using?

    Is the com port the same as your program?

    Can you communicate with your development board using Hyperterminal?

    If you are still getting the:
    When I run my code, it starts of with the "serial port does not exist" error.
    make sure that no other program is running that is trying to access the serial port. I believe Windows will not normally allow two programs to try to access the port at the same time.

    Jim

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    16
    Quote Originally Posted by jimblumberg View Post
    What com port is Hyperterminal using?

    Is the com port the same as your program?
    Hyperterminal is using the same COM port since I have only this one USB-to-serial adapter.

    Quote Originally Posted by jimblumberg View Post
    Can you communicate with your development board using Hyperterminal?
    Yes..my development board can communicate with Hyperterminal

    Quote Originally Posted by jimblumberg View Post
    If you are still getting the:
    make sure that no other program is running that is trying to access the serial port. I believe Windows will not normally allow two programs to try to access the port at the same time.
    Jim
    I'm assuming that hyperterminal closes the port after using it.. I even restarted my computer, and then immediately ran my software, and still I got the same error...

    I cant find it now, but I remember coming across a thread on a forum for Arduino, where it seemed a solution was to use the device name rather than "COM9".. how do I get the device name for the COM port?

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by yohanevindra View Post
    I cant find it now, but I remember coming across a thread on a forum for Arduino, where it seemed a solution was to use the device name rather than "COM9".. how do I get the device name for the COM port?
    Here... let me google that for you....

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    CreateFile function (Windows)
    Scroll down to "Communications Resources".

    You're not initializing your DCB properly: Configuring a Communications Resource (Windows)
    Notice they don't use FILE_ATTRIBUTE_NORMAL either.

    You're not setting "dcb.fParity".

    >> dcb.fAbortOnError = TRUE;
    Do you really want to call ClearCommError() every time there's an error?

    gg

  11. #11
    Registered User
    Join Date
    May 2010
    Posts
    16
    Code:
    HANDLE Cport[16];
    
    
    char comports[16][10]={"\\\\.\\COM1",  "\\\\.\\COM2",  "\\\\.\\COM3",  "\\\\.\\COM4",
                           "\\\\.\\COM5",  "\\\\.\\COM6",  "\\\\.\\COM7",  "\\\\.\\COM8",
                           "\\\\.\\COM9",  "\\\\.\\COM10", "\\\\.\\COM11", "\\\\.\\COM12",
                           "\\\\.\\COM13", "\\\\.\\COM14", "\\\\.\\COM15", "\\\\.\\COM16"};
    
    char baudr[64];
    
    
    int OpenComport(int comport_number, int baudrate)
    {
      if((comport_number>15)||(comport_number<0))
      {
        printf("illegal comport number\n");
        return(1);
      }
    
      switch(baudrate)
      {
        case     110 : strcpy(baudr, "baud=110 data=8 parity=N stop=1");
                       break;
        case     300 : strcpy(baudr, "baud=300 data=8 parity=N stop=1");
                       break;
        case     600 : strcpy(baudr, "baud=600 data=8 parity=N stop=1");
                       break;
        case    1200 : strcpy(baudr, "baud=1200 data=8 parity=N stop=1");
                       break;
        case    2400 : strcpy(baudr, "baud=2400 data=8 parity=N stop=1");
                       break;
        case    4800 : strcpy(baudr, "baud=4800 data=8 parity=N stop=1");
                       break;
        case    9600 : strcpy(baudr, "baud=9600 data=8 parity=N stop=1");
                       break;
        case   19200 : strcpy(baudr, "baud=19200 data=8 parity=N stop=1");
                       break;
        case   38400 : strcpy(baudr, "baud=38400 data=8 parity=N stop=1");
                       break;
        case   57600 : strcpy(baudr, "baud=57600 data=8 parity=N stop=1");
                       break;
        case  115200 : strcpy(baudr, "baud=115200 data=8 parity=N stop=1");
                       break;
        case  128000 : strcpy(baudr, "baud=128000 data=8 parity=N stop=1");
                       break;
        case  256000 : strcpy(baudr, "baud=256000 data=8 parity=N stop=1");
                       break;
        default      : printf("invalid baudrate\n");
                       return(1);
                       break;
      }
    
      Cport[comport_number] = CreateFileA(comports[comport_number+1],
                          GENERIC_READ|GENERIC_WRITE,
                          0,                          /* no share  */
                          NULL,                       /* no security */
                          OPEN_EXISTING,
                          0,                          /* no threads */
                          NULL);                      /* no templates */
    
      if(Cport[comport_number]==INVALID_HANDLE_VALUE)
      {
        printf("unable to open comport\n");
        return(1);
      }
    
      DCB port_settings;
      memset(&port_settings, 0, sizeof(port_settings));  /* clear the new struct  */
      port_settings.DCBlength = sizeof(port_settings);
    
      if(!BuildCommDCBA(baudr, &port_settings))
      {
        printf("unable to set comport dcb settings\n");
        CloseHandle(Cport[comport_number]);
        return(1);
      }
    
      if(!SetCommState(Cport[comport_number], &port_settings))
      {
        printf("unable to set comport cfg settings\n");
        CloseHandle(Cport[comport_number]);
        return(1);
      }
    
      COMMTIMEOUTS Cptimeouts;
    
      Cptimeouts.ReadIntervalTimeout         = MAXDWORD;
      Cptimeouts.ReadTotalTimeoutMultiplier  = 0;
      Cptimeouts.ReadTotalTimeoutConstant    = 0;
      Cptimeouts.WriteTotalTimeoutMultiplier = 0;
      Cptimeouts.WriteTotalTimeoutConstant   = 0;
    
      if(!SetCommTimeouts(Cport[comport_number], &Cptimeouts))
      {
        printf("unable to set comport time-out settings\n");
        CloseHandle(Cport[comport_number]);
        return(1);
      }
    
      return(0);
    }
    
    
    int PollComport(int comport_number, unsigned char *buf, int size)
    {
      int n;
    
      if(size>4096)  size = 4096;
    
    /* added the void pointer cast, otherwise gcc will complain about */
    /* "warning: dereferencing type-punned pointer will break strict aliasing rules" */
    
      ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL);
    
      return(n);
    }
    
    
    int SendByte(int comport_number, unsigned char byte)
    {
      int n;
    
      WriteFile(Cport[comport_number], &byte, 1, (LPDWORD)((void *)&n), NULL);
    
      if(n<0)  return(1);
    
      return(0);
    }
    
    
    int SendBuf(int comport_number, unsigned char *buf, int size)
    {
      int n;
    
      if(WriteFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL))
      {
        return(n);
      }
    
      return(-1);
    }
    
    
    void CloseComport(int comport_number)
    {
      CloseHandle(Cport[comport_number]);
    }
    
    
    int IsCTSEnabled(int comport_number)
    {
      int status;
    
      GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status));
    
      if(status&MS_CTS_ON) return(1);
      else return(0);
    }
    
    
    #endif
    
    
    void cprintf(int comport_number, const char *text)  /* sends a string to serial port */
    {
      while(*text != 0)   SendByte(comport_number, *(text++));
    }
    This is part of the code from the RS-232 library, and as can be seen, it does use the device name. I am a bit unclear as to how they set the DCB settings, but the main issue here is, it does not open the COM port, inspite of its existence. And I've checked this code also, and its correct (as far as I can see)

    Does anyone else have any working code or something that I can check this with?

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Call GetLastError() to get the reason why CreateFile() failed.

    What is the make/model of your USB-to-serial adapter?

    You say you are using hyperterminal, but that doesn't come with Win7. So what are you using?

    gg

  13. #13
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Before you ask for help at least RUN the code. Clearly you have just found it on the 'net and asked us to fix it.

    Quote Originally Posted by yohanevindra View Post
    Code:
    char comports[16][10]={"\\\\.\\COM1",  "\\\\.\\COM2",  "\\\\.\\COM3",  "\\\\.\\COM4",
                           "\\\\.\\COM5",  "\\\\.\\COM6",  "\\\\.\\COM7",  "\\\\.\\COM8",
                           "\\\\.\\COM9",  "\\\\.\\COM10", "\\\\.\\COM11", "\\\\.\\COM12",
                           "\\\\.\\COM13", "\\\\.\\COM14", "\\\\.\\COM15", "\\\\.\\COM16"};
    Error number 1, buffer overruns because those 16 strings require 11 chars (+1 for the terminator character)


    Quote Originally Posted by yohanevindra View Post
    Code:
      if((comport_number>15)||(comport_number<0))
      {
        printf("illegal comport number\n");
        return(1);
      }
    Error number 2. 0 is not a vaild com port number and you array contains values greater than 15

    Quote Originally Posted by yohanevindra View Post
    Code:
      Cport[comport_number] = CreateFileA(comports[comport_number+1],
    Error number 3. Possible buffer over-run or wrong COM port opened.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. programming serial.data
    By cbrandy in forum C Programming
    Replies: 1
    Last Post: 02-21-2011, 04:46 AM
  2. Serial Programming the Win32 api
    By Hexagram1000 in forum Windows Programming
    Replies: 5
    Last Post: 07-18-2008, 08:16 PM
  3. clearing windows serial port allocations
    By cnewb999 in forum C Programming
    Replies: 0
    Last Post: 06-29-2008, 02:47 AM
  4. Serial Programming
    By gvector1 in forum Networking/Device Communication
    Replies: 3
    Last Post: 07-16-2003, 06:32 PM
  5. Serial programming
    By stovellp in forum C++ Programming
    Replies: 6
    Last Post: 01-20-2003, 12:29 PM