3

I am looking to know if it is possible to read from a serial port at 100 baud rate. As per termio.h there is no provision to set 100 as baud rate. I am working in Linux. The communicating device on the other end is sending data at 100 baud rate and it is fixed. I would like to know if my baud rate is set to 110, would it guarantee that the data I am receiving is correct? or is there any solution for this?

Kindly guide.

Mike
  • 47,263
  • 29
  • 113
  • 177
user_abh
  • 357
  • 3
  • 6
  • 20

2 Answers2

6

You're actually in luck. 100 baud is low enough that you can compute a divisor that will do it (1,152) with typical 16450-compatible serial ports (which is pretty much what everything is) and linux supports custom divisors with the spd_cust parameter to setserial.

Community
  • 1
  • 1
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • thank you for your point. Is there a command in linux to know the clock speed of the serial? thank you.. i was checking this- http://www.connecttech.com/KnowledgeDatabase/kdb309.htm – user_abh Sep 27 '12 at 09:38
  • 1
    Pretty much every PC that has an included serial port has a [16550A-compatible port with a 1.8432MHz clock](http://www.lammertbies.nl/comm/info/serial-uart.html). This makes the correct divisor for you 1,152. – David Schwartz Sep 27 '12 at 09:51
  • Thank you. I seem to be successful in customizing to 100 baud. Could you let me know how I can confirm programatically that 100 has been set? I used cfgetospeed() which outputs 15 everytime(irrespective of baud rate set). – user_abh Oct 08 '12 at 06:50
  • 1
    There's no good way you can. I don't know of any way to directry read the baud rate. If you have an oscilloscope, you can measure a constant stream of `0x55` bytes and measure the pulse width. – David Schwartz Oct 08 '12 at 06:57
0

Hmmm.... 110 bps is unique among serial port speeds in that it conventionally has two stop bits (all other speeds use one stop bit), so that sending one character requires 10 bits for 7-bit data, or 11 bits for 8-bit data.

If the communication protocol was communicated as ten characters per second and someone ignorant of 1950s protocols might convert cps to baud by assuming only one stop bit and 8-bit data, they would conclude that 100 baud is the result.

If the custom setting for a true 100 baud doesn't work, try setting standard 110 baud.

Excerpted from a related answer:

#include <errno.h>
#include <termios.h>
#include <unistd.h>

int
set_interface_attribs (int fd, int speed, int parity)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                error_message ("error %d from tcgetattr", errno);
                return -1;
        }

        cfsetospeed (&tty, speed);
        cfsetispeed (&tty, speed);

        tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
        if (speed == B110)
            tty.c_cflag |= CSTOPB;      // 2 stop bits for 110

        // disable IGNBRK for mismatched speed tests; otherwise receive break
        // as \000 chars
        tty.c_iflag &= ~IGNBRK;         // ignore break signal
        tty.c_lflag = 0;                // no signaling chars, no echo,
                                        // no canonical processing
        tty.c_oflag = 0;                // no remapping, no delays
        tty.c_cc[VMIN]  = 0;            // read doesn't block
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

        tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

        tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
                                        // enable reading
        tty.c_cflag &= ~(PARENB | PARODD);      // shut off parity
        tty.c_cflag |= parity;
        tty.c_cflag &= ~CSTOPB;
        tty.c_cflag &= ~CRTSCTS;

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
        {
                error_message ("error %d from tcsetattr", errno);
                return -1;
        }
        return 0;
}

void
set_blocking (int fd, int should_block)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                error_message ("error %d from tggetattr", errno);
                return;
        }

        tty.c_cc[VMIN]  = should_block ? 1 : 0;
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
                error_message ("error %d setting term attributes", errno);
}


...
char *portname = "/dev/ttyUSB1"
 ...
int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0)
{
        error_message ("error %d opening %s: %s", errno, portname, strerror (errno));
        return;
}

set_interface_attribs (fd, B110, 0);  // set speed to 115,200 bps, 8n2 (no parity)
Community
  • 1
  • 1
wallyk
  • 56,922
  • 16
  • 83
  • 148