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

NMEA GPS messages
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Tue Nov 17, 2020 5:06 pm     Reply with quote

Bkamen,

this looks beautiful.

Regards,
Samo
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Tue Nov 17, 2020 6:44 pm     Reply with quote

PrinceNai wrote:
Bkamen,

this looks beautiful.



You should see it in UltraEdit with syntax highlighting. :D

Seriously though - thank you.

I'm reluctant to post code because I always look at it wondering if a professional would do it that way.

I usually avoid GOTOs, but I thought at the time it was a rare but nice fit.

As the years go by and I keep writing stuff -- especially Verilog for FPGAs, I've been formatting things a certain way that really helps me make code that's visually coherent in a way that I can quickly check a blob for mistakes.


Kinda weird how that works out.

Thanks again. Smile
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
aldina



Joined: 09 Oct 2009
Posts: 26

View user's profile Send private message Send e-mail

PostPosted: Wed Nov 18, 2020 11:46 am     Reply with quote

This drive me crazy....
Code:

#include <16F18323.h>
#FUSES NOLVP   
#FUSES NOWDT                     
#FUSES RSTOSC_HFINTRC
#FUSES NOCLKOUT
#FUSES BROWNOUT, LPBOR, PUT, BORV27     
#FUSES NOPROTECT 
#fuses NOEXTOSC 
#use delay(internal=32000000)
#pin_select U1TX = PIN_C4
#pin_select U1RX = PIN_C5
#use rs232 (UART1, baud = 9600, ERRORS, RECEIVE_BUFFER=128)
#BYTE OSCCON1 = 0x919  // OSCCON register (pg 37 datasheet)
#BYTE WDTCON = 0x97 // WDTCON (pg 27 datasheet)
#include <stdio.h>
#include <stdlib.h>

//Global Variables
int8 speedk, speed;
int8 Dollar_Sign, Got_Data, gsm_state;

#INT_RDA
void isr_gps(void)         
{
   // Variables of INT.
   unsigned char tmp;
   char buffer[10];
   int8 next_in;
   int8 Character_Counter;
   char Nmea_State;
   
   // Inicialise Vars
   tmp = 0x00;
   Character_Counter = 0;
   next_in = 0;
   
   tmp=getc(); // get received char and thus also clear interrupt flag                                       

// ............................................................................                                                                                 
// Process reception through state machine
// Possible data from NMEA module that will be handled is $GPVTG plus data
//
// Actions of this state machine are:
//                 
// Dollar_Sign = 1;            inform MAIN that we have an $
// Got_Data = 1;             inform MAIN we have some data to work on
// main is responsible to clear those flags
                                                                 
  switch (Nmea_State)
  {
 
      // get initial character, '$'                 
      case 0:
      {
         if(tmp == '$')
         { // we have "$", could be "$GPVTG"
            gsm_state = 1; // expecting G
            Dollar_Sign = 1; // inform main we have an $
            //OUTPUT_HIGH(PIN_C3);
         }                                     
         else
            gsm_state = 0;                     
         break;         
      }
     
// ********WE HAVE RECEIVED '$' AS A FIRST CHARACTER ******
// we have "$", expecting G   
      case 1:
      {
         if(tmp == 'G') // have "G"
            gsm_state = 11; // expecting 'P'             
         else
            gsm_state = 0; // reset state machine           
         break;
      }

// we have "$G", expecting 'P'
      case 11: 
      {
         if(tmp == 'P') // expecting 'V'
            gsm_state = 12;     
         else
            gsm_state = 0; // error, reset state machine
         break;         
      }
     
// we have "$GP", expecting 'V'               
      case 12: 
      {
         if(tmp == 'V' ) // expecting 'T'
            gsm_state = 13;
         else
            gsm_state = 0; // error, reset state machine
         break;   
      }   
     
// we have "$GPV", expecting 'T'                 
      case 13: 
      {
         if(tmp == 'T' ) // we have $GPV so far
            gsm_state = 14;
         else
            gsm_state = 0; // error, reset state machine
         break;
      }   
     
// we have "$GPVT", expecting 'G'                 
      case 14: 
      {
         if(tmp == 'G' ) // we have $GPVT so far
            gsm_state = 15; // and now  $GPVTG
         else
            gsm_state = 0; // error, reset state machine
         break;           
      }
     
// we have "$GPVTG", now wait for the N
      case 15:
      {
         if(tmp == 'N')
            gsm_state = 16;
         else   
            gsm_state = 0; // abort, something went wrong
         break;         
      }
     
// we have "$GPVTG...N", now wait for the , character to start recording your data
      case 16:
      {
         if(tmp == ',')
         {
            gsm_state = 17;
            Character_Counter = 0;           
         }
         else
         {
            Character_Counter++; // allow max. x characters before you encounter 'N', otherwise
                                 // you could get stuck here in case of garbled data from the module
            if(Character_Counter == 4) // put your number here!!!!
            {     
               gsm_state = 0; // abort, something went wrong
               Character_Counter = 0;
               next_in = 0;               
            }           
         }
         break;         
      }

      case 17: 
      {
         if(tmp != '.' || tmp != ',')
         { // Record until received.
            buffer[next_in]= tmp; // move received char to the appropriate place in buffer.
            ++next_in; // increment next_in pointer
         
            if(next_in == 10) // prevent rollover
            {       
               next_in=0;                           
            }
         }
         else
         {
            Got_Data = 1; // inform main we have the data
            gsm_state = 0; // reset state machine
            next_in = 0; // go to beginning of the data buffer
            speed = atoi(buffer); // convert buffer data to speed var
         }         
         break;           
      }           
                                                 
   }  // switch brace
}

