Problem to read and write on a serial port

Discussion in 'C Programming' started by collinm, Mar 29, 2005.

  1. collinm

    collinm Guest

    hi

    i send a command to a led display, the led display is suppose to return
    me some character

    i write a string on a serial port

    void ledDisplayExist()
    {
    char msg[]={'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0',
    '\2', 'H', 'B', '\4' };
    int length = sizeof(msg);
    writeopen(msg, length);
    readopen();
    }

    int writeopen(char msg[], int size)
    {
    printf("write\n");
    int fd1;
    int wr;
    fd1 = open(ledisplay, O_RDWR | O_NOCTTY | O_NDELAY );
    if (fd1 == -1)
    {
    fprintf(stderr, " %s open_port: Unable to open %s\n",
    strerror(errno), ledisplay);
    }
    else
    {
    fcntl(fd1, F_SETFL, 0);

    wr=write(fd1, msg, size);
    if (wr < 0)
    fputs("write() of n bytes failed!\n", stderr);
    close(fd1);
    }
    return (fd1);
    }

    after i read on the serial port:

    int readopen()
    {
    printf("read\n");
    int fd1;
    int rd;
    char *buff=NULL;
    fd1 = open(ledisplay, O_RDONLY | O_NOCTTY | O_NDELAY );
    if (fd1 == -1)
    {
    fprintf(stderr, "%s open_port: Unable to open %s\n",
    strerror(errno), ledisplay);
    }
    else
    {
    fcntl(fd1, F_SETFL, 0);
    printf(" Port 1 has been sucessfully opened and %d is the file
    descriptor\n",fd1);
    rd=read(fd1, buff, 30);
    printf(" Bytes recieved are %d \n",rd);
    close(fd1);
    }
    return (fd1);
    }

    the string returned by the led display is suppose to be something like:
    <nul><nul><nul><nul><nul><soh>"000"<stx>"G234.3432"<etx>"0237<eot>

    the lenght of the returned string is under 30 character...

    when i run the prog, the prog display

    port série utilisé: /dev/ttyS2
    connection au led display
    write
    read
    Port 1 has been sucessfully opened and 3 is the file descriptor

    i wait a few second and nothing more is display.... i kill the program

    any idea why i don't read correctly on the serial port?
    collinm, Mar 29, 2005
    #1
    1. Advertising

  2. In article <>,
    collinm <> wrote:
    >i write a string on a serial port


    Anything to do with serial ports is implimentation specific; you
    could likely get better and faster advice in a newsgroup such as
    comp.programming.embedded .


    >int writeopen(char msg[], int size)
    >{


    > return (fd1);


    Note that by that point fd1 is either not been opened properly, or
    has already been closed. fd1 is thus only of academic interest and should
    not be treated as being anything particularily meaningful .

    >after i read on the serial port:


    >int readopen()
    >{
    > printf("read\n");
    > int fd1;
    > int rd;
    > char *buff=NULL;
    > fd1 = open(ledisplay, O_RDONLY | O_NOCTTY | O_NDELAY );


    The behaviour of open() is not part of the C standard. If you are
    using some other standard, then you should at least say which standards
    we should interpret the code under.

    For example, your description indicates you are opening /dev/ttyS2 .
    That appears to be a serial port. On some systems, the fact that you
    opened the port as ttyS<something> would have a different result
    than if you opened it as (say) ttyd<something>. You have not said which
    OS you are using, so we cannot research to find out what, if any,
    special properties might be associated with opening the serial port
    through that version of its name.

    > fcntl(fd1, F_SETFL, 0);


    fcntl() is not part of the C standard either. If you are using the
    POSIX.1-1990 fcntl() then using the F_SETFL open with a value of 0
    clears all the flags associated with the file descriptor -- including
    the O_NDELAY flag that you carefully specified in the open() statement.
    The read() statement is thus (assuming POSIX.1 once more) going to become
    a blocking read. We don't know how that serial port or leddisplay operate
    so we don't have information on the expected behaviour upon opening.

    In one of your earlier code iterations in this newsgroup, your code did
    not close the device between the write() and the read(). That might or might
    not be crucial to the behaviour.

    > printf(" Port 1 has been sucessfully opened and %d is the file
    >descriptor\n",fd1);
    > rd=read(fd1, buff, 30);


    You could add debugging there such as using a select() with a timeout,
    or you could loop reading 1 character at a time and seeing how many
    characters you actually get.


    >any idea why i don't read correctly on the serial port?


    As I indicated in an earlier posting, one thing that is missing
    from your code is any code to set the port to a known good state,
    such as by specifying the serial port speed, number of stop bits,
    whether the I/O is "raw" or "cooked". For example, it could be
    (hypothetically) that the problem you are having is that the <stx>
    in the input stream is being interpreted as indicating that one
    or more characters in the input buffer should be flushed, which
    would leave you with less than 30 characters in the buffer but you
    always wait for exactly 30. Then too there is the issue that the
    default behaviour on most serial ports that are not specifically
    set to "raw" mode is to ignore NUL bytes, which again would lead
    to a short input count.

    --
    "[...] it's all part of one's right to be publicly stupid." -- Dave Smey
    Walter Roberson, Mar 29, 2005
    #2
    1. Advertising

  3. collinm

    -berlin.de Guest

    collinm <> wrote:
    > i send a command to a led display, the led display is suppose to return
    > me some character


    > after i read on the serial port:


    > int readopen()
    > {
    > printf("read\n");
    > int fd1;
    > int rd;
    > char *buff=NULL;
    > fd1 = open(ledisplay, O_RDONLY | O_NOCTTY | O_NDELAY );
    > if (fd1 == -1)
    > {
    > fprintf(stderr, "%s open_port: Unable to open %s\n",
    > strerror(errno), ledisplay);
    > }
    > else
    > {
    > fcntl(fd1, F_SETFL, 0);
    > printf(" Port 1 has been sucessfully opened and %d is the file
    > descriptor\n",fd1);
    > rd=read(fd1, buff, 30);


    Assuming that read() is meant to read a certain number of characters
    into the memory pointed to by 'buff' (which I can't say for sure since
    there's no read() function in standard C) then you make a mistake here,
    'buff' is a pointer initialized to NULL and thus pointing to memory you
    are never allowed to use (if it exists at all). You need to make 'buff'
    an array of at least as many characters as you want to read or assign a
    pointer to 'buff' that points to enough space (e.g. by using malloc()).

    > printf(" Bytes recieved are %d \n",rd);
    > close(fd1);
    > }
    > return (fd1);
    > }


    From what you are writing it looks as if you might be on some kind of
    UNIX system. Most of your questions then might be answered better in
    a group that deals with programming under UNIX - lots of your code
    uses non-standard extensions to C (all the functions open(), read(),
    write(), close(), fcntl() are not part of C). If that is the case
    you might benefit quite a lot by asking your questions in e.g.
    comp.unix.programmer instead of here. There are several people who
    have been dealing with serial port issues under UNIX for quite some
    time, but they won't answer you're question here since it would be
    off-topic (if they read comp.lang.c at all). And there are quite a
    few problems involved with using the UNIX read() function correctly
    (and especially when used for serial ports), but you won't find out
    about it here but only in a group where read() has a well-defined
    meaning.
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
    -berlin.de, Mar 30, 2005
    #3
  4. collinm

    collinm Guest


    >Walter Roberson wrote:


    > Anything to do with serial ports is implimentation specific; you
    > could likely get better and faster advice in a newsgroup such as
    > comp.programming.embedded .
    >


    i begining a tread to this newsgroup


    >
    > The behaviour of open() is not part of the C standard. If you are
    > using some other standard, then you should at least say which

    standards
    > we should interpret the code under.
    >
    > For example, your description indicates you are opening /dev/ttyS2 .
    > That appears to be a serial port. On some systems, the fact that you
    > opened the port as ttyS<something> would have a different result
    > than if you opened it as (say) ttyd<something>. You have not said

    which
    > OS you are using, so we cannot research to find out what, if any,
    > special properties might be associated with opening the serial port
    > through that version of its name.


    we use a sixnet Mini-VersaTRAK mIPm
    http://www.sixnetio.com/html_f iles/products_and_groups/mipm_ vt.htm

    this system use linux

    >
    > > fcntl(fd1, F_SETFL, 0);

    >
    > fcntl() is not part of the C standard either. If you are using the
    > POSIX.1-1990 fcntl() then using the F_SETFL open with a value of 0
    > clears all the flags associated with the file descriptor -- including
    > the O_NDELAY flag that you carefully specified in the open()

    statement.
    > The read() statement is thus (assuming POSIX.1 once more) going to

    become
    > a blocking read. We don't know how that serial port or leddisplay

    operate
    > so we don't have information on the expected behaviour upon opening.
    >
    > In one of your earlier code iterations in this newsgroup, your code

    did
    > not close the device between the write() and the read(). That might

    or might
    > not be crucial to the behaviour.
    >
    > > printf(" Port 1 has been sucessfully opened and %d is the

    file
    > >descriptor\n",fd1);
    > > rd=read(fd1, buff, 30);

    >
    > You could add debugging there such as using a select() with a

    timeout,
    > or you could loop reading 1 character at a time and seeing how many
    > characters you actually get.
    >
    >
    > >any idea why i don't read correctly on the serial port?

    >
    > As I indicated in an earlier posting, one thing that is missing
    > from your code is any code to set the port to a known good state,
    > such as by specifying the serial port speed, number of stop bits,
    > whether the I/O is "raw" or "cooked".


    under bash:
    ~ # stty -a </dev/ttyS2
    speed 9600 baud; rows 0; columns 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
    eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z;
    rprnt = ^R; werase = ^W; lnext = ^V; flush = ^U; min = 1; time = 0;
    -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl
    ixon
    -ixoff -iuclc -ixany -imaxbel
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0
    bs0
    vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop
    -echoprt echoctl echoke

    For example, it could be
    > (hypothetically) that the problem you are having is that the <stx>
    > in the input stream is being interpreted as indicating that one
    > or more characters in the input buffer should be flushed, which
    > would leave you with less than 30 characters in the buffer but you
    > always wait for exactly 30. Then too there is the issue that the
    > default behaviour on most serial ports that are not specifically
    > set to "raw" mode is to ignore NUL bytes, which again would lead
    > to a short input count.
    >


    with:

    int readopen()
    {
    printf("read\n");
    int fd1;
    int rd;
    char buff[255];
    fd1 = open(ledisplay, O_RDWR | O_NOCTTY | FNDELAY );
    if (fd1 == -1)
    fprintf(stderr, "%s open_port: Unable to open %s\n",
    strerror(errno), ledisplay);
    else
    {
    fcntl(fd1, F_SETFL, FNDELAY);
    rd=read(fd1, buff, 20);
    printf(" Bytes recieved are %d \n",rd);
    close(fd1);
    }
    return (fd1);
    }

    that return always return me: Bytes recieved are -1
    collinm, Mar 30, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. collinm

    Read Write serial port

    collinm, Mar 21, 2005, in forum: C Programming
    Replies:
    0
    Views:
    648
    collinm
    Mar 21, 2005
  2. collinm

    Read Write serial port

    collinm, Mar 21, 2005, in forum: C Programming
    Replies:
    7
    Views:
    519
    Dave Thompson
    Mar 28, 2005
  3. Shadowdancer

    Open/write and read serial port (COM1) on iPAQ 2210

    Shadowdancer, Sep 17, 2004, in forum: ASP .Net Mobile
    Replies:
    1
    Views:
    413
    JuanDG
    Sep 21, 2004
  4. PerlFAQ Server
    Replies:
    0
    Views:
    197
    PerlFAQ Server
    Jan 15, 2011
  5. PerlFAQ Server
    Replies:
    0
    Views:
    182
    PerlFAQ Server
    Mar 11, 2011
Loading...

Share This Page