View previous topic :: View next topic |
Author |
Message |
gamal eldeen
Joined: 29 May 2012 Posts: 29 Location: Alexandria - Egypt
|
GPS display on 16*2 lcd code |
Posted: Mon Jul 16, 2012 5:23 pm |
|
|
Hi, I want to display the latidute and longitude of GPGGA string -NMEA of GPS(skynav-SKG12A) on 16*2 lcd (lcm16020).
But the data that displayed on lcd is wrong.
This is an example of my code to show the latitude only.
Code: |
#include <16F887.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1) |
Code: |
#include <12-07-gps.h>
#include <flex_lcd.h>
unsigned char data,value=0;
unsigned int i=0;
//char gps[48];
char lat[12];
void main()
{
SET_TRIS_B( 0x00 );
OUTPUT_B(0x00);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
lcd_init();
while(1)
{
if (kbhit())
data = fgetc(PORT1); // Check the string '$GPGGA,'
if(data=='$')
{
if (kbhit())
data = fgetc(PORT1);
if(data=='G')
{
if (kbhit())
data = fgetc(PORT1);
if(data=='P');
{
if (kbhit())
data = fgetc(PORT1);
if(data=='G');
{
if (kbhit())
data = fgetc(PORT1);
if(data=='G')
{
if (kbhit())
data = fgetc(PORT1);
if(data=='A')
{
if (kbhit())
data = fgetc(PORT1);
if(data==',')
{
i=0;
data=0;
for(i=0;data!=',';i++)
{
if (kbhit())
data = fgetc(PORT1);
}
if(data==',')
{
i=0;
data=0;
for(i=0;data!='N';i++)
{
if (kbhit())
data = fgetc(PORT1);
lat[i]=data;
data =0;
}
}
printf(LCD_PUTC,"lati: %u%u%u%u%u%u%u%u%u%u",lat[0],lat[1],lat[2],lat[3],lat[4],lat[5],lat[6],lat[7],lat[8]);
}
}
}
}
}
}
}
}
i=0;
Delay_ms(1000);
for(i=0;i<48;i++)
{
data=0;
lati[i]=0;
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9247 Location: Greensville,Ontario
|
|
Posted: Mon Jul 16, 2012 7:50 pm |
|
|
So what is 'wrong' ???
Is the data from the GPS correct ??
What format is the data ???
How can you tell the data is 'wrong'?
Is it the actual display of figures or are the number wrong?
Please give us an example of the true,correct data and what is displayed.
Also you should always add 'errors' to the use rs232(options....)
hth
jay |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Mon Jul 16, 2012 10:39 pm |
|
|
As an important side note:
MOST GPS's (if not all) put out NMEA data at a rate of 4800, not 9600 bits/sec.
It's actually part of the NMEA standard (You did read up on it, yes?).
Now, that doesn't mean a device (like a GPS) send data at a different rate, but it means you should check your device first.
You did check, right?
Have you considered writing out the TX pin of the PIC debug information to a computer or something? Since the GPS is only using the RX pin... TX could provide valuable debug information for you.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Jul 17, 2012 12:55 am |
|
|
And then there are the obvious errors and remarks: Code: | char lat[12];
...
...
for(i=0;i<48;i++)
{
data=0;
lati[i]=0;
} | You are resetting 48 bytes of data in a 12 byte array. This means data in RAM will be overwritten with all kind of errors as result.
And why set data 48 times to 0? One time should suffice.
Code: | if (kbhit())
data = fgetc(PORT1); // Check the string '$GPGGA,'
if(data=='$') | Check your levels of indentation! It is not a real bug but it makes your code a lot more confusing that you have no extra indent for the line after the if-statements. Like: Code: | if (kbhit())
data = fgetc(PORT1); // Check the string '$GPGGA,'
if(data=='$') | Looking at it now, I think you are missing an '{' at each kbhit line.
Your use of kbhit seems strange to me. For the first fgetc it makes sense because fgetc is blocking and you probably want to do other things, but for the next calls it makes no sense in your current setup because there you want fgetc to be blocking. Now you don't wait and get out of the string sequence test.
I recommend you to read up on state-machines, it is a much more efficient way to detect string sequences. Examples can be found a lot on this forum. Search for code lock examples or EMEA code. |
|
|
gamal eldeen
Joined: 29 May 2012 Posts: 29 Location: Alexandria - Egypt
|
|
Posted: Thu Jul 19, 2012 7:38 am |
|
|
temtronic wrote: | So what is 'wrong' ???
Is the data from the GPS correct ??
What format is the data ???
How can you tell the data is 'wrong'?
Is it the actual display of figures or are the number wrong?
Please give us an example of the true,correct data and what is displayed.
Also you should always add 'errors' to the use rs232(options....)
hth
jay |
........................
i tested the data by a hyper terminal and it shows all nmea strings.
and when i display the latidute data on the lcd it shows a strange character.
...
thanks temtronic |
|
|
gamal eldeen
Joined: 29 May 2012 Posts: 29 Location: Alexandria - Egypt
|
|
Posted: Thu Jul 19, 2012 7:56 am |
|
|
bkamen wrote: | As an important side note:
MOST GPS's (if not all) put out NMEA data at a rate of 4800, not 9600 bits/sec.
It's actually part of the NMEA standard (You did read up on it, yes?).
Now, that doesn't mean a device (like a GPS) send data at a different rate, but it means you should check your device first.
You did check, right?
Have you considered writing out the TX pin of the PIC debug information to a computer or something? Since the GPS is only using the RX pin... TX could provide valuable debug information for you.
-Ben |
..................................................
i'm already checked my device . and when i connect it to a pc it worked at 9600 bps onlyyyyyyyy ( i'm use a modified GPS - gps with serial rs232 cable )
>>>
i'm already get the data from the GPS on pic and send it again to pc ... it shows the same random data ( that appears on LCD )
...
thanks bkamen |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Thu Jul 19, 2012 8:01 am |
|
|
One thing I normally do if I have any kind of display (LCD in this case) is print some sort of "Hello World" (or "mikeys test2" etc) to the display when I first power up - that verifies to me that at least I am talking to the LCD correctly. You don't indicate (and there is nothing in your code) if you have verified that you are actually talking to the LCD correctly. I love test messages and blinking LED's since they give me a clue where I am having problems. Have you verified that you can talk to the LCD and get the expected results with a sample string or something ? (LCD's can act very odd if you don't get them initialized properly).
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
gamal eldeen
Joined: 29 May 2012 Posts: 29 Location: Alexandria - Egypt
|
|
Posted: Thu Jul 19, 2012 8:08 am |
|
|
ckielstra wrote: | And then there are the obvious errors and remarks: Code: | char lat[12];
...
...
for(i=0;i<48;i++)
{
data=0;
lati[i]=0;
} | You are resetting 48 bytes of data in a 12 byte array. This means data in RAM will be overwritten with all kind of errors as result.
And why set data 48 times to 0? One time should suffice.
Code: | if (kbhit())
data = fgetc(PORT1); // Check the string '$GPGGA,'
if(data=='$') | Check your levels of indentation! It is not a real bug but it makes your code a lot more confusing that you have no extra indent for the line after the if-statements. Like: Code: | if (kbhit())
data = fgetc(PORT1); // Check the string '$GPGGA,'
if(data=='$') | Looking at it now, I think you are missing an '{' at each kbhit line.
Your use of kbhit seems strange to me. For the first fgetc it makes sense because fgetc is blocking and you probably want to do other things, but for the next calls it makes no sense in your current setup because there you want fgetc to be blocking. Now you don't wait and get out of the string sequence test.
I recommend you to read up on state-machines, it is a much more efficient way to detect string sequences. Examples can be found a lot on this forum. Search for code lock examples or EMEA code. |
...........................................
thanks ckielstra
about 48 loop its an error when i write it to you (i modified my code to make it small and simple ... make it easy for you )
( it's already 12 loop )
...
i think you are right - about '{' - ... but i will try it next week because i'm travelled now.
thanks alot
..........
thanks every body |
|
|
gamal eldeen
Joined: 29 May 2012 Posts: 29 Location: Alexandria - Egypt
|
|
Posted: Thu Jul 19, 2012 8:31 am |
|
|
gpsmikey wrote: | One thing I normally do if I have any kind of display (LCD in this case) is print some sort of "Hello World" (or "mikeys test2" etc) to the display when I first power up - that verifies to me that at least I am talking to the LCD correctly. You don't indicate (and there is nothing in your code) if you have verified that you are actually talking to the LCD correctly. I love test messages and blinking LED's since they give me a clue where I am having problems. Have you verified that you can talk to the LCD and get the expected results with a sample string or something ? (LCD's can act very odd if you don't get them initialized properly).
mikey |
............................................
i'm played on my LCD .
for example : data=$;
printf(LCD_PUTC,"%u",data);
and it shows the $ .
mikey ... what do you think about the '{' that ckielstra talking about ????
( i can't tru it now as i'm now in a different place )
...
thanks alot Mikey |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Thu Jul 19, 2012 10:12 am |
|
|
Hi,
Rather that worry about the '{', I'd consider a wholesale redesign of your
code. First, you should absolutely implement a interrupt-driven serial
receive routine, possibly with a circular buffer. Search the forum, and you'll
find hundreds of examples of how to do this. You will probably also want to
implement a state-machine inside the serial interrupt handler to exclude all
but the desired NMEA sentence.
I've been down this (GPS) road before, and I think you'll find that my
suggestions will provide you with the most robust solution to GPS reception
and display.
Good Luck!
John |
|
|
gamal eldeen
Joined: 29 May 2012 Posts: 29 Location: Alexandria - Egypt
|
|
Posted: Wed Jul 25, 2012 2:37 am |
|
|
ok
Now, I changed 3 things and the nmea string is appears correctly :
1. I changed the frequency from 20mhz to 4mhz.
2. I changed the baud rate from 9600 to 4800bps.
( why??????? .... as when i connect the GPS to a hyper terminal of PC .. it worked at 9600bps only ?????? ).... but thanks bkamen .
3. I completed the missing of '{' ....... thanks ckielstra .
4. I changed the Code: | printf(LCD_PUTC,"%u",lat[0]); | to Code: | printf(LCD_PUTC," %c",lat[0]); | .....thanks gpsmikey .
......................
but .....wait
......................
The success is on a simple display code ... not my complete code.
As when I wrote:
Code: |
while(1)
{
if (kbhit())
{
data = fgetc(PORT1);
printf(LCD_PUTC,"%c",data);
}
}
|
it shows all nmea strings correctly
but when i wrote the next code to build my complete code ... no thing is appears
Code: | while(1)
{
if (kbhit())
{
data = fgetc(PORT1);
if(data=='$')
{
if (kbhit())
{
data = fgetc(PORT1);
if(data=='G')
{
if (kbhit())
{
data = fgetc(PORT1);
printf(LCD_PUTC,"%c",data);
Delay_ms(1000);
}
}
}
}
}
}
|
help please |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Wed Jul 25, 2012 2:56 am |
|
|
gamal eldeen wrote: |
2. I changed the baud rate from 9600 to 4800pbs.
( why??????? .... as when i connect the GPS to a hyper terminal of PC .. it worked at 9600pbs only ?????? ).... but thanks bkamen .
|
That's fine -- as long as you have verified that 9600 is the right bit rate.
Moving along.
Quote: |
Code: |
data = fgetc(PORT1);
printf(LCD_PUTC,"%c",data);
Delay_ms(1000);
|
|
WHY oh WHY are you putting in a blocking 1second delay!?!? NOooooooooooooooooooooooooooo.
This is so very bad.
You should be collecting every string and then looking for a match if it's the string you want and then parsing out the information you want.
You have a very incomplete state machine. If I just looked at that alone, I would guess your results are going to be unpleasant to say the least.
If you look in the code library, there's lots of examples on how to do this the right way.
Additionally, run the PIC as fast as you can if your not bound by power/performance issues.
And in your original post, the comments are going to confuse you.
The speed of the device is not based on the compiler. It's based on the crystal you use, the device type and how fast you can make it run between those things. PCD has nothing to do with 10MHz. the DEVICE does. PCD is just for 16bit parts. Same rules for PCB/M/H -- it's all about the device.
Cheers,
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
gamal eldeen
Joined: 29 May 2012 Posts: 29 Location: Alexandria - Egypt
|
|
Posted: Wed Jul 25, 2012 3:33 am |
|
|
bkamen wrote: |
That's fine -- as long as you have verified that 9600 is the right bit rate.
|
as when i connect the GPS to a hyper terminal of PC .. it worked at 9600bps only ??????
bkamen wrote: |
WHY oh WHY are you putting in a blocking 1second delay!?!? NOooooooooooooooooooooooooooo.
|
... just to see the data ...as i can't see any thing on the display... i removed it and no thing.
Quote: |
You should be collecting every string and then looking for a match if it's the string you want and then parsing out the information you want. |
ok, i will try ... but what about parsing out the nmea string ... as i want $GPGGA message only and then extract my wanted data ?!
thanks Ben ... i will try |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jul 25, 2012 5:56 am |
|
|
gamal eldeen wrote: | bkamen wrote: |
That's fine -- as long as you have verified that 9600 is the right bit rate.
|
as when i connect the GPS to a hyper terminal of PC .. it worked at 9600bps only ?????? | Most GPS modules work at 4800 baud but it is very well possible your device is operating at 9600 baud. The specification of the SkyNav SKG12A is inconsistent. On page 3 it says the default baud rate is 4800bps, but on page 8 it is 9600bps.
If you got it working with your pc at 9600 baud then I guess 9600 baud is the correct speed.
Then I'm confused about your speed settings in the CCS compiler. What is the frequency of the crystal you have connected to the PIC?
This should be the same value you use in the #USE DELAY line.
Quote: | ... but what about parsing out the nmea string ... as i want $GPGGA message only and then extract my wanted data ?! | Easiest solution is to search this forum for people having tackled the same issue:
- Check the programs posted in the Code Library section of this forum.
- Use the search function of this forum and search for 'NMEA'
- Use google |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Wed Jul 25, 2012 7:48 am |
|
|
gamal eldeen wrote: |
ok, i will try ... but what about parsing out the nmea string ... as i want $GPGGA message only and then extract my wanted data ?!
|
Exactly.
Save the whole sentence... looking for $GPGGA on the front. If it doesn't have it, reset the state machine and wait for the next string.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|