void main()
{
   enable_interrupts(INT_RDA);
   setup_oscillator(OSC_HFINTRC_32MHZ);
     
   // Configuration of outputs
   output_low(PIN_C0);
   output_low(PIN_C1);
   output_low(PIN_C2);
   output_low(PIN_C3);
   
   // Inicialize Vars
   speedk = 0;
   speed = 0;
   Dollar_Sign = 0;
   Got_Data = 0;
   gsm_state = 0;
   
   while(true)
   { 
      //restart_wdt();
     
      if(speed == 0)
      {
         OUTPUT_high(PIN_C3);
         delay_ms(300);
      }
     
      else if(speed >= 15)  // 15km/h
      {
         OUTPUT_low(PIN_C3);
         delay_ms(300);
      }     
   }
}


I'm using 32MHz now with NOWDT.
I'm only are reading and record data from 'N,' so I'm not recording ',' and transfer with atoi() these data from buffer to an int8 var:
Code:
speed = atoi(buffer);
I think I can use this var speed in main program to turn HIGH or LOW PIN C3.
But it still always ON like before. Maybe I'm using data not so well, right? Or maybe I'm not read only data I need and can't convert with atoi()

Your example seems so clear for me and it is very similar with my purpose and I can not put my idea running :-(

Thank you for your help again.
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Nov 18, 2020 1:18 pm     Reply with quote

One thing I saw is the value you put for character_counter, 4. This is too small. The idea is to count the number of characters AFTER you got $GPVTG and before you encounter 'N'. The format of the data is:
$GPVTG,0.00,T,,M,0.00,N,0.00,K,.... That means you have at least 17 characters before you see 'N', so character counter must be higher than that. But you changed the code, so that might not be the issue, because that counter doesn't count what was intended any more. What surely is a problem is this:

Code:

   // Inicialise Vars
   tmp = 0x00;
   Character_Counter = 0;
   next_in = 0; 


Every time you reach RDA_ISR you set next_in to 0, so I think you only write to the first location of the buffer. All starting values should be declared outside the interrupt. Also the plan with the flags was to only record the data inside ISR and then do the calculations in MAIN and only turn LED's on or off when you get new data. Do you use a debugger, to be able to see what is happening? The contents of the buffer, state variable, next_in and so on? There might also be a problem with NULL (or rather the lack of it) in the buffer. ATOI isn't happy without it at the end of the string. That one I missed in my original code.
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Nov 18, 2020 1:24 pm     Reply with quote

Also case 15 is wrong. If it doesn't see 'N' as the first received character, it goes straight back to waiting for '$' (gsm_state gets reset to 0). You never reach case 16, even if all else works.
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Nov 18, 2020 4:03 pm     Reply with quote

Code:

#include <main.h>

char tmp = 0;
int8 Nmea_State = 0;
int8 gsm_state = 0;
int8 Dollar_Sign = 0;
int8 Character_Counter = 0;
int8 next_in = 0;
#define BUFFER_SIZE 16                       //create 16 byte large buffer
char buffer[BUFFER_SIZE];
int8 Got_Data = 0;

#INT_RDA
void  RDA_isr(void)
{
 tmp=getc();                      // get received char and thus also clear interrupt flag                                       

// ............................................................................                                                                                 
// Process reception through state machine
// Possible data from NMEA module that will be handled is $GPVTG plus data
//
// Actions of this state machine are:
//                 
// Dollar_Sign = 1;            inform MAIN that we have an $
// Got_Data = 1;             inform MAIN we have some data to work on
// main is responsible to clear those flags
                                                                 
  switch (Nmea_State) {
 
//get initial character, '$'                 
      case 0:{                                                                                                   
        if(tmp == '$'){                 //we have "$", could be "$GPVTG"
            gsm_state = 1;                //expecting G
            output_toggle(PIN_C1);     // blink the led every time you get an $
            Dollar_Sign = 1;            // inform main we have an $
        }                                     
         else {                         
            gsm_state = 0;                     
         }
         break;         
            }
//********WE HAVE RECEIVED '$' AS A FIRST CHARACTER***************************
// we have "$", expecting G   
      case 1:{
         if    (tmp == 'G')         //have "G"
               gsm_state = 11;      //expecting 'P'             
         else
            gsm_state = 0;          //reset state machine           
         break;
            }

// we have "$G", expecting 'P'
      case 11:  {
         if(tmp == 'P' )                     // expecting 'V'
            gsm_state = 12;     
         else
            gsm_state = 0;                   //error, reset state machine
         break;         
               }
// we have "$GP", expecting 'V'               
      case 12:  {
         if(tmp == 'V' )                     // expecting 'T'
            gsm_state = 13;
         else
            gsm_state = 0;                   //error, reset state machine
         break;   
     }         
// we have "$GPV", expecting 'T'                  }
      case 13:  {
         if(tmp == 'T' )                     // we have $SGPV so far
            gsm_state = 14;
         else
            gsm_state = 0;                   //error, reset state machine
         break;
     }     
// we have "$GPVT", expecting 'G'                 }
      case 14:  {
         if(tmp == 'G' )   {                  // we have $SGPVT so far
            gsm_state = 15;               // and now  $SGPVTG
      }   
         else
            gsm_state = 0;                   //error, reset state machine
         break;           
               }
// we have "$GPVTG", now wait for the N character to start recording your data
      case 15: {
         if(tmp == 'N'){
            gsm_state = 16;
            Character_Counter = 0;           
         }
         else{
            Character_Counter++;                // allow max. x characters before you encounter 'N', otherwise
                                                // you could get stuck here in case of garbled data from the module
            if (Character_Counter == 20){       // 16 or 17 max. needed till you get 'N'
               gsm_state = 0;                   // abort, something went wrong
               Character_Counter = 0;           // 'N' didn't come in time
               next_in = 0;               
            }           
         }
         break;         
      }
// don't record ',' in the buffer                }
      case 16:  {
         if(tmp == ',' )   {                    // we have $SGPVT so far
            gsm_state = 17;                     // and now  $SGPVTG,
      }   
         else
            gsm_state = 0;                      //error, reset state machine
         break;           
               }     
     

      case 17:  {
        if(tmp != ','){                         //Record data until received comma is received
         buffer[next_in]= tmp;                  // move received char to the appropriate place in buffer.
         ++next_in;                             // increment next_in pointer       
         if(next_in == BUFFER_SIZE - 1) {       // prevent rollover. Numbering in the buffer begins with 0         
         next_in = 0;                           
         }
        }
      else{
         Got_Data = 1;                 // inform main we have the data
         gsm_state = 0;                // reset state machine
         buffer[next_in] = '\n';       // put NULL at the end of the string the buffer for ATOI
         next_in = 0;                  // go to beginning of the data buffer         
      }         
         break;           
     }           
                                                 
   }  // switch brace
}

void main()
{

   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      if(Dollar_Sign){
         Dollar_Sign = 0;           // clear flag
// do one thing     
      }
      if(Got_Data){
         Got_Data = 0;              // clear flag
// do another thing           
      }

   }

}


