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 CCS Technical Support

Read a message over rs232

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



Joined: 25 Jan 2012
Posts: 13

View user's profile Send private message

Read a message over rs232
PostPosted: Wed Apr 11, 2012 10:45 pm     Reply with quote

I am trying to read a text over rs232 and extract a part of it and print the extracted portion on a 16*2 lcd.

This is the code:
Code:

#include <uart.h>
#include <string.h>

#define LCD_DB4   PIN_C1
#define LCD_DB5   PIN_C2
#define LCD_DB6   PIN_C3
#define LCD_DB7   PIN_D0
#define LCD_RS    PIN_A7
#define LCD_RW    PIN_A6
#define LCD_E     PIN_C0
#include <flex_lcd.c>

void load();

#int_RDA
void  RDA_isr(void)
{
if(kbhit(GPS))if(getc(GPS)=="$")load();

}


#int_TIMER2
void  TIMER2_isr(void)
{

}

char RXstr[80]={};
volatile char rx;
int i,j,k;
volatile char lat[11]= {};
volatile char lon[12]= {};


void main()
{
   setup_timer_2(T2_DIV_BY_16,255,16);//2.0 ms overflow, 32.7 ms interrupt
   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   enable_interrupts(INT_TIMER2);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_8MHZ);
lcd_init();
output_high(PIN_D1);

      while(true){

         lcd_gotoxy(1,1);
         printf(LCD_PUTC, "LAT %s",lat);
         lcd_gotoxy(1,2);
         printf(LCD_PUTC, "LON %s",lon);
         delay_ms(500);

      }//while ends



}//main ends

void load(){
disable_interrupts(INT_RDA);
            j=0;
         for(i=0;i<80;i++){
         if(kbhit(GPS)) {delay_us(10);
                        rx = getc(GPS);RXstr[j]=rx;
                        }
         
         j++;
         }

         j=18;
         for(k=0;k<11;k++){
         lat[k] = RXstr[j];
         j++;
         }
         
         j=30;
         for(k=0;k<12;k++){
         lon[k] = RXstr[j];
         j++;
         }            
         RXstr="";
      enable_interrupts(INT_RDA);      


}


This is what inside uart.h:
Code:

#include <16F887.h>
#device ICD=TRUE
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES DEBUG                    //Debug mode for use with ICD

#use delay(int=8000000)

#use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=GPS)


I'm using a Royaltek rgm-2000 gps reciver and it sends the following message at the baud rate of 4800:

$GPGGA,161229.487,3723.2475,N,12158.3416,W,1,07,1.0,9.0,M, , , ,0000*18

I have to extract the latitude highlighted in cyan longitude in blue
and print them on lcd, but the problem is this code only prints
Code:

LAT                                                                         
                                                                             
LON                                                                       

on lcd.

The lat and lon values are not printed.

Please help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Thu Apr 12, 2012 3:55 am     Reply with quote

Seriously. Uurgh......
Not how to handle the data at all.
There has been code posted here in the past for parsing NMEA data (which is what this is), and may even be some in the code library.

Several problems:
1) You are basically missing the 'point' of using interrupts. The idea is being able to do multiple things apparently 'at the same time'. Your code just sits in the interrupt handler, stopping anything else happening, so might as well not be using interrupts at all...
2) You are _assuming_ that you will always get strings exactly the same length. Not true.
3) Then what you put into the arrays is not a string. In C, a string _must_ be 'null terminated', and extra space is needed for this, and this must be done.
4) _Always_ have 'errors' in the RS232 declaration for a hardware UART, unless _you_ handle UART errors yourself. Without this, if the data gets corrupted, or you miss receiving a character, the UART _will_ become permanently hung. This is _required_, not 'optional'.
5) As for why nothing gets displayed - it is because there is nothing in the array. Your for loop in the 'load' routine, will find just one character waiting when called, so the first character of the array receives this, and the the remaining 79 characters are left blank....

Best Wishes
lasal



Joined: 25 Jan 2012
Posts: 13

View user's profile Send private message

reading gps over rs232
PostPosted: Thu Apr 12, 2012 6:45 am     Reply with quote

I found a code as you said.

But I can't understand how it works. Can you help me with this?
Code:

///////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdlib.h>
///////////////////////////////////////////////////////////////////////////////
typedef struct _DateTimeInfo
{
   int8 Day;
   int8 Month;
   int8 Year;
   int8 Hour;
   int8 Minute;
   int8 Second;
} DateTimeInfo;
////////////////////////////////////////
typedef struct _GPRMCInfo
{
   char Valid;
   DateTimeInfo DT;
   float Latitude;
   char N_S;
   float Longitude;
   char E_W;
   float Speed;
} GPRMCInfo;
///////////////////////////////////////////////////////////////////////////////
//copy string (pos n to pos m) from s2 to s1
char* StrnmCpy(char *s1, char *s2, size_t n, size_t m)
{
   int8 i;
   char *s;
   
   for (s=s1, i=n, s2+=n; i<=m; i++)
      *s++ = *s2++;
   *s = '\0';
   
   return s1;
}
///////////////////////////////////////////////////////////////////////////////
// find c in s starting from pos st
int8 StrFnd(char *s, char c, size_t st)
{
   int8 l;
   
   for (l=st, s+=st ; *s != '\0' ; l++, s++)
      if (*s == c)
         return l;
   return -1;
}
///////////////////////////////////////////////////////////////////////////////
void GPRMC_decode(char *GPRMCStr, GPRMCInfo *RMCInfo)
{
   int8 p1, p2;
   char TempStr[16];
   
   p1 = StrFnd(GPRMCStr, ',', 0);      //find first comma
   if (p1 == 6)
   {
      //check for valid packet:
      if ( (StrFnd(GPRMCStr, 'A', p1+1) == 18) && (GPRMCStr[0]=='$')) //valid?
      {
         RMCInfo->Valid = 'A';
         
         //Get time
         p1 = StrFnd(GPRMCStr, ',', 0);      //find first comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->DT.Hour = atoi(StrnmCpy(TempStr, GPRMCStr, p1+1, p1+2));   //hour
         RMCInfo->DT.Minute = atoi(StrnmCpy(TempStr, GPRMCStr, p1+3, p1+4)); //min
         RMCInfo->DT.Second = atoi(StrnmCpy(TempStr, GPRMCStr, p1+5, p1+6)); //sec
         
         //Get latitude & direction
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->Latitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
         RMCInfo->N_S = GPRMCStr[p2+1];
         
         //Get longitude & direction
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->Longitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
         RMCInfo->E_W = GPRMCStr[p2+1];
         
         //Get speed
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->Speed = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
         
         //Get date
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->DT.Day = atoi(StrnmCpy(TempStr, GPRMCStr, p1+1, p1+2));  //dd
         RMCInfo->DT.Month = atoi(StrnmCpy(TempStr, GPRMCStr, p1+3, p1+4));//mm
         RMCInfo->DT.year = atoi(StrnmCpy(TempStr, GPRMCStr, p1+5, p1+6)); //yy
      }
      else                                //not valid
      {
         RMCInfo->Valid = 'V';
      }
   }
}
/////////////////////////////////////////////////////////////////////////////// 

How do i input the uart data i received to these functions ?
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Thu Apr 12, 2012 8:27 am     Reply with quote

Hi,

Your project really has two parts:

1. Receive the desired NMEA data message
2. Parse, and display the data from NMEA data message

I would start with part 1 first, and get that working 100%. CCS provides an example program called 'EX_SISR.c' which shows you how to implement an interrupt driven 'circular' serial receive buffer. I would add to this example a 'State Machine' in the serial ISR to exclude all NMEA messages except the one you really need (eg. $GPRMC).

Once that is working and you've got the desired NMEA message into a string, those parsing routines can be implemented. That's not worth messing with, though, until your serial receive routines are working 100%!

John
darkrush



Joined: 29 Sep 2011
Posts: 18
Location: Colombia

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 9:41 am     Reply with quote

This is an old code I found, but should be something like this:

Code:


char c;
char *proto = "$GPGGA";

#INT_RDA
void in_data(){

   c = getc();
   if (c == '$')
   {
      idx = 0;
      buffer[idx++] = c;
   }
   else if (c != 0x0A)//LF
      buffer[idx++] = c;
   else{
      if(!strncmp(proto,buffer,6))
      dat = 1;
   }
}



Hope it helps.

Xavier
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