Cast problem / serial interface

Discussion in 'C Programming' started by MVennebusch@web.de, Feb 20, 2008.

  1. Guest

    Hi,

    I want to read/parse the binary output of a GPS receiver written to
    the serial interface. The data packages start with a "$@".

    The following program does read from the serial interface, but it does
    not find the beginning of a data block. (I am very sure that the
    binary data sent from the GPS receiver does contain the "$@"!). So
    there must be an error in the if-statement. Do I have to cast either
    "buf[0]" or the '$'-sign? What else could be wrong?

    Thanks for your help!
    Markus


    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <termios.h>
    #include <stdio.h>

    #define BAUDRATE B38400
    #define MODEMDEVICE "/dev/ttyS0"
    #define _POSIX_SOURCE 1 /* POSIX compliant source */
    #define FALSE 0
    #define TRUE 1

    #define BLOCKSIZE 1

    int main()
    {
    int fd;
    struct termios oldtio,newtio;
    char buf[BLOCKSIZE];

    ssize_t res;

    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
    if (fd <0) { printf("ERROR while opening MODEMDEVICE \n");
    perror(MODEMDEVICE); return 0; }

    tcgetattr(fd,&oldtio); /* save current port settings */

    bzero(&newtio, sizeof(newtio));
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR;
    newtio.c_oflag = 0;

    /* set input mode (non-canonical, no echo,...) */
    newtio.c_lflag = 0;

    newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
    newtio.c_cc[VMIN] = 5; /* blocking read until 5 chars received
    */

    tcflush(fd, TCIFLUSH);
    tcsetattr(fd,TCSANOW,&newtio);

    while (1) {

    res = read(fd, &buf, BLOCKSIZE);
    buf[1]='\0';

    printf("%c\n", buf[0]);
    // Why does the following not work???
    if (buf[0] == '$') { printf("Possible beginning of data!\n");
    sleep(1); }
    // read next byte and check for "@"...

    }

    tcsetattr(fd,TCSANOW,&oldtio);

    return 0;

    }
     
    , Feb 20, 2008
    #1
    1. Advertising

  2. said:

    <snip>

    > #define BLOCKSIZE 1


    1. Right, okay so far.

    >
    > int main()
    > {
    > int fd;
    > struct termios oldtio,newtio;
    > char buf[BLOCKSIZE];


    i.e. char buf[1], i.e. an array of 1 byte, whose index is 0.

    <snip>

    > buf[1]='\0';


    Writing to buf[0] is legal, but writing to buf[1] is not, because buf[1]
    doesn't exist.

    I'm not saying that's your only problem, but it's definitely *a* problem.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Feb 20, 2008
    #2
    1. Advertising

  3. Guest

    On Feb 20, 3:06 pm, wrote:
    > Hi,
    >
    > I want to read/parse the binary output of a GPS receiver written to
    > the serial interface. The data packages start with a "$@".
    >
    > The following program does read from the serial interface, but it does
    > not find the beginning of a data block. (I am very sure that the
    > binary data sent from the GPS receiver does contain the "$@"!). So
    > there must be an error in the if-statement. Do I have to cast either
    > "buf[0]" or the '$'-sign? What else could be wrong?

    As the snippet that follows uses POSIX headers and functions, your
    question(s) belong in another newsgroup, namely comp.unix.programmer.
    comp.lang.c discusses ISO C and ISO C only.
    <bellow is OT>

    > #include <sys/types.h>
    > #include <sys/stat.h>
    > #include <fcntl.h>
    > #include <termios.h>
    > #include <stdio.h>
    >
    > #define BAUDRATE B38400

    This doesn't seem valid..

    > #define MODEMDEVICE "/dev/ttyS0"
    > #define _POSIX_SOURCE 1 /* POSIX compliant source */
    > #define FALSE 0
    > #define TRUE 1

    Rather annoying macros IMHO.
    > #define BLOCKSIZE 1

    Since you won't change this (or else, your whole code would change as
    seen bellow)
    why not write a readbyte(sock, buf) function instead? (or just use
    read with 1 as size)

    > int main()
    > {
    > int fd;
    > struct termios oldtio,newtio;
    > char buf[BLOCKSIZE];
    >
    > ssize_t res;
    >
    > fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
    > if (fd <0) { printf("ERROR while opening MODEMDEVICE \n");
    > perror(MODEMDEVICE); return 0; }
    >
    > tcgetattr(fd,&oldtio); /* save current port settings */
    >
    > bzero(&newtio, sizeof(newtio));

    bzero marked as a legacy function from the open group base spec issue
    6.
    (available online at <http://www.opengroup.org/onlinepubs/009695399/>)
    Use memset(&newtio, 0, sizeof newtio); instead, or the macro suggested
    by open group.
    > #define bzero(b,len) (memset((b), '\0', (len)), (void) 0)


    > newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

    You have defined BAUDRATE as B38400, that would probably be a syntax
    error.

    > newtio.c_iflag = IGNPAR;
    > newtio.c_oflag = 0;
    >
    > /* set input mode (non-canonical, no echo,...) */
    > newtio.c_lflag = 0;
    >
    > newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
    > newtio.c_cc[VMIN] = 5; /* blocking read until 5 chars received
    > */
    >
    > tcflush(fd, TCIFLUSH);
    > tcsetattr(fd,TCSANOW,&newtio);
    >
    > while (1) {
    >
    > res = read(fd, &buf, BLOCKSIZE);

    Why don't you check the return value of read?
    > buf[1]='\0';

    Why set it every time you run the loop?
    >
    > printf("%c\n", buf[0]);
    > // Why does the following not work???
    > if (buf[0] == '$') { printf("Possible beginning of data!\n");

    Possibly? that is not reliable at all. Have a size_t object that
    counts the data that has been read.
    if(buf[0] == '$' && count == 0) /* possibly beginning of data */

    > sleep(1); }
    > // read next byte and check for "@"...

    Do you really want to sleep there?
    It is very likely that you have not posted the code that doesn't
    "work".
     
    , Feb 20, 2008
    #3
  4. Guest

    Thanks a lot for your quick answers!
    It was (as always) a stupid mistake: The baud rate was wrong, indeed.
    Now everything works fine!

    But thank you for the useful comments!

    Markus
     
    , Feb 20, 2008
    #4
  5. CBFalconer Guest

    wrote:
    >
    > I want to read/parse the binary output of a GPS receiver written
    > to the serial interface. The data packages start with a "$@".
    >

    Take a look at the thread "search a string in file handling in c"
    and my answer of last Thursday, Feb. 14th.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Feb 20, 2008
    #5
  6. writes:
    > On Feb 20, 3:06 pm, wrote:
    >> I want to read/parse the binary output of a GPS receiver written to
    >> the serial interface. The data packages start with a "$@".
    >>
    >> The following program does read from the serial interface, but it does
    >> not find the beginning of a data block. (I am very sure that the
    >> binary data sent from the GPS receiver does contain the "$@"!). So
    >> there must be an error in the if-statement. Do I have to cast either
    >> "buf[0]" or the '$'-sign? What else could be wrong?

    > As the snippet that follows uses POSIX headers and functions, your
    > question(s) belong in another newsgroup, namely comp.unix.programmer.
    > comp.lang.c discusses ISO C and ISO C only.


    Yup.

    > <bellow is OT>
    >
    >> #include <sys/types.h>
    >> #include <sys/stat.h>
    >> #include <fcntl.h>
    >> #include <termios.h>
    >> #include <stdio.h>
    >>
    >> #define BAUDRATE B38400

    > This doesn't seem valid..

    [...]

    I think B38400 is a macro defined in one of the POSIX-specific headers.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Feb 20, 2008
    #6
    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. Math55
    Replies:
    3
    Views:
    663
    Math55
    Nov 2, 2003
  2. MSG

    to cast or not to cast malloc ?

    MSG, Feb 6, 2004, in forum: C Programming
    Replies:
    38
    Views:
    1,079
    Dan Pop
    Feb 10, 2004
  3. EvilRix
    Replies:
    8
    Views:
    648
    Martin Dickopp
    Feb 14, 2004
  4. Max Kotasek
    Replies:
    4
    Views:
    989
    Max Kotasek
    Apr 9, 2010
  5. Pavel
    Replies:
    7
    Views:
    535
    Pavel
    Sep 19, 2010
Loading...

Share This Page