【物聯網智能網關-06】GPS定位+星圖顯示(WinForm庫應用實例)

在2008年上半年就曾經深刻研究過GPS,當時還覺得已經相對全面的瞭解GPS呢,如今從新拾起去研究GPS技術,發現仍是差了一大截。最初覺得GPS是單向通訊,GPS模塊按照固定的時間間隔發送文本格式的GPS數據。如今才知道GPS不只能夠雙向通訊,還能夠以二進制格式收發數據,而且能夠配置須要發送數據的種類和發送間隔,固然必要的時候,還能夠用專門的工具,更新GPS模塊的固件。git

最初瞭解GPS,是基於WINCE平臺,爲寫一本書而作,詳情請參見《實戰WindowsEmbedded CE 6.0GPS》和《個人第一個WINCE驅動》。後來爲了便於調試,又把程序移植到Windows Mobile手機上(採用.NET精簡框架集的Winform完成,本篇.NET MF界面代碼就是基於原先的這套代碼,稍做改進而來,而底層接收代碼,添加了校驗和更全的GPS命令解析),相關博文請參見《GPS NMEA0183協議解析》。編程

如今從新研究GPS,是爲物聯網網關係統封裝一個GPS庫,最初的時候,購買了幾個低價二手的GPS模塊,可是卻沒法定位,在陽臺附近沒法定位也就算了,可是我直接到空曠的大操場也沒法定位,而且沒有一個星的信號。因此後來只好又購買一個價錢較高,帶有源天線的GPS模塊。windows

這個帶外接天線的模塊果真不錯,信號強度蠻強,可是我在購買的時候犯了一個錯誤,選型的時候,選擇了「4800bps GPRMC數據包輸出,不帶PPS」,因此就只能輸出$GPRMC基本信息了,可是這樣星圖就沒法顯示了。框架

因爲技術支持不在線,因此只好先本身想辦法解決這個問題了。我想應該有兩種思路能夠解決這個問題,一是更新固件。可是這種方法顯然須要技術支持來提供相應固件,若是本身找相關工具和固件進行燒寫,不免會出問題(後來問了技術支持才知道,還得飛一個線,進入燒寫模式才行);二是配置信息輸出。這種方法最方便,問題是,掉電配置就丟失了,可是這個GPS板子帶鈕釦電池,因此問題不大。ide

有了第二種思路,而後網上就進行搜索,果真功夫不負有心人,搜到了以下信息:函數

    NMEA信息輸出控制工具

$PSRF103,00,01,00,01*25<CR><LF>測試

格式說明(Set Serial Port Data Format):spa

Name.net

Example

Unit

Description

Message ID

$PSRF103

 

PSRF103 protocol header

Msg

00

 

0:GGA

1:GLL

2:GSA

3:GSV

4:RMC

5:VTG

6:MSS (If internal beacon is supported)

7:Not defined

8:ZDA (if 1PPS output is supprttd)

9:Not defined

Mod

01

 

0 = Set Rate

1 = Query one time

2 = ABP On

3 = ABP Off

Rate

00

 

Output Rate:

0 = Off

1–255 = seconds between messages

CksumEnable

01

 

0=Disable Checksum

1=Enable Checksum

Checksum

*25

 

 

<CR><LF>

 

 

End of message termination

示例

關閉GGA:

$PSRF103,00,00,01,01*25

設置GGA爲5秒輸出一次:

$PSRF103,00,00,05,01*21

 

關閉GSA:

$PSRF103,02,00,00,01*26

設置GSA爲5秒輸出一次:

$PSRF103,02,00,05,01*23

         可是因爲NMEA有校驗,因此還須要一個專門的工具來設置才行,因此又找到了SiRFLive軟件,這個軟件很不錯,能夠方便的調試GPS模塊。也許是供電的問題,我此次在陽臺測試我原先的GPS模塊,竟然能夠定位成功了。下圖即是該GPS模塊使用SiRFLive軟件進行測試的效果圖。


若是須要配置GPS,直接進入命令發送窗口便可,記得選擇NMEA協議。

修改了相關配置,新購買的GPS果真能夠輸出星圖信息了,在物聯網智能網關上的運行效果圖以下:

