Receive serial data

From: Anders Christensen (andersc1_at_hotmail.com)
Date: 02/23/05


Date: Wed, 23 Feb 2005 00:02:34 +0100

Hi, I have problem receiving serialdata.
First a short describtion of the context in which I experience the
problem: I have a barcodescanner connected to my PC via a RS-232/RS-485
network using ICP CON modules 7520 and 7522. The purpose of this network
is to be able to use several RS-232-devices from one serialport. From my
PC I have only one serialport open which connects to the 7520-module.
Reading and writing the different RS-232-devices is a matter of
sending an appropriate command telling the 7520-module to read/write which
serialbuffer. The manufactor of the ICP CON modules has made a function
for that under Linux; i7k_send_readt().

Now on to the actual problem
I can from my PC read the serialbuffer of the barcodescanner, but
sometimes one barcode is splitted into several reads. And sometimes a
<CR> is received as the first character of the barcode. What can I do to
avoid this?

Below I paste
1) A print from the terminal to illustrate the problem
2) The source-code of my test-main
3) The function sio_open

Hope that someone has an idea on what the problem might be. I'd be glad to
hear any suggestion.

./Anders.

________________Print from the terminal:
[root@dhcp231 examples]# ./send_read
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=8: 48 48 57 51 54 54 48 13
r=6: 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=5: 48 48 57 51 13
r=9: 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=6: 48 48 57 51 54 13
r=8: 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=14: 10 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 48 48 57 51 54 54 48 48 48 49 57 54 13
r=14: 10 48 48 57 51 54 54 48 48 48 49 57 54 13
r=14: 10 48 48 57 51 54 54 48 48 48 49 57 54 13
r=13: 10 48 48 57 51 54 54 48 48 48 49 57 13

________________Source-code of my test-main:
#include "i7k.h"

#define RCVBUF_SIZE 128

int main()
{
        int fd;/* file descriptor */
        char *cmd;/* point to command string */
        char rbuf[RCVBUF_SIZE];/* receive buffer */
        __tod_t texp;/* to receive the expended time */
        int r, i;

        fd = sio_open("/dev/ttyS0", B9600, DATA_BITS_8, NO_PARITY,
                                  ONE_STOP_BIT);
        if (fd == ERR_PORT_OPEN) {
                printf("open port failed!\n");
                return (-1);
        }

        cmd = "$01U\r"; //command for reading from my barcode-buffer

        while(1) {
                usleep(100000);
                r = i7k_send_readt(fd, cmd, rbuf, RCVBUF_SIZE-1, &texp);
                if (r>2) {
                        printf("r=%i: ",r);
                        for (i=0;i<r;i++) printf("%i ", (int)rbuf[i]);
                        printf("\n");
                }
        }
        sio_close(fd);
        return (0);
}

________________Function sio_open:
/**********************************************************************
 * sio_open
 *
 * Open and initiate serial port
 * default open port in noncanonical mode
 *
 * Arguments:
 * port a string point to the name of serial device,
 * such as "/dev/ttyS0"
 * baud B0, B50... B9600, B19200, B38400...
 * data Data bit(s), unsigned char
 * parity Parity, unsigned char
 * stop Stop bit(s), unsigned char
 *
 * Returned:
 * This function returns int port descriptor for the port opened
 * successfully. Return value ERR_PORT_OPEN if failed.
 *
 **********************************************************************/
