CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

incorrect GPS output result

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ccs_user



Joined: 16 Feb 2019
Posts: 5

View user's profile Send private message

incorrect GPS output result
PostPosted: Sun Feb 17, 2019 8:17 am     Reply with quote

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
Quote:

$GPGGA,134950.00,


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: 19195

View user's profile Send private message

PostPosted: Sun Feb 17, 2019 8:52 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sun Feb 17, 2019 9:24 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Sun Feb 17, 2019 9:26 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 17, 2019 9:33 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sun Feb 17, 2019 9:34 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 17, 2019 9:55 am     Reply with quote

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 Rolling Eyes

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

View user's profile Send private message Visit poster's website

PostPosted: Sun Feb 17, 2019 9:58 am     Reply with quote

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: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Feb 17, 2019 10:01 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sun Feb 17, 2019 10:12 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 17, 2019 10:18 am     Reply with quote

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. Smile
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Sun Feb 17, 2019 10:25 am     Reply with quote

Np,

I forgot to #include <string.h>, which is required for strstr.

I recommend also putting
Code:
printf("%s", rcv);

right after the
Code:
gets(rcv);

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

View user's profile Send private message

PostPosted: Tue Feb 19, 2019 1:03 pm     Reply with quote

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. Very Happy

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

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 19, 2019 1:29 pm     Reply with quote

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: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Thu Feb 28, 2019 1:30 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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