how to manupulate gps nmea data to float type using pic16f877a

Status
Not open for further replies.

chalani0088

Junior Member level 3
Joined
Jun 19, 2012
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,562
#include <htc.h>

#define RX_PIN TRISC7
#define TX_PIN TRISC6
#define _XTAL_FREQ 4000000


__CONFIG(1,XT & WDTDIS & LVPDIS);

/****** serial comms using USART to comm port ***************/

void serial_setup()
{
SYNC=0; //Asynchronous mode
BRGH=1; //High Speed
SPBRG=25; //9600 bps
SPEN=1; //Enable serial port
CREN=1; //Enable reception
SREN=0; //No effect
TXIE=0; //Desable interrupts
RCIE=0; //disable rx interrupts
TX9=0; //8-bit transmission
RX9=0; //8-bit reception
TXEN=1; // Enable transmission
}

void putch(unsigned char byte)
{
/* output one byte */
while(!TXIF) /* set when register is empty */
continue;
TXREG = byte;
}

unsigned char getch() {
/* retrieve one byte */
while(!RCIF) /* set when register is not empty */
continue;
return RCREG;
}



unsigned char getch();
unsigned char longi_data[12];
unsigned char lati_data[12];
unsigned char data,value=0;
unsigned int i=0,pos;

float latitude;

void main(void){
RX_PIN = 1;
TX_PIN = 0;
unsigned char input1;
unsigned char input2;
unsigned char input3;
serial_setup();
INTCON=0; // purpose of disabling the interrupts.




while(1){

{
data=getch(); // Check the string '$GPGGA,'
if(data=='$')
{
data=getch();
if(data=='G')
{
data=getch();
if(data=='P');
{
data=getch();
if(data=='G');
{
data=getch();;
if(data=='G')
{
data=getch();
if(data=='A')
{
data=getch();
if(data==',')
{
data=getch();
while(data!=',')

data=getch();

for(i=0;data!='N';i++)
{ data=getch();
lati_data=data; // Store the Latitude data

putch(data);
}
} data=getch();
if(data==',')
{
for(i=0;data!='E';i++)
{
data=getch();

longi_data=data; // Store the Longitude data
putch(data);
}
}




i=0;

while(i<11)
{
PORTB=lati_data; // Print the Latitude data

i++;
}

i=0;

while(i<12)
{
PORTD=longi_data; // Print the Longitude data


i++;
}





}









}
}
}
}
}
}

__delay_ms(10);
for(i=0;i<12;i++)
{
data=0;
lati_data=0;
longi_data=0;
}
}


}


am doing my final project on gps based warning system for fishermen, and i want to receive gps data into my controller and exctract only the longitudanal and latitudanal data, and then i have to compare it with my previously stored boundaries and make nececsary outputs by comaparing, In my program i could exctract only the longitudanal and latitudanal data , and stored them as character strings. This worked fine and i checked using pic simulator i gave the sentence $GPGGA,100156.000,2650.9416,N,07547.8441,E,1,08,1.0,442.8,M,-42.5,M,,0000*71 to the hardware UART simulation interface and it correctly worked.I am using MPLAB IDE V8.83 and now i want to convert this character string in to numerics in order to compare with my boundaries. It would be grateful if u can help me on this or give any support

Thank you
 

Depends on what libraries you are able to include... the traditional way would be to use sscanf().
If you can't use that, then you'll have to implement your own method... an example would be a loop that traverses the string, and
reads each character up to the decimal point and multiplies by 10000,1000,100,10,1 etc, and then adds to the current sum,
to convert from the ascii decimal representation to a floating point number (and obviously divides by 10, 100 etc after
the decimal point and adds to the sum).
If you're using floating point functions, then bear in mind you need a microcontroller with sufficient memory to handle the math library.
I've no idea concerning specific PIC models.
 



can you please explain if i want to work with sscanf() how should i do that? i downloaded stdio.h header and i include it to my program but it ddint work. do i have to include the source code also?? how should i make work the function sscanf() in my program? please help me on this as i am stucked with my project.

thank you in advance

- - - Updated - - -




can you please explain if i want to work with sscanf() how should i do that? i downloaded stdio.h header and i include it to my program but it ddint work. do i have to include the source code also?? how should i make work the function sscanf() in my program? please help me on this as i am stucked with my project.

thank you in advance
 

It's quite easy, here is an example.