int
sio_open(const char *port, speed_t baud, tcflag_t data, tcflag_t parity,
                 tcflag_t stop)
{
        struct sio *sio; /* point to current sio structure */

        int fd; /* file descriptor for current port */
        int r;

        struct termios *options; /* options for current port */

        PDEBUG("sio_open: start\n");

  /***************
   * open port *
   ***************/
        fd = _sio_device(port);
        if (fd == 0) { /* device is not yet opened, so, open it */
                // fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
                fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
        }
        PDEBUG(" fd = %u\n", fd);

        if (fd == -1) { /* Could not open the port */
                PDEBUG("sio_open: Unable to open %s - %s\n", strerror(errno),
                           port);
                return (ERR_PORT_OPEN);
        }

  /********************************
   * allocate new sio structure *
   ********************************/
        sio = _sio_follow(fd);
        if (!sio) { /* out of memory */
                close(fd);
                return (ERR_PORT_OPEN);
        }

        sio->fd = fd;
        sio->name = port;

        // fcntl(fd, F_SETFL, FNDELAY); /* nonblocking */

        tcgetattr(fd, sio->old_options); /* save the original options */
        tcgetattr(fd, sio->options); /* Get the current options */

        options = sio->options;

        /*
         * printf("\nsio_open\n"); printf("name : %s\n", sio->name);
         * printf("fd : %d\n", fd); printf("sio : %lx\n", sio);
         * printf("sio->options : %lx\n", sio->options);
         * printf("sio->old_options : %lx\n", sio->old_options);
         * printf("options : %lx\n", options); printf("\n");
         */

  /*********************
   * select Baudrate *
   *********************/
        r = cfsetispeed(options, baud); /* input */
        if (r) {
                PDEBUG("sio_open: fails to set input baudrate!\n", r);
                close(fd);
                return (r);
        }
        r = cfsetospeed(options, baud); /* output */
        if (r) {
                PDEBUG("sio_open: fails to set output baudrate!\n", r);
                close(fd);
                return (r);
        }

  /**********************
   * select data bits *
   **********************/
        options->c_cflag &= ~CSIZE; /* bit mask for data bits */
        options->c_cflag |= data;
        /*
         * close(fd); PDEBUG("undefined data bits number %d, port %s
         * closed.\n", data, port); return (ERR_PORT_OPEN);
         */

  /*******************
   * select parity *
   *******************/
        switch (parity) {
        case NO_PARITY:
                options->c_cflag &= ~(PARENB | PARODD);
                break;
        case ODD_PARITY:
                options->c_cflag |= PARODD;
                break;
        case EVEN_PARITY:
                options->c_cflag |= PARENB;
                break;
        default:
                tcsetattr(fd, TCSANOW, sio->old_options);
                close(fd);
                _sio_trim(fd);
                PDEBUG("undefined parity code %d, port %s closed.\n", parity,
                           port);
                return (ERR_PORT_OPEN);
        }

  /************************
   * select stop bit(s) *
   ************************/
        switch (stop) {
        case ONE_STOP_BIT:
                options->c_cflag &= ~CSTOPB;
                break;
        case TWO_STOP_BITS:
                options->c_cflag |= CSTOPB;
                break;
        default:
                tcsetattr(fd, TCSANOW, sio->old_options);
                close(fd);
                _sio_trim(fd);
                PDEBUG("undefined stop bits code %d, port %s closed.\n", stop,
                           port);
                return (ERR_PORT_OPEN);
        }

  /**********************
   * other parameterm *
   **********************/
        /*
         * posix input mode flags
         */
        options->c_iflag &= ~ICRNL; /* disable map CR to NL for noncanonical */
        options->c_iflag &= ~INLCR;
        options->c_iflag &= ~IXON; /* disable software flow control
                                                                   * (outgoing) */
        options->c_iflag &= ~IXOFF; /* disable software flow control
                                                                   * (incoming) */

        /*
         * posix output mode flags
         */
        options->c_oflag &= ~OPOST; /* raw output */
        options->c_oflag &= ~OLCUC; /* do not transfer the case */
        options->c_oflag &= ~ONLCR; /* do not translate the CR and NL */
        options->c_oflag &= ~OCRNL;
        options->c_oflag &= ~NLDLY; /* no delay for NL */
        options->c_oflag &= ~CRDLY; /* no delay for CR */
        options->c_oflag &= ~TABDLY; /* no delay for TAB */
        options->c_oflag &= ~BSDLY; /* no delay for BS */
        options->c_oflag &= ~VTDLY; /* no delay for VT */
        options->c_oflag &= ~FFDLY; /* no delay for FF */

        /*
         * posix control mode flags
         */
        options->c_cflag |= CLOCAL; /* Local line */
        /*
         * do not change "owner" of port
         */
        options->c_cflag |= CREAD; /* Enable receiver */

        options->c_cflag &= ~CRTSCTS; /* Disable hardware flow control */

        /*
         * posix local mode flags
         */
        options->c_lflag &= ~ICANON; /* default for noncanonical mode */
        options->c_lflag &= ~ECHO; /* Disable echoing of input characters */
        options->c_lflag &= ~ISIG; /* disable signals */

        /*
         * posix control characters
         */
        options->c_cc[VINTR] = 0;
        options->c_cc[VQUIT] = 0;
        options->c_cc[VERASE] = 0;
        options->c_cc[VKILL] = 0;
        options->c_cc[VEOF] = 4;
        options->c_cc[VTIME] = 0; /* Time to wait for data (tenths of
                                                                   * seconds) */
        options->c_cc[VMIN] = 1;//Anders: var foer 1
        options->c_cc[VSWTC] = 0;
        options->c_cc[VSTART] = 0;
        options->c_cc[VSTOP] = 0;
        options->c_cc[VSUSP] = 0;
        options->c_cc[VEOL] = 0;
        options->c_cc[VREPRINT] = 0;
        options->c_cc[VDISCARD] = 0;
        options->c_cc[VWERASE] = 0;
        options->c_cc[VLNEXT] = 0;
        options->c_cc[VEOL2] = 0;

  /**************************************
   * set the new options for the port *
   **************************************/
        // tcsetattr(fd, TCSANOW, options);
        tcsetattr(fd, TCSAFLUSH, options); /* flush input and output buffers,
                                                                                   * and make the change */
# ifdef I7K_DEBUG
        _sio_poptions(fd);
# endif /* I7K_DEBUG */

        return (fd);
}



Relevant Pages

  • RE: rs232?
    ... // Setup the serial port using hardware handshaking ... "CSerial is the base serial class, which provides a wrapper around the Win32 ... CSerialWnd fits in the Windows event driven model. ... I tried to enter words like SerialPort class in the help, ...
    (microsoft.public.vc.language)
  • Re: SerialPort Caching?
    ... Dropping the odd GPS sentence is hardly going to stuff things up much if ... ReadLine looks at the buffer for a line break, ... close the port during a read. ... SerialPort for 10x seconds...not sure what the exact numbers are, ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: Virtual COM port with UMDF
    ... virtual com port. ... The file type returned by GetFileTypeis 1, ... Please do not send e-mail directly to this alias. ... I would like to debug into the SerialPort component of .NET, ...
    (microsoft.public.development.device.drivers)
  • Re: Virtual COM port with UMDF
    ... component SerialPort can now open my virtual com port. ... Please do not send e-mail directly to this alias. ... I would like to debug into the SerialPort component of .NET, ... driver cannot write to this key so that it is not possible without ...
    (microsoft.public.development.device.drivers)
  • Problem with JNI and Tomcat
    ... This DLL is used to communicate over a RS232 port, and it must notice any event that occurs on the port to the java application. ... the nativeOpenPort functions looks for the "notifyEvent" Java method in the object that called it, in order to notify events when they occurs, and saves it in the "eventNotifyMethod" of the SERIALPORT structure ... private int portType; ...
    (comp.lang.java.programmer)