Problem accessing serial port (9600 7-E-1)

Posted on 2006-05-20
Last Modified: 2012-05-05
I am writing a simple program which is intended to send short strings to a device i have attached to the serial port of my target machine. The simple program i have written seems to achieve this however the external device requires specific settings as follows.

9600 Baud, 7-bit data, 1 start bit, 1 stop bit, even parity.

After reading a number of samples off the web i decided on this code to set the relevant flags...

termio.c_cflag = B9600 | CS7 | PARENB | CLOCAL | CREAD;
tcflush(ttys0_fd, TCIFLUSH);
tcsetattr(ttys0_fd, TCSANOW, &termio);

I have tried every combination of c_flag settings that made sense from what i read but every time tcsetattr() is called with the specific settings the serial port seems to stop working all together and next time the program runs it cant even access the port.

When i let the program run with whatever default settings exist, i can send and receive strings no problem. What am i doing wrong? This has taken far longer than i had anticipated :(

Thanks in advance. Ill post the entire code if necessary.
Question by:HaL
    LVL 34

    Accepted Solution

    It's easier to do an stty -F {wanted device} {wanted characteristics} in the shell script before running the program.

    If you really must do it programmatically:-

    You should always read the current settings into your struct termios, and then modify the ones you care about. Also always use struct termios, not the old struct termio.

       struct termios termio;

       if (tcgetattr(ttys0_fd, &termio)) {perror("tcgetattr");exit(1);}

    Use cfset[io]speed to set speeds:

       if (cfsetospeed(&termio, B9600)) {perror("cfsetospeed");exit(1);}
       if (cfsetispeed(&termio, B9600)) {perror("cfsetispeed");exit(1);}

    Clear bits you don't want:

       termio.c_cflag &= ~(CSIZE | CSTOPB | CRTSCTS | PARODD);  

    Set the bits you want:

       termio.c_cflag |= CS7 | PARENB | CLOCAL | CREAD;

    (I added clearing of CRTSCTS hardware flow control).
    After your tcsetattr(), you should do a tcgetattr() to another struct termios and compare it for equality with the first one, to ensure all the facilities you requested were set.


    Author Comment

    Thanks a lot for the example. This is exactly what i was looking for and it works a treat. It seems that serial devices are a little more touchy than i had previously though, at least in Linux anyway.

    I was wondering why cfsetospeed() is used to set the speed instead of adding the B9600 flag directly to the c_cflag property. Perhaps to prevent multiple speeds being applied?

    Thanks again, the points are yours.
    LVL 34

    Expert Comment

    by:Duncan Roe
    Thanks Hal. To answer your question - in "man termios" see
    "(POSIX  says  that  the  baud  speed  is stored in the termios structure without specifying where precisely, and provides cfgetispeed() and cfsetispeed() for getting at it. Some systems use bits selected by CBAUD in c_cflag, other systems use separate fields, e.g.  sg_ispeed and sg_ospeed.)"

    Featured Post

    Threat Intelligence Starter Resources

    Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

    Join & Write a Comment

    The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
    The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…
    Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

    729 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now