Quantcast
Channel: FiveTech Software tech support forums
Viewing all articles
Browse latest Browse all 26212

Rutina para leer Gps

$
0
0
Estimaodos amigos. un saludito fraternal a los listeros. teng dos preguntas. 1 esta rutina podra sr adatada para ser utilzada en fwh porque creo que fue hecha para algun dispositovo movil 2 De ser asi cual seria la libreria para accesar los puertos OpenCom , ComRead ect. gracias desde ya. Gracias al señor /////////////////////////////////////////////////////// // Mini Clase TGps // // Lectura de sentencias NMEA GPGGA y GPRMC de un GPS // son las necesarias para conocer fecha, hora, posición, velocidad // Probado con GPS bluetooth en Com:8 e IPAQ HP2210 // // Autor: Salvador Gallardo 2007 // #include "FiveWin.ch" Function Main( cCom ) // especifica el puerto como parámetro LOCAL oWnd, oGps, nCom, oTimer DEFAULT cCom := "8" // puerto Com:8 nCom := VAL(cCom) DEFINE WINDOW oWnd TITLE "GPS TEST" oGps := Tgps():New( oWnd ) oTimer := Ttimer():New( 1000, { || UpdateControls( oWnd, oTimer ) }, oWnd ) @ 5, 5 SAY "Fecha" SIZE 53, 20 RIGHT PIXEL @ 5, 60 GET oGps:cDate SIZE 80, 20 WHEN .f. PIXEL OF oWnd @ 5, 145 GET oGps:cTime SIZE 60, 20 WHEN .f. PIXEL OF oWnd @ 27, 5 SAY "Lat." SIZE 53,20 RIGHT PIXEL @ 27, 60 GET oGps:cLat SIZE 80,20 WHEN .f. PIXEL OF oWnd @ 27, 145 GET oGps:cNS SIZE 20,20 WHEN .f. PIXEL OF oWnd @ 50, 5 SAY "Long." SIZE 53,20 RIGHT PIXEL @ 50, 60 GET oGps:cLong SIZE 80,20 WHEN .f. PIXEL OF oWnd @ 50, 145 GET oGps:cEW SIZE 20,20 WHEN .f. PIXEL OF oWnd @ 72, 5 SAY "Lat dec." SIZE 50,20 RIGHT PIXEL @ 72, 60 GET oGps:nLat SIZE 80,20 PICTURE "999.999999" RIGHT; WHEN .f. PIXEL OF oWnd @ 94, 5 SAY "Lon dec." SIZE 50,20 RIGHT PIXEL @ 94, 60 GET oGps:nLong SIZE 80,20 PICTURE "999.999999" RIGHT; WHEN .f. PIXEL OF oWnd @ 118, 5 SAY "Fix" SIZE 50,20 RIGHT PIXEL @ 116, 60 GET oGps:cFix SIZE 30,20 WHEN .f. PIXEL OF oWnd @ 140, 5 SAY "Sats" SIZE 50,20 RIGHT PIXEL @ 138, 60 GET oGps:cSats SIZE 30,20 WHEN .f. PIXEL OF oWnd @ 162, 5 SAY "Alt." SIZE 50,20 RIGHT PIXEL @ 160, 60 GET oGps:cAlt SIZE 60,20 WHEN .f. PIXEL OF oWnd @ 184, 5 SAY "Veloc." SIZE 50,20 RIGHT PIXEL @ 182, 60 GET oGps:cSpeed SIZE 60,20 WHEN .f. PIXEL OF oWnd @ 204, 5 GET oGps:cNMEA SIZE 232,40 WHEN .f. MULTILINE; NO VSCROLL PIXEL OF oWnd @ 258, 5 BUTTON "CONECTAR" SIZE 95, 25 PIXEL; ACTION ( oGps:Conecta( nCom ), oTimer:Activate()); @ 258, 110 BUTTON "DESCONECTAR" SIZE 95, 25 PIXEL; ACTION ( oTimer:Deactivate(), oGps:Desconecta() ) ACTIVATE WINDOW oWnd; VALID ( oTimer:End(), oGps:end(), .t.) RETURN .t. /////////////////////////////////////////////////////// // Mini Clase TGps // // Lectura de sentencias NMEA GPGGA y GPRMC de un GPS // son las necesarias para conocer fecha, hora, posición, velocidad // Probado con GPS bluetooth en Com:8 e IPAQ HP2210 // // Autor: Salvador Gallardo 2007 // /////////////////////////////////////////////////////// #define LENNMEA 1024 // longitud cadena leida 3 sentencias minimo #define READINTERVAL 1500 // intervalo de lectura del puerto en ms. #define NRETRY 10 // reintentos de lectura del puerto #define BAUDS 4800 // velocidad de recepcion CLASS TGps DATA lGps // hay conexion con el gps DATA oTimer // intervalo de tiempo para leer el puerto DATA oWnd // ventana asociada los timers estan asociados a una window DATA aNMEA // array con las sentencias nmea leidas DATA cNMEA // ultima sentencia interpretada DATA cTime // hora DATA cDate // fecha DATA cLat, cLong // latitud y longitud en formato //dddmm.mmmm,ddddmm.mmmm DATA cNS, cEW // indicadores de N/S E/O DATA nLat, nLong // latitud y longitud en formato decimal dd.mmmmmmmm DATA cFix // fix del gps 0= invalido 1= valido DATA cSats // satelites usados DATA cAlt // altitud DATA cSpeed // velocidad DATA CMsgErr // guarda estado conexion con gps DATA nHdlCom // handle del puerto de comunicaciones DATA nRetry // reintentos sin recibir datos del GPS DATA lLog // hace log de los datos en una dbf METHOD New( oWnd ) CONSTRUCTOR METHOD Conecta( nCom ) METHOD Desconecta( ) METHOD LeeNMEA() // lee datos del gps METHOD GPGGA( cCad ) // procesa sentencia GPGGA METHOD GPRMC( cCad ) // procesa sentencia GPRMC METHOD End() ENDCLASS METHOD New( oWnd ) CLASS TGps ::aNMEA := Array(3) // se leen 3 sentencias cada vez ::lGps := .f. ::cMsgErr := "INIT" ::oWnd := oWnd ::nRetry := 0 ::oTimer := TTimer():New( READINTERVAL, { || ::LeeNMEA()}, ::oWnd ) ::lLog := .f. ::nLat := 0 ::nLong := 0 RETURN self //////////////////////////////////////////////////////////////// METHOD Conecta( nCom ) CLASS TGps ::nHdlCom := OpenCom( nCom, BAUDS ) IF ::nHdlCom < 0 ::lGps := .f. ::cMsgErr := "FALLO AL ABRIR EL COM:"+ Str( nCom,2 ) ENDIF ::cMsgErr := "PUERTO ABIERTO" ::oTimer:Activate() RETURN nil ///////////////////////////////////////////////////////////////// METHOD DesConecta() CLASS TGps ::oTimer:Deactivate() ComClose( ::nHdlCom ) ::lGps := .f. ::cMsgErr := "DESCONECTADO DEL GPS" RETURN nil ////////////////////////////////////////////////////////////////// // // LeeNMEA() // Lee el puerto y si hay datos los interpreta /////////////////////////////////////////////////////////////////// METHOD LeeNMEA() CLASS TGps LOCAL c, cBuffer ::oTimer:Deactivate() cBuffer := ComRead( ::nHdlCom, LENNMEA ) IF Len( cBuffer ) <= 0 ::nRetry ++ IF::nRetry > NRETRY ::lGps := .f. ::cMsgErr := "PERDIDA CONEXION" ENDIF ELSE ::nRetry := 0 FOR c := 1 TO LEN( ::aNMEA ) ::aNMEA[c] := StrToken( cBuffer, c, "$" ) NEXT FOR c := LEN( ::aNMEA ) TO 1 STEP -1 // leemos ultimas sentencias DO CASE CASE AT( "GPGGA", ::aNMEA[c] ) ==1 IF ChkSum( ::aNMEA[c] ) ::cNMEA := ::aNMEA[c] ::GPGGA( ::aNMEA[c] ) ENDIF EXIT CASE AT( "GPRMC", ::aNMEA[c] ) ==1 IF ChkSum( ::aNMEA[c] ) ::cNMEA := ::aNMEA[c] ::GPRMC( ::aNMEA[c] ) ENDIF EXIT ENDCASE NEXT ENDIF ::oTimer:Activate() RETURN nil ////////////////////////////////////////////////////////////// // // GPGGA( cCad ) // Extrae los datos de una sentencia GPGGA //////////////////////////////////////////////////////////// METHOD GPGGA( cCad ) CLASS TGps LOCAL cHora, nLat, nLon, nGrados, nMinutos SET DECIMALS TO 6 cHora := StrToken( cCad, 2, "," ) ::cTime := Substr( cHora,1,2)+":"+Substr( cHora,3,2)+":"+Substr( cHora,5,2) ::cLat := StrToken( cCad, 3, "," ) ::cNS := StrToken( cCad, 4, "," ) ::cLong := StrToken( cCad, 5, "," ) ::cEW := StrToken( cCad, 6, "," ) ::cFix := StrToken( cCad, 7, "," ) ::cSats := StrToken( cCad, 8, "," ) ::cAlt := StrToken( cCad, 10, "," ) // calculamos latitud y longitud en decimal // es la que utiliza Google Maps nGrados := Val(SubStr( ::cLat, 1, 2) ) nMinutos := Val(SubStr( ::cLat, 3, 7) ) /60 ::nLat := nGrados+ nMinutos* IIF( ::cNS ="S", -1, 1 ) // longitud nGrados := Val(SubStr( ::cLong, 1, 3 ) ) nMinutos := Val(SubStr( ::cLong, 4, 7 ) ) /60 ::nLong := nGrados+ nMinutos* IIF( ::cNS ="W", -1, 1 ) ::lGps := .t. ::cMsgErr := "OK" // log de los datos leidos // hay que mejorar la gestion de la dbf // añadir fecha y hora IF ::lLog .AND. VAL( ::cFix ) != 0 use (CURDIR()+"\gps.dbf" ) VIA "DBFCDX" append blank replace lon with ::nLong replace lat WITH ::nlat replace fix WITH VAL(::cFix) replace sats WITH val(::cSats) replace clong WITH ::cLong replace cLat WITH ::cLat USE endif RETURN nil //////////////////////////////////////////////////////////// // // GPRMC( cCad ) // Extrae los datos de una sentencia GPRMC //////////////////////////////////////////////////////////// METHOD GPRMC( cCad ) CLASS TGps Local cFecha cFecha := StrToken( cCad, 10, "," ) ::cDate := Substr( cFecha, 1, 2 ) + "/"+ Substr( cFecha, 3, 2) + "/"+ Substr(cFecha, 5, 2 ) ::cSpeed := StrToken( cCad, 8, "," ) ::lGps := .t. ::cMsgErr := "OK" RETURN nil ///////////////////////////////////////////////////////// METHOD End() CLASS TGps ::OTimer:Deactivate() ::oTimer:End() ComClose( ::nHdlCom ) RETURN nil ////////////////////////////////////////////////////////////////////// // ChkSum( cCad ) // // Calcula el checksum de la sentencia NMEA ////////////////////////////////////////////////////////////////////7 STATIC Function ChkSum( cCad ) LOCAL c, nLen, nSum1, nSum2 nLen := AT( "*", cCad ) nSum1 := HexToDec( Substr( cCad, nLen +1, 2 ) ) // el checksum esta apartir de "*" nSum2 := Asc( Substr( cCad, 1, 1 ) ) // cogemos el primer caracter a sumar FOR c := 2 TO nLen -1 nSum2 := nXor( nSum2, Asc( Substr( cCad, c, 1 ) ) ) NEXT RETURN IIF( nSum1 == nSum2, .t., .f. ) ////////////////////////////////////////// // // Actualiza los datos de la ventana ////////////////////////////////////////// Function UpdateControls( oWnd, oTimer ) LOCAL c oTimer:Deactivate() For c = 1 to Len(oWnd:aControls) oWnd:aControls[c]:Refresh() next oTimer:Activate() return .t. /* #pragma BEGINDUMP #include #include #include // funcion de FW adaptada a FWPPC HB_FUNC (HEXTODEC) { LPBYTE pString = ( LPBYTE ) hb_parc( 1 ); WORD w = 0, wLen = hb_parclen( 1 ); BYTE bChar; LONG nHex = 0; while( w < wLen ) { bChar = pString[ w ] ; if ( bChar >= 97 ) bChar -= 39; // lowercase if ( bChar >= 65 ) bChar -= 7 ; // uppercase bChar -= 48; nHex += bChar * pow( 16, wLen - w - 1 ); w++; } hb_retnl( nHex ); } #pragma ENDDUMP

Viewing all articles
Browse latest Browse all 26212

Trending Articles