|
|
View previous topic :: View next topic |
Author |
Message |
lasal
Joined: 25 Jan 2012 Posts: 13
|
Read a message over rs232 |
Posted: Wed Apr 11, 2012 10:45 pm |
|
|
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
on lcd.
The lat and lon values are not printed.
Please help. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu Apr 12, 2012 3:55 am |
|
|
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
|
reading gps over rs232 |
Posted: Thu Apr 12, 2012 6:45 am |
|
|
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
|
|
Posted: Thu Apr 12, 2012 8:27 am |
|
|
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
|
|
Posted: Mon Apr 16, 2012 9:41 am |
|
|
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 |
|
|
|
|
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
|