This should work. Once again, I can't test it, since I don't have a GPS module here. Please note output_toggle(PIN_C1); in state1. The LED should blink every time you get an '$' over the UART. Move this line to other states, so you can see if you even get there. The code was built for 18f46k22, so you'll need to add pin selects at the beginning and chanhe include main.h to whatever name you use for your project.

I can understand your frustration, by the way.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 18, 2020 5:40 pm     Reply with quote

You could test it. Program a 2nd PIC to output a NMEA test stream
at a desired interval. Connect it to your first PIC and test.
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Nov 18, 2020 7:00 pm     Reply with quote

True :-) . Will do it tomorrow.
aldina



Joined: 09 Oct 2009
Posts: 26

View user's profile Send private message Send e-mail

PostPosted: Thu Nov 19, 2020 3:28 am     Reply with quote

Hi PrinceNai,

I follow your recommends, I use: output_toggle(PIN_C1); to see if I'm receiving the correct data, so I can see I have $, than try the same after receive 'G' in case 11 and nothing, LED not blinks.

Confused
temtronic



Joined: 01 Jul 2010
Posts: 9100
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Nov 19, 2020 6:03 am     Reply with quote

I'm with PCMP about a 'controlled' test setup ! Though another PIC sending NMEA data will work, probably easier to use a PC running, say RealTerm, where you press a key and a 'script' (message) can be sent. This way KNOWN data can be sent and frankly easier to make it happen.

