3
votes

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.

2
Are you sure the other end isn't actually sending at 110 baud? 100 baud is basically unheard of.David Schwartz

2 Answers

6
votes

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.

0
votes

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)