Cast problem / serial interface

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • MVennebusch@web.de

    Cast problem / serial interface

    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(MODEMDEVIC E, O_RDWR | O_NOCTTY );
    if (fd <0) { printf("ERROR while opening MODEMDEVICE \n");
    perror(MODEMDEV ICE); return 0; }

    tcgetattr(fd,&o ldtio); /* 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,TC SANOW,&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("Possibl e beginning of data!\n");
    sleep(1); }
    // read next byte and check for "@"...

    }

    tcsetattr(fd,TC SANOW,&oldtio);

    return 0;

    }
  • Richard Heathfield

    #2
    Re: Cast problem / serial interface

    MVennebusch@web .de 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

    Comment

    • vippstar@gmail.com

      #3
      Re: Cast problem / serial interface

      On Feb 20, 3:06 pm, MVennebu...@web .de 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.progr ammer.
      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(MODEMDEVIC E, O_RDWR | O_NOCTTY );
      if (fd <0) { printf("ERROR while opening MODEMDEVICE \n");
      perror(MODEMDEV ICE); return 0; }
      >
      tcgetattr(fd,&o ldtio); /* 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.o rg/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,TC SANOW,&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("Possibl e 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".

      Comment

      • MVennebusch@web.de

        #4
        Re: Cast problem / serial interface

        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

        Comment

        • CBFalconer

          #5
          Re: Cast problem / serial interface

          MVennebusch@web .de 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

          Comment

          • Keith Thompson

            #6
            Re: Cast problem / serial interface

            vippstar@gmail. com writes:
            On Feb 20, 3:06 pm, MVennebu...@web .de 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.progr ammer.
            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_Keit h) <kst-u@mib.org>
            Nokia
            "We must do something. This is something. Therefore, we must do this."
            -- Antony Jay and Jonathan Lynn, "Yes Minister"

            Comment

            Working...