GPS庫相關內容我這裏就不細說了,文檔裏面有詳細的說明。我這裏說一下,在.NET Micro Framework平臺,如何進行Winform界面開發(WinForm for .NET MF 功能一覽)。

本實例程序,GPS相關函數一旦執行,會自動把GPS模塊的相關參數賦值到GPS類的相關屬性中去。界面繪圖咱們採用重載Form類的OnPaint方法,爲了不閃爍,咱們還採用了在Windows編程中常見的技巧,就是重載OnPaintBackground方法,不去繪製背景。

         protected override void OnPaint(PaintEventArgse)

    {

        try

        {

            e.Graphics.Clear(Color.Gray);   //繪製背景

            //--------------------------

            //繪製信噪比圖

            DrawSNR(e.Graphics, new Rectangle(2,240 - 80, 320 - 4, 80));

            //繪製星圖

            DrawSatellite(e.Graphics, new Rectangle(10,60, 100, 100));

 

            //狀態

            e.Graphics.DrawString("狀態:" + (GPS.Online ? "已鏈接 " : "未鏈接 ") + (GPS.Manage.AnchorState == "A" ? "已定位" : "未定位"), font, sb, 5, 8);

 

            //座標

            e.Graphics.DrawString("座標:" + GPS.Manage.ToString("D"),font, sb, 5, 25);

            //pb_Graphics.DrawString("座標:" + GPS.Manage.Latitude.ToString()+ " " + NMEA.GPS.Longitude.ToString(), font, newSolidBrush(Color.White), 5, 25);

 

            //時間

            e.Graphics.DrawString("時間:" + GPS.Manage.UTCDateTime.ToString(), font, sb,150, 25);

            //-------------------------------

            //衛星數

            e.Graphics.DrawString("衛星:" + GPS.Manage.SatelliteNum.ToString() + " ", font, sb, 130, 60);

            //定位狀態 0=未定位,1=GPS單點定位固定解,2=差分定位,3=無效PPS4=RTK固定解,5=RTK浮點解,6=估計值,7=手工輸入模式,8=模擬模式

            e.Graphics.DrawString("狀態:" + strState[GPS.Manage.AnchorSStateEx], font, sb,130, 75);

            //獲取定位模式(A=自動,M=手動)。

            e.Graphics.DrawString("模式:" + (GPS.Manage.AnchorMode == "A" ? "自動" : "手動"), font, sb, 130, 90);

            //定位類型(1=未定位,2=2D定位,3=3D定位)

            e.Graphics.DrawString("類型:" + strType[GPS.Manage.AnchorType], font, sb, 130,105);

            //海拔

            e.Graphics.DrawString("海拔:" + GPS.Manage.Altitude.ToString("F2") + "("+ GPS.Manage.Height.ToString("F2")+ ")", font, sb, 130, 120);

            //速度

            e.Graphics.DrawString("速度:" + GPS.Manage.KSpeed.ToString("F2"), font, sb, 130, 135);

            //方向

            e.Graphics.DrawString("方向:" + GPS.Manage.Track.ToString("F2"), font, sb, 130, 150);

            //信息

            Microsoft.SPOT.Debug.Print(GPS.ErrorMessage);

        }

        catch {}

    }

具體繪製繪製信噪比圖的代碼以下:

    private void DrawSNR(Graphicse, Rectangle rect)

    {

        Fontfont = new Font("Arial", 9, FontStyle.Regular);

        intFontHeight = 20;

        int SNRHeight= rect.Height - FontHeight;

        intSNRWidth = (rect.Width - FontHeight / 2) / 12;

 

        //繪製信噪比圖

        e.DrawLine(newPen(Color.Gray),rect.Left, rect.Top, rect.Right, rect.Top);

        e.DrawLine(newPen(Color.Gray),rect.Left, rect.Top + SNRHeight / 2, rect.Right, rect.Top + SNRHeight / 2);

        e.DrawLine(newPen(Color.Gray),rect.Left, rect.Top + SNRHeight, rect.Right, rect.Top + SNRHeight);

 

        for (int i = 0; i < 12; i++)

        {

            stringstrPRN = GPS.Manage.Satellite[i].PRN.ToString();

            if(strPRN.Length == 1) strPRN = "0"+ strPRN;

            intHeight = (int)(GPS.Manage.Satellite[i].SNR *SNRHeight / 100);

            intfont_h, font_w;

            font.Value.ComputeExtent(strPRN, out font_w, outfont_h);

 

            //星號

            e.DrawString(strPRN, font, new SolidBrush(Color.White), (int)(rect.Left+ FontHeight / 4 + SNRWidth * i), (int)(rect.Top+ SNRHeight + 4));

 

            //信噪比

            e.FillRectangle(new SolidBrush(Color.Blue), new Rectangle(rect.Left + FontHeight / 4 + SNRWidth *i, rect.Top + SNRHeight - Height, font_w, Height));

        }

    }

