Serial port or usb port

Discussion in 'C' started by Andres, Feb 2, 2009.

  1. Andres

    Andres New Member

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    Is there such a code that can read serial ports or usb ports in real time? Some help please...
     
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    What operating system are you using?
     
  3. Andres

    Andres New Member

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    I am using windows xp
     
  4. Andres

    Andres New Member

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    for example, if i want to use this code to open a serial port, which libraries do i use?
    Code:
    using namespace std;
    
    int main()
    {
    HANDLE hComm;
    hComm = CreateFile( gszPort,  
                        GENERIC_READ | GENERIC_WRITE, 
                        0, 
                        0, 
                        OPEN_EXISTING,
                        FILE_FLAG_OVERLAPPED,
                        0);
    if (hComm == INVALID_HANDLE_VALUE)
       // error opening port; abort
    }
     
    Last edited by a moderator: Feb 4, 2009
  5. jayaraj_ev

    jayaraj_ev New Member

    Joined:
    Aug 29, 2007
    Messages:
    20
    Likes Received:
    2
    Trophy Points:
    0
    Occupation:
    Software engineer
    Location:
    Bangalore
    1 Opening the serial port
    Opening the serial port is very easy, especially if you’ve ever done Windows file I/O before. First, make sure you include windows.h. You can then use the following code to open it:
    HANDLE hSerial;
    hSerial = CreateFile("COM1",
    GENERIC_READ | GENERIC_WRITE,
    0,
    0,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    0);
    if(hSerial==INVALID_HANDLE_VALUE){
    if(GetLastError()==ERROR_FILE_NOT_FOUND){
    //serial port does not exist. Inform user.
    }
    //some other error occurred. Inform user.
    }

    So let’s walk through this. First, we declare a variable of type HANDLE and initialize it with a call to
    CreateFile. The first argument to CreateFile is simply the name of the file you want to open. In this
    case, we want to open a serial port, so we use "COM1", "COM2", etc. The next argument tells Windows whether you want to read or write to the serial port. If you don’t need to do one of these, just leave it out. Arguments 3 and 4 should pretty much always be 0. The next argument tells us that Windows should only open an existing file, and since serial ports already exist, this is what we want. After this comes FILE ATTRIBUTE NORMAL, which just tells Windows we don’t want anything fancy here. The final argument should also be zero.

    2 Setting Parameters
    So now that we have a HANDLE to the serial port, we need to set the parameters for it (baud rate, stop bits, etc).
    Windows does this through a struct called DCB:

    Code:
    DCB dcbSerialParams = {0};
    dcbSerial.DCBlength=sizeof(dcbSerialParams);
    if (!GetCommState(hSerial, &dcbSerialParams)) {
    //error getting state
    }
    dcbSerialParams.BaudRate=CBR_19200;
    dcbSerialParams.ByteSize=8;
    dcbSerialParams.StopBits=ONESTOPBIT;
    dcbSerialParams.Parity=NOPARITY;
    if(!SetCommState(hSerial, &dcbSerialParams)){
    //error setting serial port state
    }
    
    Once again, we’ll walk through this line-by-line. First, we create a variable of type DCB, clear all its
    fields, and set its size parameter (this is required due to a strange quirk of Windows). We then use the
    GetCommState function, which takes in our serial port handle and the DCB struct, to fill in the parameters currently in use by the serial port.
    Anyway, once we have this, we just need to set the parameters we care about. Notably, baud rate, byte size, stop bits, and parity. For whatever reason, Windows requires that we use special constants to specify the baud rate. These constants are pretty straightforward: CBR 19200 for 19200 baud, CBR 9600 for 9600 baud, CBR 57600 for 57600 baud, etc.
    Byte size we can just specify directly, but stop bits and parity once again require special constants. The options for StopBits are ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS. Similarly, the most commonly used options for Parity are EVENPARITY, NOPARITY, ODDPARITY. There are others, but these are quite obscure.

    See the MSDN library entry (do search for DCB) for full details.
    Similarly, there are loads of other fields in a DCB struct that you can use for some other more obscure
    serial parameters.
    After we’ve set up the DCB struct how we want it, we need to apply these setting to the serial port.
    This is accomplished with the SetCommState function.

    3 Setting timeouts
    One of the big problems with serial port communication is that if there isn’t any data coming into the serial port (if the serial port device gets disconnected or turned off, for example) then attempting to read from the port can cause your application to hang while waiting for data to show up. There are two ways of going about fixing this. First, you can use multithreading in your application with one thread dealing with the serial port stuff and the other doing the actual processing. This can get very messy and complex and really isn’t necessary. The other way is much simpler: just tell Windows not to wait for data to show up! This is accomplished quite simply:
    Code:
    COMMTIMEOUTS timeouts={0};
    timeouts.ReadIntervalTimeout=50;
    timeouts.ReadTotalTimeoutConstant=50;
    timeouts.ReadTotalTimeoutMultiplier=10;
    timeouts.WriteTotalTimeoutConstant=50;
    timeouts.WriteTotalTimeoutMultiplier=10;
    if(!SetCommTimeouts(hSerial, &timeouts)){
    //error occureed. Inform user
    }
    The COMMTIMEOUTS structure is pretty straightforward, and the above fields are the only ones it has.
    A quick rundown:
    • ReadIntervalTimeout specifies how long (in milliseconds) to wait between receiving characters before
    timing out.
    • ReadTotalTimeoutConstant specifies how long to wait (in milliseconds) before returning.
    • ReadTotalTimeoutMultiplier specifies how much additional time to wait (in milliseconds) before
    returning for each byte that was requested in the read operation.
    • WriteTotalTimeoutConstant and WriteTotalTimeoutMultiplier do the same thing, just for writes
    instead of reads.

    One special case that comes up pretty often: Setting ReadIntervalTimeout to MAXDWORD and both
    ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier to zero will cause any read operations to
    return immediately with whatever characters are in the buffer (ie, have already been received), even if there aren’t any.

    After we’ve setup the COMMTIMEOUTS structure how we want it, we need to apply the settings to the serial port using the SetCommTimeouts function.

    4 Reading/Writing data
    Alright, so once you have an open serial port with the correct parameters and timeouts, you can start doing the actual reads. These are extremely simple. Suppose we want to read n bytes from the serial port. Then we just do:

    Code:
    char szBuff[n + 1] = {0};
    DWORD dwBytesRead = 0;
    if(!ReadFile(hSerial, szBuff, n, &dwBytesRead, NULL)){
    //error occurred. Report to user.
    }
    
    ReadFile takes in a HANDLE to a file (our serial port in this case), a buffer to store the data in, the
    number of bytes to read, a pointer to an integer that will be set to the number of bytes actually read, and NULL.
    Note that dwBytesRead will contain the number of bytes actually read by the ReadFile operation.
    Writing data is exactly the same, except the function is called WriteFile.

    5 Closing down
    Once you’re done using the serial port, make sure you close the handle. If you don’t weird things can happen, like nobody else being able to access the serial port until you reboot. In any event, it’s really simple to do, so just remember to do it:

    Code:
    CloseHandle(hSerial);
     
  6. Andres

    Andres New Member

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    Thank you very much jayaraj ev...does this work with a microcontroller too...
    For example, lets say i programmed the microcontroller to send information to my computer via serial port, will your code receive the information and will i be able to manipulate it once i receive it with another program?
     
  7. Andres

    Andres New Member

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    I am having a problem with step 4 Reading/Writing part
    can you please help me...

    I get this error:
    'n' undeclared (first use this function)
    'szBuff' undeclared (first use this function)
     
  8. jayaraj_ev

    jayaraj_ev New Member

    Joined:
    Aug 29, 2007
    Messages:
    20
    Likes Received:
    2
    Trophy Points:
    0
    Occupation:
    Software engineer
    Location:
    Bangalore
    Hi,
    declare int n; first where you want to specify the no of bytes to be read.
     
  9. Andres

    Andres New Member

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    ok thanks i fixed it but now i get something else:
    variable-sized object 'szBuff' may not be initialized
     
  10. Andres

    Andres New Member

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    Do you know if there is a similar code for usb ports?
     
    Last edited: Feb 9, 2009

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice