This project is read-only.

GPS.NET 3.0.1 on CF3.5 Broken?

Feb 17, 2010 at 2:23 AM
Edited Feb 17, 2010 at 2:24 AM

Hi All,

I am pulling my hair out here, can anyone explain to me why this code compiled against the last retail version of GPS.NET (v2.3.20.0) works perfectly:

using System;
using System.Windows.Forms;
using GeoFramework.IO.Serial;
using GeoFramework.Gps.Nmea;

namespace SmartDeviceProject1
{
    public partial class Form1 : Form
    {
        public delegate void MethodInvoker();

        SerialDevice sd;
        NmeaInterpreter n;

        public Form1()
        {
            InitializeComponent();

            GeoFramework.Licensing.GeoFrameworksLicenseProvider.AddLicense("snip");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            sd = new GeoFramework.IO.Serial.SerialDevice(
               CommunicationPort.Com1,
               BaudRate.Baud4800,
               GeoFramework.IO.Serial.DataBits.Eight,
               GeoFramework.IO.Serial.Parity.None,
               GeoFramework.IO.Serial.StopBits.One,
               GeoFramework.IO.Serial.FlowControl.None);

            n = new NmeaInterpreter();
            n.SentenceReceived += new NmeaSentenceEventHandler(n_SentenceReceived);
            n.BaseStream = sd.GetHardwareStream();
            n.Start();         
        }

        void n_SentenceReceived(object sender, NmeaSentenceEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    label1.Text = e.Sentence.ToString();
                }));
            }
            else
                label1.Text = e.Sentence.ToString();
        }
    }
}

Yet, this code (adjusted to work with the new name spaces, etc) compiled against the latest open source version of GPS.NET (v3.0.1.30607) is broken:

using System;
using System.Windows.Forms;
using GeoFramework.Gps.IO;
using GeoFramework.Gps.Nmea;

namespace SmartDeviceProject2
{
    public partial class Form1 : Form
    {
        public delegate void MethodInvoker();

        SerialDevice sd;
        NmeaInterpreter n;

        public Form1()
        {
            InitializeComponent();           
        }

        private void button1_Click(object sender, EventArgs e)
        {
            sd = new SerialDevice("COM1", 4800);

            n = new NmeaInterpreter();
            n.SentenceReceived += new EventHandler<NmeaSentenceEventArgs>(n_SentenceReceived);
            n.Start(sd);
        }

        void n_SentenceReceived(object sender, NmeaSentenceEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    label1.Text = e.Sentence.ToString();
                }));
            }
            else
                label1.Text = e.Sentence.ToString();
        }
    }
}

resulting in:

The interpreter could not be started.  Win32Exception
   at GeoFramework.Gps.Interpreter.Start(Device device)
   at SmartDeviceProject2.Form1.button1_Click(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.ButtonBase.WnProc(WM wm, Int32 wParam, Int32 lParam)
   at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
   at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
   at System.Windows.Forms.Application.Run(Form fm)
   at SmartDeviceProject2.Program.Main()

I've also tried instantiating sd with all of the following:

sd = new SerialDevice("COM1:", 4800);
sd = new SerialDevice("1", 4800);
sd = new SerialDevice("\\\\.\\COM1", 4800);

I'm testing with very standard hardware. Any other GPS Util I download can communicate fine the GPS on COM1.

Any help is greatly appreciated!

-Steve

 

 

 

May 3, 2010 at 7:14 PM
Edited May 3, 2010 at 7:23 PM

Hello!

After having the exact same problems and having waited some time for an official answer, I decided to try for my self.

I've tested the same device with OpenNetCF Library without any problem, so the problem was, without any doubt in the GPS.Net.

There were two problem detected:

1. For same reason (OpenNetCF also has this behaviour), SetupComm always return FALSE!
Under serialstream.cs,

        public override void SetLength(long value)
        {
            // Pass along the buffer size to the port
            _Result = NativeMethods.SetupComm(_Handle, (uint)value, (uint)value);
            // if (!_Result) CheckError(); <-------- Comment This
        }

2. The other problem was in the CreateFile method in SerialStream constructor. In Windows CE, the access must be GENERIC_READ, GENERIC_WRITE, and so on and not using the FileAccess enum. This way, it doesn't work.

My solution :
Under serialstream.cs,

 

        public SerialStream(string portName, int baudRate, FileAccess access, FileShare sharing)
        {
            try
            {
                // Remember the port name and baud rate
                _PortName = portName;
                _Access = access;
                BaudRate = baudRate;

                // Open a connection to the port
                //_Handle = NativeMethods.CreateFile( <----- Comment old call
                //    portName,
                //    access,
                //    sharing,
                //    0,
                //    FileMode.Open,
                //    FileAttributes.Normal,
                //    IntPtr.Zero);

                uint Access = 0x80000000;
                switch (access)
                {
                    case FileAccess.Read :
                        Access = 0x80000000;
                        break;
                    case FileAccess.Write :
                        Access = 0x40000000;
                        break;
                    case FileAccess.ReadWrite :
                        Access = 0x40000000 | 0x80000000;
                        break;
                }

                _Handle = NativeMethods.CECreateFile(
                    portName,
                    Access,
                    sharing,
                    0,
                    FileMode.Open,
                    FileAttributes.Normal,
                    IntPtr.Zero);
..... and, in NativeMethods.cs, add : 
        [DllImport(Kernel32, EntryPoint = "CreateFile", SetLastError = true)]
        public static extern IntPtr CECreateFile(
            String lpFileName, UInt32 dwDesiredAccess, FileShare dwShareMode,
            uint lpSecurityAttributes, FileMode dwCreationDisposition, FileAttributes dwFlagsAndAttributes,
            IntPtr hTemplateFile);
This may not be the most elegant way, but for my problem, it works!
Hope someone places the correction in the official release! 
Regards, 
Joao
Sep 22, 2010 at 4:33 AM
Edited Sep 22, 2010 at 4:33 AM

Thank you Joao!

I'm just revisiting this (trying to upgrade our application to the latest version of GPS.NET), and although a new version (3.0.2) has since been released, the problem remains. Your solution above solves the issue.

-Steve