繪製星圖的代碼以下:

private voidDrawSatellite(Graphics e, Rectangle rect)

    {

        Fontfont = new Font("Arial", 9, FontStyle.Regular);

 

        int X = rect.Left + rect.Width / 2;

        int Y =rect.Top + rect.Height / 2;

        intSize = (rect.Width > rect.Height ? rect.Height : rect.Width);

        int R =(Size - 12 * 2) / 6;

        int r =8;

 

        e.DrawLine(newPen(Color.Red),X - R * 3 - 12, Y, X + R * 3 + 12, Y);

        e.DrawLine(newPen(Color.Red),X, Y - R * 3 - 12, X, Y + R * 3 + 12);

 

        e.DrawEllipse(newPen(Color.Blue),new Rectangle(X- R, Y - R, R * 2, R * 2));

        e.DrawEllipse(newPen(Color.Blue),new Rectangle(X- R * 2, Y - R * 2, R * 4, R * 4));

        e.DrawEllipse(newPen(Color.Blue),new Rectangle(X- R * 3, Y - R * 3, R * 6, R * 6));

        e.DrawString("N",font, new SolidBrush(Color.White), X + 2, Y - R * 3 - 10);

        e.DrawString("S",font, new SolidBrush(Color.White), X + 2, Y + R * 3 + 2);

        e.DrawString("W",font, new SolidBrush(Color.White), X - R * 3 - 10, Y + 2);

        e.DrawString("E",font, new SolidBrush(Color.White), X + R * 3 + 2, Y + 2);

 

        //繪製衛星位置

        int X0= 0, Y0 = 0, L = 0;

        doubleA1 = 0, A2 = 0;

        StringFormatsFormat = new StringFormat();

        sFormat.Alignment = StringAlignment.Center;

        sFormat.LineAlignment = StringAlignment.Center;

 

        for (int i = 0; i < 12; i++)

        {

            if(GPS.Manage.Satellite[i].PRN > 0)

            {

                A1 =GPS.Manage.Satellite[i].Elevation * Math.PI/ 180;

                A2 =GPS.Manage.Satellite[i].Azimuth * Math.PI /180;

                L = (int)(Math.Cos(A1) * 3 * R);

               X0 = X + (int)(Math.Cos(Math.PI * 5 / 2 - A2) * L);

                Y0 = Y - (int)(Math.Sin(Math.PI * 5 / 2 - A2) * L);

                e.FillEllipse(new SolidBrush(Color.Blue), new Rectangle(X0 - r, Y0 - r, 2 * r, 2 * r));

                e.DrawString(GPS.Manage.Satellite[i].PRN.ToString(),font, new SolidBrush(Color.White), new Rectangle(X0 - r * 2, Y0 - r * 2, 4 * r, 4 * r),sFormat);

            }

        }

 

    }

從以上代碼能夠看出,在.NET Micro Framework系統中開發WinForm程序,和上位機沒有什麼區別,上面的代碼也基本上也能夠在windows桌面.Net程序中直接可使用。

   

下載地址:http://www.sky-walker.com.cn/MFRelease/library/V42/YFSoft.Hardware.GPS.rar

MF簡介:http://blog.csdn.net/yefanqiu/article/details/5711770

MF資料:http://www.sky-walker.com.cn/News.asp?Id=25

相關文章
相關標籤/搜索