I also wonder if it's 'better' to receive the entire NMEA msg in the ISR, then have main() decode/parse ? Perhaps the 'data' is NOT what you expect. Getting the whole msg, then displaying it, would SHOW you what IS coming into the PIC. Maybe there's a flaw in the ISR decode logic
that would show up if you can SEE the incoming data.

Jay
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Nov 19, 2020 6:36 am     Reply with quote

Case 11 is a "case" problem. It should look for a capital 'P' :-( . Please change that. I whipped together another board to send out the message every second and will test the reception in the evening. I also added a bigger buffer in the beginning of the ISR to capture all the data that comes in.

Regards,
Samo
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Thu Nov 19, 2020 10:46 am     Reply with quote

PCM programmer wrote:
You could test it. Program a 2nd PIC to output a NMEA test stream
at a desired interval. Connect it to your first PIC and test.


That's what I did for my test-bed...

Except I used a PC and wrote something in TCL to just rattle out strings I wanted and then added lots of strings I didn't want normally found in the stream.

Code:

#!/usr/local/bin/tclsh
#
#
# Commandline Args are:
#
# rate (bit rate) port (comm port)
#
#


set debug "0"

set com(port)   "com2"
set com(baud)   "9600"
set com(bits)   "8"
set com(parity) "n"
set com(stop)   "1"


set stringlist   {
         "\$PMRRC01LR0"
         "\$PMRRC041KCMI"
         "\$PMRRC042KDEC"
         "\$PMRRC043KSPI"
         "\$PMRRC0517PN6"
         "\$PMRRC0511IP6"
         "\$PMRRC0510F:4"
         "\$PMRRC0510H@4"
         "\$PMRRC051<JV7"
         "\$PMRRC0519UW7"
         "\$PMRRC0519TR7"
         "\$PMRRC0519I>5"
         "\$PMRRC0513I>5"

         "\$PMRRC0522LR6"
         "\$PMRRC0532LR6"
         "\$PMRRC0572LR6" }


set stringlist2   {
         "\$PMRRC041KSPI"
         "\$PMRRC042KSTL"
         "\$PMRRC043KCMI"

         "\$PMRRC0511JP6"
         "\$PMRRC0512LR6"

         "\$PMRRC0521JP6"
         "\$PMRRC0522LR6"

         "\$PMRRC0537PN6"
         "\$PMRRC0531IP6"
         "\$PMRRC0530F:4"
         "\$PMRRC0530H@4"
         "\$PMRRC053<JV7"
         "\$PMRRC0539UW7"
         "\$PMRRC0539TR7"
         "\$PMRRC0539I>5"
         "\$PMRRC0533I>5"
         }


# =========================================================
# Wait for bytes on $chan
#
proc serial_receiver { chan } {
   set data ""

   if { [gets $chan data] >= 0 } {
      puts "<-- $data"
   } else { puts -nonewline "" }


   if { [eof $chan] } {
      puts stderr "Closing $chan"
      catch {close $chan}
      set done 1
   }
}

# ---------------------------------------------------------
# ---------------------------------------------------------
# Main Routine that sets up comport for Reading and then waits
# forever. Exciting, eh?

if { [llength $argv] > 0 } {
   foreach arg $argv {
      switch -regexp -- $arg {

         {^[-]d$} { set debug "1" }
         {^[-]d.$} { regexp {^[-][Dd]([\d])$} $arg junk debug }

         default {
            puts "\nUsage: VHF-Tester.tcl | \[-dn\]"
            puts "\t\t\t -dn = debug level n"
            puts ""
            exit 2
         }
      }
   }
}

if { [ catch { open $com(port) r+ } serial ] } {
  if {$debug} {
   puts -nonewline "Opening Com Port..."
   puts "Hmmm.. something happened... $serial"
   exit
  }
}

if {$debug} {
  puts "Setting Mode..."
}

fconfigure $serial -mode "$com(baud),$com(parity),$com(bits),$com(stop)" \
           -blocking 0 -buffersize 500 -buffering full -translation crlf


set item_index "0"
set timeout "0"
set delay_loop "0"
set which "0"

while (1) {

   if { !$delay_loop } {
         switch -regexp ($which) {
            "0" {
                  puts "--> [lindex $stringlist $item_index] "
                  puts $serial "[lindex $stringlist $item_index]"
                  flush $serial

                  if { $item_index > [llength $stringlist] } {
                     set which "0"
                     set item_index "0"
                  } else {
                     incr item_index
                  }
                }
             "1" {
                  puts "--> [lindex $stringlist2 $item_index] "
                  puts $serial "[lindex $stringlist2 $item_index]"
                  flush $serial

                  if { $item_index > [llength $stringlist2] } {
                     set which "0"
                     set item_index "0"
                  } else {
                     incr item_index
                  }
                }
         }


      set delay_loop "50"
   }

   if {$delay_loop} {
      set delay_loop [expr $delay_loop -1]
   }


   fileevent $serial readable [ serial_receiver $serial ]
   after 1

}


_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Nov 19, 2020 1:16 pm     Reply with quote

So many stupid mistakes :-( . Anyway, I'm sending this string from my sender board with 19.200 baud: "$GPVTG,360.0,T,348.7,M,000.0,N,123.4,K*34\n"

I tested the sending PIC on a terminal and it does output that.

After correcting one oversight, the following code works. I get 123.4 in the buffer.

Code:

#include <main.h>

char tmp = 0;
int8 Nmea_State = 0;
int8 Dollar_Sign = 0;
int8 Character_Counter = 0;
int8 next_in = 0;
#define BUFFER_SIZE 8                       //create 16 byte large buffer
char buffer[BUFFER_SIZE];
int8 Got_Data = 0;

int8 Test_Buffer_Pointer = 0;
#define Test_Buffer_Size 64
char Test_Buffer[Test_Buffer_Size];

#INT_RDA
void  RDA_isr(void)
{
 tmp=getc();                      // get received char and thus also clear interrupt flag
 
      Test_Buffer[Test_Buffer_Pointer]= tmp;                  // move received char to the appropriate place in buffer.
      ++Test_Buffer_Pointer;                             // increment next_in pointer       
      if(Test_Buffer_Pointer == Test_Buffer_Size - 1) {       // prevent rollover. Numbering in the buffer begins with 0         
         Test_Buffer_Pointer = 0;
      }
// ............................................................................                                                                                 
// Process reception through state machine
// Possible data from NMEA module that will be handled is $GPVTG plus data
//
// Actions of this state machine are:
//                 
// Dollar_Sign = 1;            inform MAIN that we have an $
// Got_Data = 1;             inform MAIN we have some data to work on
// main is responsible to clear those flags
                                                                 
  switch (Nmea_State) {
 
//get initial character, '$'                 
      case 0:{                                                                                                   
        if(tmp == '$'){                   //we have "$", could be "$GPVTG"
            Nmea_State = 1;               //expecting G
            output_toggle(PIN_C1);        // blink the led every time you get an $
            Dollar_Sign = 1;              // inform main we have an $
        }                                     
         else {                         
            Nmea_State = 0;
         }
         break;         
            }
//********WE HAVE RECEIVED '$' AS A FIRST CHARACTER***************************
// we have "$", expecting G   
      case 1:{
         if    (tmp == 'G')                  //have "G"
               Nmea_State = 11;              //expecting 'P'             
         else{
            Nmea_State = 0;                  //reset state machine
         }
         break;
            }

// we have "$G", expecting 'P'
      case 11:  {
         if(tmp == 'P' )                     // expecting 'V'
            Nmea_State = 12;     
         else{
            Nmea_State = 0;                  //error, reset state machine
         }
         break;         
               }
// we have "$GP", expecting 'V'               
      case 12:  {
         if(tmp == 'V' )                     // expecting 'T'
            Nmea_State = 13;
         else{
            Nmea_State = 0;                  //error, reset state machine
         }
         break;   
     }         
// we have "$GPV", expecting 'T'                  }
      case 13:  {
         if(tmp == 'T' )                     // we have $SGPV so far
            Nmea_State = 14;
         else{
            Nmea_State = 0;                  //error, reset state machine
         }
         break;
     }     
// we have "$GPVT", expecting 'G'                 }
      case 14:  {
         if(tmp == 'G' )   {                 // we have $SGPVT so far
            Nmea_State = 15;                 // and now  $SGPVTG
      }   
         else{
            Nmea_State = 0;                  //error, reset state machine
         }
         break;           
               }
// we have "$GPVTG", now wait for the N character to start recording your data
      case 15: {
         if(tmp == 'N'){
            Nmea_State = 16;
            Character_Counter = 0;           
         }
         else{
            Character_Counter++;                // allow max. x characters before you encounter 'N', otherwise
                                                // you could get stuck here in case of garbled data from the module
            if (Character_Counter == 28){       // 25 or 26 max. needed till you get an 'N'
               Nmea_State = 0;                  // abort, something went wrong
               Character_Counter = 0;           // 'N' didn't come in time
               next_in = 0;
            }           
         }
         break;         
      }
// don't record ',' in the buffer               
      case 16:  {
         if(tmp == ',' )   {                    // now get the data
            Nmea_State = 17;                   
      }   
         else{
            Nmea_State = 0;                      //error, reset state machine
         }
         break;           
               }     
     

      case 17:  {
         if(tmp != ','){                            //Record data until comma is received
            buffer[next_in]= tmp;                  // move received char to the appropriate place in buffer.
            ++next_in;                             // increment next_in pointer       
            if(next_in == BUFFER_SIZE - 1) {       // prevent rollover. Numbering in the buffer begins with 0         
            next_in = 0;                           
            }
         }
         else{
            buffer[next_in] = '\n';       // put NULL at the end of the string in the buffer for ATOI
            next_in = 0;                  // go to beginning of the data buffer
            delay_cycles(1);
            Got_Data = 1;                 // inform main we have the data
            Nmea_State = 0;                // reset state machine
            Test_Buffer_Pointer = 0;
         }         
         break;           
     }           
                                                 
   }  // switch brace
}

void main()
{

   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      if(Dollar_Sign){
         Dollar_Sign = 0;           // clear flag
// do one thing     
      }
      if(Got_Data){
         Got_Data = 0;              // clear flag
// do another thing           
      }

   }     // while true

}        // main


Now about my mistake. The code was rewritten from an existing GSM project. I changed the name of the switch statement for this, but never the name of the states (gsm_state, Nmea_State). Of course it came only till state 0.

I do have a question for the OP: How do you get your speed out of this info? Is the dot correctly positioned or does it output the data reversed?

Regards,
Samo


Last edited by PrinceNai on Fri Nov 20, 2020 8:00 am; edited 11 times in total
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Nov 19, 2020 1:20 pm     Reply with quote

This is what I found on the net for that answer:

$GPVTG

Track Made Good and Ground Speed.

eg1. $GPVTG,360.0,T,348.7,M,000.0,N,000.0,K*34
eg2. $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*48


054.7,T True course made good over ground, degrees
034.4,M Magnetic course made good over ground, degrees
005.5,N Ground speed, N=Knots
010.2,K Ground speed, K=Kilometers per hour


eg3. for NMEA 0183 version 3.00 active the Mode indicator field
is added at the end
$GPVTG,054.7,T,034.4,M,005.5,N,010.2,K,A*25
A Mode indicator (A=Autonomous, D=Differential,
E=Estimated, N=Data not valid)

If this is the correct format for the GPS output you get, you should change the limit of Data_Counter in state 15 to at least 25, otherwise you'll never see a 'N' in case 15. I already edited the code above to the last working one I have. Format of the message I found on the net is already taken into account. Also, if you'll do ATOI on the buffer, you'll only get the decimal representation of the part before the dot.

Regards,
Samo
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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