|
|
View previous topic :: View next topic |
Author |
Message |
ccs_user
Joined: 16 Feb 2019 Posts: 5
|
incorrect GPS output result |
Posted: Sun Feb 17, 2019 8:17 am |
|
|
Hi, I'm new to this forum. I'm using PIC16F887 to get the time from GPS, store it & send it through RS232.
I get the correct output from GPS if connected directly to RS232
But when I connect it to MCU, I get the following result after displaying MCU output on PC:
Quote: |
GPS Time: 44
GPS Time: 146
GPS Time: 53
GPS Time: 183
GPS Time: 241
GPS Time: 0
|
I have tried all possible changes that could cause the issue but it seems that it does not work. Can someone help me in this matter, please? It is supposed to be simple but this is confusing me as I'm not sure where it is going wrong.
Code: |
#include <16F887.h>
#USE delay(internal=8MHz)
#USE RS232 (BAUD=9600,XMIT=PIN_C6,RCV=PIN_C7)
int i;
unsigned char in_char,start_[5],time_gps[5];
VOID main()
{
in_char = getc();
if(in_char == '$')
{
for(i=0; i<6; i++){
in_char = getc();
start_[i] = in_char;
}
if((start_[3] == 'G' && start_[4] == 'A'))
{
for(i=0; i<6; i++)
{
in_char = getc();
time_gps[i] = in_char;
}
}
}
for(i=0;i<6;i++){
printf("GPS Time: ");
printf("%u",time_gps[i]);
printf("\r\n");
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19596
|
|
Posted: Sun Feb 17, 2019 8:52 am |
|
|
44 is the ASCII value of ','.
You need to first skip this character as well (so read seven characters),
and then convert the ASCII being received into numeric format.
Look at atoi and atol, which convert ASCII strings. |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sun Feb 17, 2019 9:24 am |
|
|
You can use the functions inside string.h to help read these inputs. You can use strtok or strchr to help you isolate the time strings from the overall message. You can always manually copy out the number in the rs232 message, but if you use atoi, atol or atof, you must remember that the strings you use in those functions must be null terminated... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19596
|
|
Posted: Sun Feb 17, 2019 9:26 am |
|
|
There is also another issue. Not enough characters.
You read six characters in each loop (0....5), but have dimensioned your
receive arrays to hold 5. Result these will overflow, and other things
will get overwritten. |
|
|
ccs_user
Joined: 16 Feb 2019 Posts: 5
|
|
Posted: Sun Feb 17, 2019 9:33 am |
|
|
Ttelmah wrote: | 44 is the ASCII value of ','.
You need to first skip this character as well (so read seven characters),
and then convert the ASCII being received into numeric format.
Look at atoi and atol, which convert ASCII strings. |
Thank you for the quick reply.
I have tried it but it is giving
Quote: |
*** Error 12 "****\CCS C Projects\GPS\GPS.c" Line 84(18,19): Undefined identifier -- atoi
|
Code: |
int i,n;
unsigned char in_char,start_[6],time_gps[5];
char x;
VOID main()
{
in_char = getc();
if(in_char == '$')
{
for(i=0; i<7; i++){
in_char = getc();
start_[i] = in_char;
}
if((start_[3] == 'G' && start_[4] == 'A'))
{
for(i=0; i<7; i++)
{
in_char = getc();
time_gps[i] = in_char;
}
}
}
for(i=0;i<6;i++){
x = time_gps[i];
n = atoi(x);
printf("GPS Time: ");
printf("%d",n);
printf("\r\n");
}
}
|
|
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sun Feb 17, 2019 9:34 am |
|
|
ccs_user wrote: |
Thank you for the quick reply.
I have tried it but it is giving
Quote: |
*** Error 12 "****\CCS C Projects\GPS\GPS.c" Line 84(18,19): Undefined identifier -- atoi
|
|
I think atoi is inside stdlib.h
You will need to include that with:
#include <stdlib.h> |
|
|
ccs_user
Joined: 16 Feb 2019 Posts: 5
|
|
Posted: Sun Feb 17, 2019 9:55 am |
|
|
dluu13 wrote: | ccs_user wrote: |
Thank you for the quick reply.
I have tried it but it is giving
Quote: |
*** Error 12 "****\CCS C Projects\GPS\GPS.c" Line 84(18,19): Undefined identifier -- atoi
|
|
I think atoi is inside stdlib.h
You will need to include that with:
#include <stdlib.h> |
Now I'm getting this in the output. It's driving me crazy
Quote: |
GPS Time: 0
GPS Time: 0
GPS Time: 0
GPS Time: 0
GPS Time: 0
GPS Time: 0
|
|
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sun Feb 17, 2019 9:58 am |
|
|
It is because you are trying to do atoi on chars instead of a full null-terminated string.
I personally would recommend doing a gets into a large receive buffer such as char* rcv[30] or something. Then you can use strstr to determine whether or not you are getting the CPGGA line.
Finally, you can use strtok to get the time number out as a whole, rather than char by char. Besides, that way, it will give you null-terminated strings. Gimme a few minutes and I can give an (untested) example. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9274 Location: Greensville,Ontario
|
|
Posted: Sun Feb 17, 2019 10:01 am |
|
|
You could also look in the 'code library' here. There's bound to be working code you can 'cut/paste' from.... |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sun Feb 17, 2019 10:12 am |
|
|
This is untested code. But the idea is, just grab the entire string, and then use strstr to check whether or not this is the message you want.
Then, grab the numbers from the message (I am assuming these GPS time messages are always fixed width).
Null terminate the string with the time, and then convert it. Note that I used atol (string to long) and a 32 bit num because normal ints are only 8bit and it is not enough to hold the time, which appears to be a 6 digit number.
Code: | #include <16F887.h>
#USE delay(internal=8MHz)
#USE RS232 (BAUD=9600,XMIT=PIN_C6,RCV=PIN_C7)
#include <stdio.h>
#include <stdlib.h>
char rcv[30];
int32 num;
char time[7];
char * cmp = "GPGGA";
int main(void)
{
while (1)
{
if (kbhit()) // read manual to see how kbhit is used
{
gets(rcv); // puts the incoming string into rcv
if (strstr(rcv, cmp) != 0) //checks to see that this is the GPGGA string
{
for (int i = 0; i < 6; i++)
{
time[i] = rcv[i+7];
}
time[6] = '\0'; // null terminate the time string so you can use atol
num = atol(time);
printf("GPSTIME: %ld\r\n", num);
}
else{}
}
}
} |
|
|
|
ccs_user
Joined: 16 Feb 2019 Posts: 5
|
|
Posted: Sun Feb 17, 2019 10:18 am |
|
|
dluu13 wrote: | This is untested code. But the idea is, just grab the entire string, and then use strstr to check whether or not this is the message you want.
Then, grab the numbers from the message (I am assuming these GPS time messages are always fixed width).
Null terminate the string with the time, and then covert it. Note that I used atol (string to long) and a 32 bit num because normal ints are only 8bit and it is not enough to hold the time, which appears to be a 6 digit number.
Code: | #include <16F887.h>
#USE delay(internal=8MHz)
#USE RS232 (BAUD=9600,XMIT=PIN_C6,RCV=PIN_C7)
#include <stdio.h>
#include <stdlib.h>
char rcv[30];
int32 num;
char time[7];
char * cmp = "GPGGA";
int main(void)
{
while (1)
{
if (kbhit()) // read manual to see how kbhit is used
{
gets(rcv); // puts the incoming string into rcv
if (strstr(rcv, cmp) != 0) //checks to see that this is the GPGGA string
{
for (int i = 0; i < 6; i++)
{
time[i] = rcv[i+7];
}
time[6] = '\0'; // null terminate the time string so you can use atol
num = atol(time);
printf("GPSTIME: %ld\r\n", num);
}
else{}
}
}
} |
|
This is another way to it. I'll try it and let you know how it goes.
Thanks again for your input. |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sun Feb 17, 2019 10:25 am |
|
|
Np,
I forgot to #include <string.h>, which is required for strstr.
I recommend also putting
right after the
That way you can verify that you are getting the right string in.
You can even try
Code: | printf("%s", rcv+7); |
and see what happens :D
I also recommend carefully reading the CCS manual or search the internet to read about kbhit, gets, strstr, or any other function that I used if you are unsure what they do.
Finally, if you plan on using peripherals with RS232 communications with strings like this GPS module, I recommend getting very familiar with the string.h library. |
|
|
ccs_user
Joined: 16 Feb 2019 Posts: 5
|
|
Posted: Tue Feb 19, 2019 1:03 pm |
|
|
dluu13 wrote: | This is untested code. But the idea is, just grab the entire string, and then use strstr to check whether or not this is the message you want.
Then, grab the numbers from the message (I am assuming these GPS time messages are always fixed width).
Null terminate the string with the time, and then convert it. Note that I used atol (string to long) and a 32 bit num because normal ints are only 8bit and it is not enough to hold the time, which appears to be a 6 digit number.
Code: | #include <16F887.h>
#USE delay(internal=8MHz)
#USE RS232 (BAUD=9600,XMIT=PIN_C6,RCV=PIN_C7)
#include <stdio.h>
#include <stdlib.h>
char rcv[30];
int32 num;
char time[7];
char * cmp = "GPGGA";
int main(void)
{
while (1)
{
if (kbhit()) // read manual to see how kbhit is used
{
gets(rcv); // puts the incoming string into rcv
if (strstr(rcv, cmp) != 0) //checks to see that this is the GPGGA string
{
for (int i = 0; i < 6; i++)
{
time[i] = rcv[i+7];
}
time[6] = '\0'; // null terminate the time string so you can use atol
num = atol(time);
printf("GPSTIME: %ld\r\n", num);
}
else{}
}
}
} |
|
Hi again dluu13,
I've been busy at work and I was free few hours ago so, resumed working on this.
I appreciate your replies as comments really helped.
Below is the final code:
Code: |
char rcv[50];
int i=0;
int8 hh[3],mm[3],ss[3],gpshh,gpsmm,gpsss;
char start_[7],in_char;
VOID main(void)
{
while(1){
switch (kbhit())
{
case 1:
in_char = getc();
if(in_char == '$')
{
for(i=0; i<6; i++){
in_char = getc();
start_[i] = in_char;
}
if((start_[3] == 'G' && start_[4] == 'A'))
{
gets(rcv);
printf("%s\r\n", rcv);
for(int i=0; i<3;i++){
hh[i] = rcv[i];
hh[2] = '\0';
gpshh = atoi(hh);
}
for(int i=0; i<3;i++){
mm[i] = rcv[i+2];
mm[2] = '\0';
gpsmm = atoi(mm);
}
for(int i=0; i<3;i++){
ss[i] = rcv[i+4];
ss[2] = '\0';
gpsss = atoi(ss);
}
printf("\r\nGPS TIME: %d:%d:%d\r\n",gpshh,gpsmm,gpsss);
}
break;
}
case 0:
break;
}
}
}
|
|
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Tue Feb 19, 2019 1:29 pm |
|
|
Glad to hear you have it working now.
Again though, if you will be using peripherals with rs232, I highly recommend learning the RS232 functions and macros provided by CCS, and learning how to store/manipulate/parse strings. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Feb 28, 2019 1:30 am |
|
|
dluu13 wrote: | Glad to hear you have it working now.
Again though, if you will be using peripherals with rs232, I highly recommend learning the RS232 functions and macros provided by CCS, and learning how to store/manipulate/parse strings. |
Amen -- and ideally, that previous program would be best suited as an ISR (interrupt service routine) driven serial receiver.
Good times....
-Ben
p.s. don't forget to edit this post's topic to include "SOLVED" _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|