desktop

Problema al recibir datos de modem

Buenas, soy nuevo en este tema, y en el foro. Me gustaria obtener ayuda de los que saben bastante, tengo un proyecto que hacer, como se lo suficiente de C, me pidieron programar un PIC. Es un PIC 18F8520, conectado con un modem simcom 300c (ese modelo me tira cuando le mando el comando ATI por 232).

Utilizo C para programarlo, con PCWHD (CSS C Compiler), microElektronika para flashear el pic, y Hercules para el monitoreo 232...

En fin, atraves de serial 232, puedo mandar comandos AT al modem, y este responde. Por ejemplo, le envio AT, y me responde OK, yo (en mi caso) no con este comando sino con otros, necesito guardar en una variable X, esa respuesta OK (o la que sea), y hasta ahora no puedo, y me estoy volviendo loco.

El proyecto antes me lo habian pasado con una forma, pero no funcionaba, por ejemplo (les saque el pedacito de codigo nomas, mas abajo pego otras partes importantes)

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=rs,errors)
#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=modem,errors)

void getip(){
char IP[16]="000.000.000.000"; // Valor inicial

fprintf(modem,"AT+CSTT=\"internet.gprs.unifon.com.ar\",\"wap\",\"wap\"\r\n");
delay_ms(5000);

fprintf(modem,"AT+CIICR\r\n"); //Activar GPRS
delay_ms(20000);

fprintf(modem,"AT+CIFSR\r\n"); //Devuelve IP
delay_ms(1500);

ip<-fgetc(modem);
delay_ms(1500);

fprintf(rs,"ip=> %s",ip);
delay_ms(1500);
}

Segui investigando el tema de las interrupciones, y descubri que tenia una interrupcion ya de antes, la siguiente:

#INT_RDA2
void RDA2_isr(){
fputc(fgetc(modem),rs);
}

y en el void main tengo : (resumido)

void main() {
//OTRAS FUNCIONES DE ENCENDIDO DE ELEMENTOS, ETC
ENABLE_INTERRUPTS(GLOBAL);
ENABLE_INTERRUPTS(INT_RDA2);
//MAS FUNCIONES DE ENCENDIDO DE MODEM, OBTENCION DE IP, ETC
do{
fputc(fgetc(rs),modem);
}while(1);
}

Asi es como lo tengo actualmente, y no logro hacerlo funcionar.

Buscando informacion, le agregue una interrupcion (INT_RDA) sacada de por ahi, al cual lo llamo por include en un modulo MODEM.c (que abarca todas las funciones del modem), el codigo es el siguiente:

#define maxbuffer 5
volatile char buffer[maxbuffer];
static int8 nextchr;

void addbuffer(char c){
buffer[nextchr++]=c;
if(nextchr==maxbuffer){
nextchr=0;
}
}

#INT_RDA
void serial_isr() {
char nextchr;
nextchr='\0';
if(kbhit()){
nextchr=fgetc();
addbuffer(nextchr);
}
}

y por ejemplo en pruebatest() (que lo llamo desde el main) tengo...

void pruebatest(){
//char rta;
fprintf(modem,"AT\n\r");
delay_ms(500);
ENABLE_INTERRUPTS(INT_RDA);
if(kbhit(modem)){
//rta=fgetc(modem);
fprintf(rs,"RTA:%c\n\r",fgetc(modem));
}
DISABLE_INTERRUPTS(INT_RDA);
}


Lo que esta comentado es porque he ido probando distintas formas y no hubo caso de hacerlo funcionar, por ejemplo en ese caso, yo le mando el comando "AT" al modem y este me responde "OK" y quiero guardar ese "OK" en una variable, pero no me saleeeee... En el codigo de arriba se mostrara por el serial, pero solo lo hice para ver si me obtenia alguna respuesta del modem, una vez que funcionara, descomentaba la linea de arriba, donde guarda en una variable... Esto es simplemente un ejemplo pero no me ha funcionado, por favor si alguno tiene idea que me de una mano, porque no se en que me estoy equivocando, o si se me esta pasando algo por alto. También probe las siguientes formas :

kbhit(); (Si bien tengo entendido kbhit, no se refiere a interrupciones del teclado? -Que no es lo que busco-, corrijanme si me equivoco)
!kbhit();
fgetc();
fgetc(modem);
kbhit(modem);
!kbhit(modem);


Por cierto, si necesitan que les pase algun dato mas, preguntenmé. Y una duda: "La respuesta del modem ¿Lo tomo como una interrupcion?"

