Connecting Tech Pros Worldwide Forums | Help | Site Map

Cast problem / serial interface

MVennebusch@web.de
Guest
 
Posts: n/a
#1: Feb 20 '08
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;

}

Richard Heathfield
Guest
 
Posts: n/a
#2: Feb 20 '08

re: Cast problem / serial interface


MVennebusch@web.de said:

<snip>
Quote:
#define BLOCKSIZE 1
1. Right, okay so far.
Quote:
>
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>
Quote:
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
vippstar@gmail.com
Guest
 
Posts: n/a
#3: Feb 20 '08

re: Cast problem / serial interface


On Feb 20, 3:06 pm, MVennebu...@web.de wrote:
Quote:
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>
Quote:
#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..
Quote:
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1
Rather annoying macros IMHO.
Quote:
#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)
Quote:
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.
Quote:
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
Quote:
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
You have defined BAUDRATE as B38400, that would probably be a syntax
error.
Quote:
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?
Quote:
buf[1]='\0';
Why set it every time you run the loop?
Quote:
>
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 */
Quote:
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".
MVennebusch@web.de
Guest
 
Posts: n/a
#4: Feb 20 '08

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
CBFalconer
Guest
 
Posts: n/a
#5: Feb 20 '08

re: Cast problem / serial interface


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

Keith Thompson
Guest
 
Posts: n/a
#6: Feb 20 '08

re: Cast problem / serial interface


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


Similar C / C++ bytes