Hi all,
I am writing a program to read data from a sensor at /dev/ser1 which gives out data at 100Hz. I am using read() function for multi byte read i.e. in following manner
res = read(fd,databuffer,500)
But res never returns small numbers. It either gives -1(no data to be read)
few times and suddenly gives res= 50, 40 etc in between.
while(1)
{
res = read(fd,databuffer,500);
printf("%d\n",res);
//extra processing <1ms
}
the output of res is in the following manner:
500
500
56
-1
-1
-1
56
-1
-1
56
…
I have confirmed that the sensor sends data every 10ms in a consistent manner. Could anyone help me with this? Is there a minimum fill of the serial buffer required before it gives out data in a multibyte read?
Thanks
That’s normal, if you check the documention for read it says that it might return less then the number of bytes you requested. However I would not expect it to return -1, what is the value of errno. How did you do the open(), did you change the setting of the serial port.
When I am doing this sort of thing, I set the port to be non blocking.
So read returns immediatly with all characters available.
Then I ask for only 1 char at a time, seems inefficient, but the message parsing is greatly simplified, and as the serial port is usually relativly slow, speed is not the issue.
It also helps to know how the data is formatted, does the sensor send a fixed length string?
Does it send a framed string?
If it’s not framed or fixed length then you have an issue in decoding the data.
If it’s framed, you need to parse the string for start and end charaters.
If it’s fixed length, only aske for the correct number of chars, (and leave it as blocking).
Thanking you for all your replies.
dear mario, here is how i open my port and my settings
int InitPort::OpenPort(char* Port)
{
int Fd=open(Port,O_RDWR | O_NOCTTY | O_NDELAY);
if(Fd == -1)
{
cout<<“Unable to open port “<<Port<<endl;
}
else
cout<<“Port '”<<Port<<”’ opened”<<endl;
Thank you for all the help and sorry for the multiple posts.
I am using an XT/104 and this i how i installed the ports:
devc-ser8250 -t8 -u3 100,5 &
I checked the data being sent over from the sensor using an oscilloscope and it is sending over the bytes at a consistent rate of 21 bytes every 10 ms.
I use the program to read every 9ms.
For every 2 or 3 reading of the serial port i will get 1 read which returns 56 bytes and errno 22 (invalid argument) while the other reads will return a -1 with errno 11 (resource temporarily unavailable).
Thanking you all for your reply…I have fixed the problem. It is a limitation of the XT/104 card. When I connected the sensor to the main serial ports 1 and 2, it works well
Ok what is required here is a bit of good old fasioned design.
The sensor sends 19 (or is it 21) bytes of data.
What does the data look like?
is it ascii or binary? - that matters for the port config, if it’s binary you need to set the raw option.
Does it end with a terminating character.
When you understand the data, you can design your app.
try:
while(bytesRx < 19) or is it 21
{
if ( read(fd, x, 1) > 0)
{
bytesRx ++;
}
msg[bytesRx] = ch
if (( ch == terminatingCharIfThereIsOne) && (bytesRx < expected))
{
break
duff message
}
}
processMessage(msg)
OK it’s not real code but you get the gist?
Once you have confidence in the data, you can optimise the code if you need to.