|
|
View previous topic :: View next topic |
Author |
Message |
warriorfenix
Joined: 29 Dec 2009 Posts: 8 Location: España
|
HELP with GPS |
Posted: Tue Dec 29, 2009 7:08 am |
|
|
Hola estoy realizando un programa que interprete las cadenas de caracteres que envia el GPS, lo simulo con proteus y funciona correctamente, pero cuando lo quemo en el pic, no muestra nada en la lcd. Por favor revisen mi codigo fuente, y diganme que es lo que esta mal. gracias
Code: |
#include <16f876.h>
#fuses XT,WDT,NOPROTECT,NOLVP,NOBROWNOUT,PUT
#use delay(clock=4000000)
#use rs232(baud= 9600, xmit=PIN_C6,rcv=PIN_C7)
//LIBRERIAS
#include <lcd2.c>
#include <string.h>
#include <stdlib.h>
char pers;
int16 dist_pers;
char sen;
int16 cod_sen;
int16 dist_sen;
int16 dist_v1;
int16 dist_v2;
char veh;
int16 cod_veh;
char buffer[2];
int comaCount;
int posCount;
char headerBuffer[6];
int i;
#int_rda
void serial_isr() {
char rxData2;
rxDATA2=0x00;
gets(rxDATA2);
puts("HOLA");
//rxData2=getc();
}
void cadena()
{
char rxData;
char s[6];
rxDATA=0x00;
if(rxData!=0x00){
if (comaCount == 0) {
if (posCount == 0) {
if (rxData == '$') {
headerBuffer[0] = '$';
posCount++;
}
}
else {
if (rxData == ',') {
comaCount++;
posCount = 0;
}
else {
headerBuffer[posCount] = rxData;
posCount++;
}
}
}
else {
strcpy(s, "$ARGOS");
if (strncmp(headerBuffer, s, 6) == 0) {
if (rxData == ',') {
comaCount++;
posCount = 0;
if (comaCount > 9) {
comaCount = 0;
}
}
else {
switch (comaCount) {
case 1: pers = rxData;
posCount++;
break;
case 2: buffer[posCount] = rxData;
dist_pers = atoi(buffer);
posCount++;
break;
case 3: sen = rxData;
posCount++;
break;
case 4: buffer[posCount] = rxData;
cod_sen = atoi(buffer);
posCount++;
break;
case 5: buffer[posCount] = rxData;
dist_sen = atoi(buffer);
posCount++;
break;
case 6: buffer[posCount] = rxData;
dist_v1 = atoi(buffer);
posCount++;
break;
case 7: buffer[posCount] = rxData;
dist_v2 = atoi(buffer);
posCount++;
break;
case 8: veh = rxData;
posCount++;
break;
case 9: buffer[posCount] = rxData;
cod_veh = atoi(buffer);
posCount++;
break;
default: posCount = 0;
comaCount = 0;
break;
for (i=0;i<2;i++)
buffer[i] = 0x00;
}
}
}
rxData=0x00;
}}}
void main() {
enable_interrupts(global);
enable_interrupts(int_rda);
lcd_init();
cadena();
do{
if (pers == 'N'&&sen == 'N'&&veh == 'N'){
lcd_putc("\f");
}
if (pers == 'P'){
lcd_gotoxy(1,1);
printf(lcd_putc,"P:%C DP:%lu",pers,dist_pers);
}
if (sen == 'S'){
lcd_gotoxy(1,1);
printf(lcd_putc,"S:%C CS:%lu DS:%lu",sen,cod_sen,dist_sen);
lcd_gotoxy(1,2);
printf(lcd_putc,"DTV1:%lu DTV2:%lu",dist_v1,dist_v2);
}
if (veh == 'V'){
lcd_gotoxy(1,1);
printf(lcd_putc,"V:%C CV:%lu"veh,cod_veh);
}
} while (TRUE);
} |
|
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Tue Dec 29, 2009 7:36 am |
|
|
English, please. http://translate.google.com
I looked at the fuses, saw "WDT"; then I looked through your code for a "restart_wdt"; didn't find it; and then stopped looking any further. Fix this first.
Rohit |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Dec 29, 2009 9:11 am |
|
|
Always add the 'ERRORS' keyword to the #rs232 line to prevent the UART from blocking.
Code: | rxDATA=0x00;
if(rxData!=0x00){ | Two comments here:
1) The if-statement will always fail
2) Type variable names always in the same capitalization. The CCS compiler accepts it but this is not according to the C-standard. Add '#case' to the start of your program to make the compiler follow the C-standards.
The point where I stopped looking was when I saw the gets() call in the interrupt routine. NEVER do this! Just yesterday Ttelmah explained why not to do this. Read his answer here |
|
|
warriorfenix
Joined: 29 Dec 2009 Posts: 8 Location: España
|
|
Posted: Tue Dec 29, 2009 7:59 pm |
|
|
I tried to set the WDT in various parts of the program
Code: | #int_rda
void serial_isr() {
char rxData;
char s[6];
//RESTART_WDT() ;
rxDATA=0x00;
if(kbhit()){ |
Code: | void main() {
enable_interrupts(global);
enable_interrupts(int_rda);
lcd_init();
//RESTART_WDT() ; |
and at the end of the interruption IRDA and nothing, the program remains the same. I do not understand the explanation of RXdata IF 0, because my English is very bad, please tell me in which points of the program and I have to make changes. Thanks |
|
|
guest1 Guest
|
|
Posted: Wed Dec 30, 2009 2:21 am |
|
|
warriorfenix wrote: |
I do not understand the explanation of RXdata IF 0, because my English is very bad, please tell me in which points of the program and I have to make changes. Thanks |
Usted toma rxData igual a 0 y en la siguiente declaración que comprobar si no es 0. Eso es inútil. (c) Google Translate))) |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Dec 30, 2009 7:50 am |
|
|
Start with an easy small program and when this works add more functions.
Do not use the watchdog in the prototype. Only add the watchdog when your program is working.
Do not use RDA interrupts. Your program does not need it and makes things difficult. |
|
|
Guest
|
|
Posted: Wed Dec 30, 2009 7:54 am |
|
|
I have removed the comparison of RXDATA IF, and I still get nothing. I do not understand how can he be ... |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Dec 30, 2009 10:00 am |
|
|
GPS modules usually transmit at 4800 baud. Use getc() instead of gets(). gets() looks for a 'string' of characters and int_rda is entered on every character. You are trying to send the word 'HOLA' everytime int_rda is entered. This will make your interrupt not work. You will lose incoming characters. If you want to send something to verify that you received data from the GPS then just send the same character that was just received with a putc(). You might want your #use rs232() to read:
Code: | #use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7, errors) |
Try something very simple at first. Get the PIC to receive and send characters first, then try writing to the LCD. Baby steps, baby steps.
Google translation:
Módulos GPS suele transmitir a 4800 baudios. Utilice getc() en lugar de gets(). gets() busca una 'cadena' de personajes y int_rda se introduce en cada personaje. Usted está tratando de enviar la palabra int_rda 'HOLA' cada vez que se introduzca. Esto hará que su interrupción no funciona. Se perderán los caracteres de entrada. Si quieres enviar algo para verificar que ha recibido los datos desde el GPS se acaba de enviar el mismo carácter que se acaba de recibir con una putc(). Es posible que desee su uso # RS232() para que diga:
Code: | #use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7, errors) |
Intente algo muy simple al principio. Obtener el consentimiento fundamentado previo para recibir y enviar los primeros caracteres, a continuación, intenta escribir en la pantalla LCD. Pasos de bebé, pasos de bebé.
Ronald |
|
|
warriorfenix
Joined: 29 Dec 2009 Posts: 8 Location: España
|
|
Posted: Thu Dec 31, 2009 10:01 am |
|
|
I made a simple program to send and receive with the serial port and the lcd, and it works, I added a putc (rxData) in the code, and forwards all data correctamnte. But I'm not on the LCD displays the data. What could go wrong?
Code: | #int_rda
void serial_isr() {
char rxData;
char s[6];
//RESTART_WDT() ;
rxDATA=0x00;
if(kbhit()){
rxData=getc();
putc(rxData);
if (comaCount == 0) {
|
|
|
|
mccoyb
Joined: 02 Jan 2010 Posts: 1
|
|
Posted: Tue Jan 05, 2010 12:57 pm |
|
|
I have some code I wrote for parsing two GPS NMEA strings:
$GPGGA and $GPRMC (if I'm remembering those correctly). I don't have it in front of me but I can post it tonight when I have it available. Let me know if you want that code.
I'm currently using the code to parse NMEA strings from 2 GPS units: a Garmin eTrex and a USGlobal Sat EM-406A SiRF III Receiver ( http://www.sparkfun.com/commerce/product_info.php?products_id=465 ).
My code works well with both, but be warned of very slight differences in NMEA strings, even though NMEA is a standard and they should be identical.
The parsing is a little more elaborate than what you have, so the code is slightly bigger, but hopefully it will work for you. I've run it in overnight tests and performed data logging and I haven't observed any memory over-runs or anything like that and it handles the empty NMEA strings if the GPS looses lock.
I believe I have one version of code that simply parses strings and one version that does the conversions to numbers. I recommend keeping it in string format and doing the conversion outside the function.
I'm running it on a PIC18F4620. Both GPS units run 4800 bps, on the standard 8 data bits, no parity, 1 stop bit (8-N-1).
Be careful about knowing your voltage levels from your GPS: TTL 0-5V? TTL 0-3V? RS-232 +7V/-7V? or whatever. Make sure you know whether your signal is getting inverted if you're doing conversion from RS-232 levels to TTL levels. _________________ Bart McCoy
Rochester, MN |
|
|
el_tigre
Joined: 23 Dec 2007 Posts: 12 Location: Bs As : Argentina
|
|
Posted: Sun Jan 17, 2010 6:51 am |
|
|
Hola warriorfenix, hablo español ya que soy de Argentina. Me parece que te cuesta entender algunas cosas de las que te estan planteando.
En primer lugar te recomiendo no usar interrupciones para recibir los caracteres de la cadena del GPS, por que tarde o temprano vas a tener problemas... dado que las cadenas que envian son bastante grandes y con una frecuencia importante, al menos veo eso en el modelo con el que estoy trabajando.
una sujerencia de un loop que sin usar interrup te levanta caracter y lo manda...ademas en tu post anterior estas usando mal la rutina en la interrupcion... proba esto....
void main() {
disable_interrupts(global);
cd_init();
while(true){ // loop eterno....
while(!kbhit()){restart_wdt();} // espera que llegue dato, mientras resetea el watchdog, cuando pasa esta linea es por que ha data
rxData=getc(); // aca levantas el dato
mando_lcd(rxData); // esto no va a andar por que no esta definido pero si pones la funcion que uses para mandar data al lcd te lo deberia mostraar
} // vuelve al looptendrias que postear el codigo entero para poder ayudarte mejor
en tu post anterior cuando pones
rxData=getc();
putc(rxData);
if (comaCount == 0) {
lo que va a hacer es mandar por 232 el caracter que recibio...para que putc() mande al lcd le tenes que decir que escriba en el lcd, la funcion putc por default lo manda al stream que quedo, pero para manejar flujos por diferentes lados tenes que usar fputc(stream, dato) entonces si definis que el stream del LCD es lcd_stream, para mandar por ahi deberia quedar asi:
fputc(lcd_stream,rxData);
POnete el codigo entero que estas usando, cuando arranca el main implemnta un linea que escriba algo en el lcd, asegurate que funciona (que realmente lo escribe) y te puedo ayudar a hacerlo andar.
Saludos |
|
|
el_tigre
Joined: 23 Dec 2007 Posts: 12 Location: Bs As : Argentina
|
|
Posted: Sun Jan 17, 2010 7:32 am |
|
|
Me olvide de contarte que encontre tu post por que casualmente estoy trabajando en un sistema similar... en mi caso tengo una placa GolbalSat modelo ET-102, pero por lo que veo casi todas manejan el mismo protocolo...bueno, cuando postees seguimos, saludos.
++++++++++++++++++++++
El Tigre,
Éste es un foro internacional que se conduce en inglés.
Siga por favor esta regla.
-- Forum Moderator
++++++++++++++++++++++ _________________ Sebastian Cohn
www.bit03.com.ar
Desarrollos Electronicos |
|
|
warriorfenix
Joined: 29 Dec 2009 Posts: 8 Location: España
|
|
Posted: Wed Jan 20, 2010 5:05 pm |
|
|
I've managed to get good chains, was no problem either global variables initialized at the beginning of the program. The problem I have now is that I can not show good values in the lcd, the text displayed does not last long enough in the lcd.
Code: | #include <16f873a.h>
#fuses HS,WDT,NOPROTECT,NOLVP,NOBROWNOUT,PUT
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
//LIBRERIAS
#include <lcd2.c>
#include <string.h>
#include <stdlib.h>
int cod_sen = 0;
int16 dist_sen = 0;
int16 dist_v1 = 0;
int16 dist_v2 = 0;
int16 utm = 0;
char buffer[2];
int comaCount = 0;
int posCount = 0;
char headerBuffer[6];
int i = 0;
#int_rda
void serial_isr() {
char rxData;
char s[6];
rxDATA=0x00;
if(kbhit()){
rxData=getc();
//putc(rxData);
if (comaCount == 0) {
if (posCount == 0) {
if (rxData == '$') {
headerBuffer[0] = '$';
posCount++;
}
}
else {
if (rxData == ',') {
comaCount++;
posCount = 0;
}
else {
headerBuffer[posCount] = rxData;
posCount++;
}
}
}
else {
strcpy(s, "$ARGOS");
if (strncmp(headerBuffer, s, 6) == 0) {
if (rxData == ',') {
comaCount++;
posCount = 0;
if (comaCount > 5) {
comaCount = 0;
}
}
else {
switch (comaCount) {
case 1: buffer[posCount] = rxData;
cod_sen = atoi(buffer);
posCount++;
break;
case 2: buffer[posCount] = rxData;
dist_sen = atoi(buffer);
posCount++;
break;
case 3: buffer[posCount] = rxData;
dist_v1 = atoi(buffer);
posCount++;
break;
case 4: buffer[posCount] = rxData;
dist_v2 = atoi(buffer);
posCount++;
break;
case 5: buffer[posCount] = rxData;
utm = atoi(buffer);
posCount++;
break;
default: posCount = 0;
comaCount = 0;
break;
for (i=0;i<3;i++)
buffer[i] = 0x00;
}
}
}
rxData=0x00;
}}
}
void main() {
int r = 0;
enable_interrupts(global);
enable_interrupts(int_rda);
lcd_init();
do{
if(cod_sen == 1){
lcd_gotoxy(1,1);
printf(lcd_putc,"VEHICULO APROX.");
lcd_gotoxy(1,2);
printf(lcd_putc,"V1:%lu V2:%lu",dist_v1,dist_v2);
delay_ms(5000);
}
if(cod_sen == 2){
lcd_gotoxy(1,1);
printf(lcd_putc,"PEATON");
lcd_gotoxy(1,2);
printf(lcd_putc,"V1:%lu V2:%lu",dist_v1,dist_v2);
delay_ms(5000);
cod_sen = 2;
}
if(cod_sen == 3){
lcd_gotoxy(1,1);
printf(lcd_putc,"CEDA EL PASO");
lcd_gotoxy(1,2);
printf(lcd_putc,"V1:%lu V2:%lu",dist_v1,dist_v2);
//cod_sen = 3;
delay_ms(5000);
}
}while(true);
}
|
|
|
|
el_tigre
Joined: 23 Dec 2007 Posts: 12 Location: Bs As : Argentina
|
|
Posted: Wed Jan 20, 2010 8:07 pm |
|
|
SPA: No me queda claro algo, no entran en el LCD o el tiempo de actualizacion es tan breve que no llegas a ver los valores?.
ENG: I do not understand something, do not enter the LCD or update time is so short as to not get to see the values? _________________ Sebastian Cohn
www.bit03.com.ar
Desarrollos Electronicos |
|
|
warriorfenix
Joined: 29 Dec 2009 Posts: 8 Location: España
|
|
Posted: Thu Jan 21, 2010 1:16 am |
|
|
El problema es qu antes el programa no funcionaba bien, por que no tenia las variables globales inicializadas a cero. una vez inicializadas, no tengo problema en la recepcion de caracteres. El problema que tengo ahora es que no puedo mostrar en la lcd, los valores de las variables que recibo durante el tiempo que quiera, tres segundos, cinco, etc... se muestran las variables cuando reciben la orden durante un segundo y se sale.
Eng:
The problem is that before, the program was not working properly
because it did not have global variables initialized to zero. Once it is
initialized, it will have no problems in the reception of characters. The
problem I have now is I can not show on the lcd, the values of the
variables during the time I get like, three seconds, five, etc... it shows
the variables when they receive the order for a second and exits. |
|
|
|
|
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
|