Code:
#include <stdio.h>
int
main(void)
{
  float a,b;
  int i;
  unsigned char gps_snippet[]="$GPGGA,100156.000,2650.9416\0";
  sscanf(gps_snippet, "$GPGGA,%f,%f", &a, &b);

  printf("recovered values were '%f' and '%f'\n", a, b);

  return(0);
}

This is the output:
Code:
./a.out 
recovered values were '100156.000000' and '2650.941650'

Edit:
By the way, that was using float, which worked for the example, but you may need to use double-precision; - I've no idea if you need to.
If you do need to, then replace 'float' with 'double', and replace '%f' with '%lf'.
 
Last edited:



Thank you so much for helping me out to make my project succes. but agin there is a problem when i compiling it gives the error saying


Executing: "C:\Program Files (x86)\HI-TECH Software\PICC\9.83\bin\picc.exe" --pass1 "C:\Users\Chalani\Documents\thiwa\project\sirial nw2\get.c" -q --chip=16F877A -P --runtime=default --opt=default -D__DEBUG=1 -g --asmlist "--errformat=Error [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s"
Warning [171] C:\Users\Chalani\Documents\thiwa\project\sirial nw2\get.c; 8.32 wrong number of preprocessor macro arguments for "__CONFIG" (2 instead of 1)
Executing: "C:\Program Files (x86)\HI-TECH Software\PICC\9.83\bin\picc.exe" -osirial.cof -msirial.map --summary=default --output=default get.p1 --chip=16F877A -P --runtime=default --opt=default -D__DEBUG=1 -g --asmlist "--errformat=Error [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s"
HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.83
Copyright (C) 2011 Microchip Technology Inc.
(1273) Omniscient Code Generation not available in Lite mode (warning)
Error [500] ; 0. undefined symbols:
_getche(sirial.obj) __scanf_buf_(sirial.obj)

********** Build failed! **********


i cant understand the problem! can you please help me out to solve this problem??

thank you again

- - - Updated - - -

the problem is sscanf function not working when i compile it gives error messages! do i have to include stdio.h header and source code! i tried once but it didnt work

thank u
regards
chalani
 

Hard to say, it looks like it it is generating a few warnings, but the error is
Code:
Error [500] ; 0. undefined symbols: _getche(sirial.obj) __scanf_buf_(sirial.obj)
which is presumably during linking. Unfortunately I'm not familiar with the PIC linker+compiler, but
the documentation (or google on that error) should help, or maybe someone else recognises this error.
Also, the
Code:
Omniscient Code Generation not available in Lite mode
is a bit worrying, but again I'm not familiar with it, so maybe it is ok.
 


hi,
i found a way to get rid of my problem, i used a for loop and switch command to convert my characters in to integers, but again i faced a problem i.e. i couldnt store the decimal point inside my integer array. how to get rid of this problem?




float long_arr[11];

for(i=0; i!=12;i++)
{

switch (lati_data)
{

case '0' :
long_arr=0;
break;
case '1':
long_arr=1;
break;

case '2':
long_arr=2;
break;

case '3':
long_arr=3;
break;
case '4':
long_arr=4;
break;

case '5':
long_arr=5;
break;
case '6':
long_arr=6;
break;

case '7':
long_arr=7;
break;

case '8':
long_arr=8;
break;

case '9':
long_arr=9;
break;
case '.' :
long_arr=0;
break;

}

}
 

Your code isn't converting the character string into an interger. It is converting each individual character into
a number.
If it was doing the correct thing, then you would be multiplying by 10, 100, 1000, etc., depending on the column.
Your code has implemented a 'strcpy' function of sorts (not quite).

Of course you can't store a '.' in a float type. That's like saying "what number is dot."
A dot is not a number.
If your code was doing the correct thing, then you wouldn't be storing a '.'

Here is some example code to look at, to get an idea.
Code:
unsigned char arr[]="1984";
int column=3;
float total=0;
unsigned char ch;
for (i=0; i<4; i++)
{
  ch=arr[i];
  ch=ch-'0';
  
  total=total + ((float)ch) * ((float)10^column);
}

The code is not tested, and possibly 10^column might not compile, so consider it as pseudo-code to
get an idea of the type of thing you should be doing, if you don't want to use the sscanf function.
A good way to replace 10^column is to just have an array of weights, i.e. col_weights[]={1000, 100, 10, 1, 0.1, 0.01}
 
Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…