Desde ya si alguno me da una mano, muchisimas gracias.
GRACIAS ENSERIO!
 
Hola, un saludo.

por lo que "veo" cada vez que madas un comdo AT, el modem te responde con un " OK ", esto asumiendo que el eco esta desactivado (ate0), sieno asi, puedes optar por distintos modos para "capturar" la respuesta del modem (OK), pude ser por interrupcion, con la funcion fgetc() o con fgets().
Para el caso es simple con fgets().
Ej.

Syntax:
gets (string)
value = fgets (string, stream)

Parameters:
string is a pointer to an array of characters. Stream is a stream identifier (a constant byte)

Returns:
undefined

Function:
Reads characters (using GETC()) into the string until a RETURN (value 13) is encountered. The string is terminated with a 0. Note that INPUT.C has a more versatile GET_STRING function.

If fgets() is used then the specified stream is used where gets() defaults to STDIN (the last USE RS232).

Availability:
All devices

Requires:
#use rs232

Examples:
char string[30];

printf("Password: ");
gets(string);
if(strcmp(string, password))
printf("OK");

Example Files:
None

Also See:
getc(), get_string in input.c
 
Muchachos muchas gracias por la informacion, mas que nada a vos Saint_

Antes con el fgetc() me complicaba mucho porque tomaba datos, y caracteres mal, no se andaba mal eso, no como queria, podia obtener caracteres pero no todos, algunos, y no me gustaba... y probe con fgets y finalmente pude meter el string en una variable la respuesta del modem... Pero se me cuelga... El codigo es el siguiente:

#INT_RDA2
void RDA2_isr(){

//disable_interrupts(int_rda2);

fgets(mdm,modem);
fprintf(rs,"[%s]",mdm);

//enable_interrupts(int_rda2);
}

Simplemente guarda en el [char *mdm;] la interrupcion, y lo muestro en el 232 entre corchetes, para diferenciar bien los datos, es solo un ejemplo despues lo perfeccionare con un switch con comparacion de strnig, y ahi hacer funciones en base a la respuesta del modem... En fin pero tengo un problema, hasta ahi anda, pero miren... En el void main tengo esto...

void main() {
initmain();
//buzzer(); //Sonido del inicio

welcome_screen(); //Pantalla de BIENVENIDO!!
delay_ms(2000); //delay
loading_screen(); //Pantalla de LOADING...
modempor232(); //Iniciamos el modulo 232 para escuchar el modem
modemON(); //Iniciamos el modem
checkMODEM(); //Chequeamos el encendido correcto del modem
int_on(); //Habilitar interrupciones (GLOBAL y INT_RDA2)
delay_ms(10000); //Dar unos segundos para terminar de cargar SIM y el Call Ready

strcpy(AT2send,"AT"); //Guarda en una variable, el comando a enviarse al modem
send2modem(AT2send); //Se envia al modem la variable con el comando

fprintf(rs,"***All loaded***\n\r"); //Indica que se cargo todo

do{
fputc(fgetc(rs),modem); //Permite ingresar comandos en el modem por 232
}while(1);
}

al escribir este codigo, el modem me da el siguiente resultado en el 232...

********** Starting **********
····· 232 Loaded ·····
·Modem Shutting down·
·Modem Starting·
#El modem se inicio correctamente
[]
[Call Ready]

