Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Performance issue with C# and GPS

176 views
Skip to first unread message

Marcel Ruff

unread,
Jan 8, 2007, 2:06:37 AM1/8/07
to
Hello,

i'm playing with GPS serial input (port.ReadLine()).

This delivers 3 NMEA sentences per second
on a XScale 400 MHz processor.

I'm experiencing a delay of up to two minutes
on receiving the GPS data and have chasing this
issue for several days now.

I have now a possible explanation that the (simple) code
written in C# is too slow and the GPS data is
queued back on the serial line.

Could this be a possible explanation?

Is this a task one should do with unmanaged C/C++?

How can i profile the CPU of the PDA to see if it is overloaded?

thanks for some advise

Marcel

chr...@mailcity.com

unread,
Jan 8, 2007, 4:08:24 AM1/8/07
to


I've done something similar on a similar spec device and never had this
problem, although I was using the OpenNETCF.IO.Serial.GPS class. Try
this and see if it helps your problem.

Cheers

Chris

dool...@gmail.com

unread,
Jan 8, 2007, 4:18:39 AM1/8/07
to
Hi Marcel,

This lack of response can have many reasons. first of all you must make
it clear what the context is ( I mean what software do you use).
I also work with GPs and c# code with the GID of my on board GPs and
don't see a performance problem.

Jan

<ctacke/>

unread,
Jan 8, 2007, 9:26:08 AM1/8/07
to
There's something else wrong. C# is definitely not "too slow" as it
performs at the same speed as native code once JITted, plus your serial data
= probably at 9600bps, is super slow anyway. Two minutes is a near
eternity - the only think to cause such a delay is a really high recevie
threshold. Then I'd expect the driver data buffer to overflow.

Without seeing code we can't help much, but I'm certain your code is the
culprit.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--

"Marcel Ruff" <m...@marcelruff.info> wrote in message
news:ensqi3$e73$1...@online.de...

Paul G. Tobey [eMVP]

unread,
Jan 8, 2007, 11:30:04 AM1/8/07
to
Maybe the GPS device is not sending an end-of-line at the end of every three
sentences. That would delay your ReadLine() until the GPS did happen to
send one or until the receive time-out, which you haven't told us.

Paul T.

"<ctacke/>" <ctacke[@]opennetcf[dot]com> wrote in message
news:uTNcuDz...@TK2MSFTNGP04.phx.gbl...

Robert Janik

unread,
Jan 9, 2007, 5:14:46 PM1/9/07
to
Your problem could be caused by multithreaded deadlock. If you are trying to
read from serial port and update an object and at the same time to read from
that object from UI thread to display data. However without the code it is
hard to say where the problem might be.

When you start receiving data after 2 minutes, do you receive $GPGGA
sentence every second (or several $GP sentences per second) or is it one
sentence per 2 minutes?
If you disconnect and connect again are you able to receive first sentences
faster? In this case it means that it occurs only after cold start, when you
switch the device on. You probably know that this is normal behavior, GPS
first needs to download data about satellites, before it can start tracking.
If your application disconnects, but GPS is still connected to your PDA,
information remains in GPS memory and when application connects to the GPS
again it can start almost immediately. If you switch PDA off (and GPS with
it) GPS needs to download data again which takes about 2 minutes (however
some GPS have small batery which can keep the database in memory for some
time - few minutes to few hours).
Manufacturers very often publish that cold start takes about 1 minute, but I
experimented a lot with my GPS receiver and I would say that it takes 2
minutes (upto 2.5). Warm start (when satellite database isn't lost) should
take about 15 to 20 seconds.
Try to display raw data instead of position. When GPS is creating the
satellite database during those 2 minutes, you should be able to receive
sentences with zero values. For example:

$GPGGA0,0,0,,,0,0,0,,0 (I made it up, but real sentence looks similar,
you will recognise it quickly)

but it is possible that some GPS devices don't send anything during this
initialization procedure, I'm not sure. I thing that all devices should at
least send empty messages, so that applications could tell if GPS is alive
or not.

In my code I use

System.IO.Ports.SerialPort class

and method

ReadExisting()

You can try this. I hope that this info will help you.
Robert Janik

"Marcel Ruff" <m...@marcelruff.info> wrote in message
news:ensqi3$e73$1...@online.de...

Marcel Ruff

unread,
Jan 16, 2007, 6:37:21 PM1/16/07
to
Hi again,

i have the problem reproducable with my HP IPAQ hw6910 with
the build in GPS receiver.

I have now bought an external GPS bluetooth mouse (Fortuna Slim)
where the IPAQ (with my same software) runs fine in 'real time',
very nice this success - but very strange, why?

Strange enough, using the bluetooth Fortuna with a Motorola HC700 PDA
i get the delay again (same software, Windows CE 5).

Here is my code (baud=57600):

==============================
public void SerialDataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try {
string sentence = this.port.ReadLine();

// ignore immediately unwanted data with string[] sentences={ "$GPRMC" };
bool found = false;
for (int i=0; i<this.sentences.Length; i++) {
if (sentence.StartsWith(sentences[i])) {
found = true;
break;
}
}
if (!found) {
if (logger.IsTraceEnabled) logger.Trace("No interest in " + sentence);
return;
}

if (logger.IsDebugEnabled) logger.Debug(sentence);
GPSData data = new GPSData(sentence);
if (data.DataReceived)
this.gpsDataListener.OnGPSData(data);
}
catch (Exception ex) {
...
}
==============================

The "new GPSData(sentence)" does nothing important,
just looping over the ',' and saving the data.

My callback virtual function:
this.gpsDataListener.OnGPSData(data);
assigns the 'data' instance to another variable
which is not protected by a mutex (is a reference assignment atomic?)
This other variable is then and again checked by the System.Forms thread (main loop):

=============================
public void OnGPSData(GPSData gpsData) {
... some logging
... if signal quality is bad -> return
// This variable is not protected by a monitor
// and later accessed be the UI thread:
this.currentGpsRmcData = gpsData;
}
=============================


The $GPGGA0,0,0,,,0,0,0,,0 sentences i can see during switch on of the
GPS mouse as well, but they quickly change to real coordinates.
I get about 4 sentences per second:

============================
$GPRMC,122557.17,A,xxxx.900111,N,yyyyy.031056,E,000.0,000.0,060107,,*33
$GPGSA,A,3,06,07,16,18,21,22,,,,,,,02,02,02*12
$GPGGA,122558.18,xxxx.900111,N,yyyyy.031056,E,1,07,2.0,552.0,M,-0.753010,M,-0.32601,*43
$GPRMC,122558.18,A,xxxx.900111,N,yyyyy.031056,E,000.0,000.0,060107,,*33
$GPGSA,A,3,06,07,16,18,19,21,22,,,,,,02,02,02*1A
$GPGGA,122558.48,xxxx.900111,N,yyyyy.031056,E,1,08,2.0,552.0,M,-0.753014,M,-0.33201,*48
$GPRMC,122558.48,A,xxxx.900111,N,yyyyy.031056,E,000.0,000.0,060107,,*36
$GPGSA,A,3,06,07,16,18,19,21,22,26,,,,,02,02,02*1E
$GPGGA,122601.22,xxxx.900111,N,yyyyy.031056,E,1,08,2.0,552.0,M,-0.753014,M,-0.33201,*4B
$GPRMC,122601.22,A,xxxx.900111,N,yyyyy.031056,E,000.0,000.0,060107,,*35
$GPGSV,3,1,12,15,82,089,,16,65,208,35,21,51,060,27,03,51,089,*7D
============================

Sometimes it helps if i disconnect from COM7 and reconnect again (i have
made a little UI button to test this), but not always.

The delay starts right when i start my car and remains
even when i driver 40 minutes. My position is always ~ 2 minutes behind,
when is finally stop the car, the coordinates are slowly catching up to my real
position.

Could using ReadExisting() help, are you then
fiddling the partly received string together yourself until a '\n' arrives?

Thanks again,

Marcel

Robert Janik

unread,
Jan 20, 2007, 3:20:59 AM1/20/07
to
"Marcel Ruff" <m...@marcelruff.info> wrote in message
news:eojnmo$cme$1...@online.de...

> Hi again,
>
> i have the problem reproducable with my HP IPAQ hw6910 with
> the build in GPS receiver.
>
> I have now bought an external GPS bluetooth mouse (Fortuna Slim)
> where the IPAQ (with my same software) runs fine in 'real time',
> very nice this success - but very strange, why?
>
> Strange enough, using the bluetooth Fortuna with a Motorola HC700 PDA
> i get the delay again (same software, Windows CE 5).
>
> Here is my code (baud=57600):
>

Try also 4800 baud. It might look like it could slow down messages even
more, but believe me it will not. When I bought CF GPS for my DELL Axim
X51v, I found that GPS worked for a few minutes and randomly stopped sending
messages or disconected and port couldn't be opened again. On the Internet I
found that DELL didn't quite comply with standards and CF communication had
a timing issue (narrower signal or something like that, which broke
synchronization). I was installing new firmware and third party fixes to COM
port driver and it took about 8 months, when they finally released fixed
firmware. During this time I experimented with baud rate and different
settings to overcome this timing issue and I found that higher speeds didn't
work always very well. It started well, but after a short time it was
receiveing random binary data. If there is a timing issue in communication
it could help (or not) to use lower speed and you will probably find
different results with different hardware configs. When using 57600 you are
not going to receive position any faster (maybe a few milliseconds).You
could try 33600 and other speeds down to 4800. 4800 is standard and some
manufacturers of GPS receivers suggest to use this speed.

Are you looping properly? Isn't there infinite loop?

I've seen a few examples and they used ReadExisting. ReadLine reads from
buffer and waits for "\n", so it shouldn't be a problem, but who knows,
maybe there is a bug in .NET CF. What if it reads even if it isn't at the
end of line. The sentence could be unfinished and it could read something
like this.
$GPRMC,122557.17,A,xxxx.900111,N,yy
yyy.031056,E,000.0,00
0.0,060107,,*33

In this case you would get correct sentences randomly. I use ReadExisting to
fill my own buffer (StringBuilder). One thread is reading from GPS every xxx
milliseconds . I can set in combobox how many ms (10, 20, 50, 100, 200, 500,
1000) should the timer use. I haven't found any difference in the settings,
but Axim has 624 MHz processor. It is better to set higher value for slower
processors, so that the thread wouldn't loop like crazy and use more CPU.
500 and 1000ms are probably too high values - you would receive position a
little bit later. I use 100 or 200ms. Another thread is reading from
StringBuilder, looking for strings between "$" and extracting them. When I
get a message I decode it and raise several events (decoded GGA, GSV, raw
message etc.) to notify subscribers.
It is quite efficient routine, considering that at the same time I render 3D
map according to elevation data (files are as big as 60 and even 200MB).

Does your problem really occur only in car when you startup engine? I have
built a satellite receiver for receiving meteorological data from Meteosat
and GOES satellites and I experienced some elmag. interference from ignition
system of cars as far as 100m (300ft). It worked in microwave band 1.7GHz.
Bluetooth is working on 2.4GHz if I remember, so it could be similar issue.
Older cars usually create more interference. When I was downloading pictures
of Earth I was even able to calculate engine RPM from noise in the picture.
Satellite was very sensitive on the other hand GPS mounted in car is very
close to the source of potential interference. This is the reason why I
bought Compact Flash GPS and not bluetooth.

So there could be many reasons why you experience this issue. I hope that
this info helps.

Robert


Marcel Ruff

unread,
Jan 25, 2007, 10:10:43 AM1/25/07
to
Hi Robert,

thanks for all your help.

It works perfectly now.

I'm using now my own StringBuilder together with
port.ReadExisting() as you suggested.

The port.ReadLine() sucks!
Using port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(...)
seems to miss fireing some events and the ReadLine()
comes behind.

I must say i'm deeply looking forward to come back
to my Linux environment - it's long time ago i had
to develop in such buggy envrionments like Windows CE
and CF.
I'm used to debug into third party libraries to easily
clarify mysterious behaviour.

regards
Marcel

<ctacke/>

unread,
Jan 25, 2007, 5:25:03 PM1/25/07
to
I don't think there's a bug in CE or the CF here. I think it's eitehr a bug
in your app, or a misunderstanding of how the library works. I've written
code from the UART registers on up through a C# serial app, so that it was
my code 100% from the app to the silicon and it works as expected. Where
people get into trouble is when they don't understand how things work along
the way.

ReadLine probably works just as intended - it looks at the CF class buffer
and returns all data to the next line feed. The DataReceived event is
probably also working fine. My guess is that the DataReceived happens
before you get all the data you're expecting in the buffer (not before all
of the data that should be there, but before your expectation) and then
you're going in and reading it and getting not what you expected.