ahi podemos ver que hay dos interrupciones, y la variable mdm en el prmier caso no tiene nada (len: 0) y en la segunda, capta lo que es el Call Ready, pero ahi se queda colgado, despues debería mostrar AT OK, y no lo muestra :(

Alguien tiene idea que puede ser? Alguien que ya haya pasado por esto?

GRACIAS DE ONDA, de paso para ayudar a futuras personas que vayan a tratar este tema... EXITOS!
 
Hola, ten en cuenta que cualdo se usa la funcion fgets(), espera recibe los caracteres hasta que encuentre un 0x0d o un 13d, por tanto si pones esa funcion dentro de una interrupcion este quedara ecperando al 13d y nunca saldra de la interrupcion hacieno parecer que se colgo...
 
Ah es verdad, perdonnn por pasarme de alto eso... Pero te hago otra pregunta, perdoname que tome tu tiempo, pero me estas ayudando bastante...

si no meto el fgets en la interrupcion no me toma nada de los caracteres del modem...

Y si lo pongo en la interrupcion, como hago para salir de la interrupcion, o sea, al no encontrar el chr(13), o 0x0d, Enter o como lo llamemos...?

Yo tengo pensado enviar ese string a una funcion, que active un flag, para que realice una funcion cuando el modem tenga una interrupcion, pero si me podrias decir como salir de la interrupcion cuando no encuentra el caracter 0x0d ? Porque he estado buscando, y no he encontrado mucha informacion :\

Vos decis que me conviene utilizar esta funcion fgets()? o fgetc()?
 
Hola, mi recomendacion es que no uses fgets() en la interrupcion seria.
seria mejor que lo uses en la rutina principal de modo que envies un comando al modem y luego esperes su respusta con fgets(). "sera mas facil"

por otro lado si por algun motivo es imperioso usar la inerupcion seral entonces mejor usar fgetc() ya que este solo lee un byte y termina, asi seria un ejemplo.
--------------------------------------------
char dato[10]; //variable global donde guarda los datosrecividos por el puerto serie
unsigned int8 n=0;
.
.
.
#INT_RDA
void serial_isr()
{
dato[n]=kbhit();
if(dato[n]==0x0d)
{
... //señalisador de respuesta recibida
n=0;
}
else
{
n++;
}
}
 
Me estoy confundiendo :\

Estas mezclando fgets() con fgetc() ?

Antes habia intentado mucho con fgetc() y me habia costado hacerlo, voy a intentar de nuevo hacer un codigo para que capte las respuestas del modem con fgetc()...

pero en el caso de usar fgets() fuera de la interrupcion por ejemplo

fprint(modem,"AT\n\r");
fgets(mdm); //variable donde guardar la respuesta?

Aca se me queda colgado esperando que ingrese un ENTER...

Entonces me queda la duda de : ¿Que código ingreso en la interrupcion? Para que le devuelva a ese fgets(mdm); (que esta fuera de la interrupcion) lo que se encuentra DENTRO de la interrupción. Me explico?


Quiero tratar de evitar usar fgetc(), pero si veo que con fgets() no avanzo, no me quedara otra que volver a intentar con fgetc()...

Gracias enserio por tu tiempo... esto es lo unico que me esta atrasando en este proyecto
 
hola, primero en el codigo anterior que "mande" hay un error (no se en que estaba pensando), el error es.

dato[n]=kbhit();..., deberia ser...dato[n]=fgetc();

Por otro lado, sugeria que para obtener la respuesta del modem habian dos caminos, uno de los cuales es mas sencillo y ese es usando fgets(); pero fuera de la interrupcion, por tanto ya no sera nesesario la interrupcion...
por ejemplo asi.
-----------------------------------------------------

char cadena[5]; //vector donde se guarda la respuesta del modem
void main()
{
.
.
.
fprint(modem,"AT\n\r");
fgets (cadena,mdm); //el resultado de esto es "cadena=respuesta del modem"
.
.
.
}
 
Última edición:
...perdon es fprintf(modem,"AT\n\r");

Uy ahi me funciono algo, mira... Ya estoy cada vez mas cerca de dejar de tomar tu tiempo, jajaj te prometo que si andas por mendoza argentina, me avisas y te invito una cerveza bien fresca! jajaj

Por el 232 estoy obteniendo el siguiente resultado

#El modem se inicio correctamente

Call Ready
AT[
OK
T]***All loaded***

con el siguiente codigo en el css (tal cual me dijiste, sos un genio):

fprintf(modem,"AT\n\r");
fgets(respuesta,modem);
fprintf(rs,"[%s]",respuesta);

y en la interrupcion tengo...

#INT_RDA2
void RDA2_isr(){
fputc(fgetc(modem),rs);
}

Lo cual si comento esa linea :

//fputc(fgetc(modem),rs);

No me imprime nada, en fin, voy a seguir probando codigo para ver el funcionamiento de todo esto, me ayudaste demasiado, toma mi palabra de lo que dije al inicio de esta respuesta. Y voy a probar el codigo y algunas cosas hasta que me salga bien bien, y voy a subirlo por si alguno pasa por el mismo inconveniente, asi como tambien si se me genera alguna otra duda (ESPERO QUE NO, porque ya llevo como 10 dias con este tema). Y de paso le voy a cambiar el estado a Solucionado.

GRACIAS !
 
ok, gracias por la invitacion y me alegra que encuentrea "luz", en tu cometido, de mi parte no tengas lio que siempre estare cooperando en cuanto a lo que conosca...
 
Atrás
Arriba