Serial is fun becasue there are 3 buffers data is going through before it
even gets to your app (UART FIFO, Driver FIFO, managed Port class FIFO) and
a hardware interrupt at the silicon saying it has data will always happen
before the data that caused it is in that 3rd buffer. That's not CE or the
CF, that's physics.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--

"Marcel Ruff" <m...@marcelruff.info> wrote in message
news:epahan$7n8$1...@online.de...

Robert Janik

unread,
Jan 28, 2007, 7:58:25 PM1/28/07
to
I'm glad it helped.
It is sometimes a little bit difficult to figure out how libraries work
(when you don't have source code) and how we should use them. I'm also
thinking of moving my GPS application over to the linux platform. It doesn't
mean that it couldn't work on WinCE. It is a good platform to verify my GPS
project, development is really fast. However Windows is aimed for consumer
market and I need something a little bit different.

"Marcel Ruff" <m...@marcelruff.info> wrote in message

news:epahan$7n8$1...@online.de...

Marcel Ruff

unread,
Jan 29, 2007, 2:26:58 PM1/29/07
to
Robert Janik wrote:
> I'm glad it helped.
> It is sometimes a little bit difficult to figure out how libraries work
> (when you don't have source code) and how we should use them. I'm also
> thinking of moving my GPS application over to the linux platform. It doesn't
> mean that it couldn't work on WinCE. It is a good platform to verify my GPS
> project, development is really fast. However Windows is aimed for consumer
> market and I need something a little bit different.

I'm just playing with a Motorola A780 mobile which has
GPS along - very cool!

It is based on Linux kernel 2.4, i'm wondering what i will
experience on that platform ...

regards
Marcel

Marcel Ruff

unread,
Jan 29, 2007, 2:30:42 PM1/29/07
to
<ctacke/> wrote:
> I don't think there's a bug in CE or the CF here. I think it's eitehr a bug
> in your app, or a misunderstanding of how the library works. I've written
> code from the UART registers on up through a C# serial app, so that it was
> my code 100% from the app to the silicon and it works as expected. Where
> people get into trouble is when they don't understand how things work along
> the way.
>
> ReadLine probably works just as intended - it looks at the CF class buffer
> and returns all data to the next line feed. The DataReceived event is
> probably also working fine. My guess is that the DataReceived happens
> before you get all the data you're expecting in the buffer (not before all
> of the data that should be there, but before your expectation) and then
> you're going in and reading it and getting not what you expected.
>
> Serial is fun becasue there are 3 buffers data is going through before it
> even gets to your app (UART FIFO, Driver FIFO, managed Port class FIFO) and
> a hardware interrupt at the silicon saying it has data will always happen
> before the data that caused it is in that 3rd buffer. That's not CE or the
> CF, that's physics.

You seem to have deep understanding of the implementation details,
for me it was just not possible to look behind the curtain of closed
source. Where to you gather those informations from?

The good thing is the excellent responsiveness of this newsgroup
which helps a lot - thanks.

Marcel

<ctacke/>

unread,
Jan 29, 2007, 7:39:32 PM1/29/07
to
None of what I did was closed. MS provides a sample serial driver with
Platform Builder, and it's most often used with little modification and the
CEPC BSP has a full working driver. The managed serial code I wrote an
published on MSDN and in OpenNETCF's SDF 1.4 - so that's still freely
available.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--

"Marcel Ruff" <m...@marcelruff.info> wrote in message

news:epli42$cku$1...@online.de...

0 new messages