Uso de un celular GSM con PIC o PC

pregunto:
despues de la ultima linea : printf("Procesado.\r\n\r\n"); // Monitorizo procesado.

iria la llave de cierre del main no?

Si , eso es correcto.

Hola de nuevo Sdel, perdón por meterme de nuevo :D. Creo que sería una muy buena idea que probaras el PIC con hypertérminal antes que con el cel...corre un programa muy simple donde metas caracteres al PIC y checa que este los interprete de alguna forma que regrese al hypertérminal

Tendrías que hacer como te dice erik ....es mucho mas facil probar los programas de esa manera.
 
hola moyano, erick no pidas perdon, al contrario es de gran ayuda sus comentario.
la verdad lo que me recomiendan ya lo tengo probado, el pic conectado con el hiperterminal envia bien los comandos y queda a la espera de una respouesta, desde el terminal le mando algo y en el proto el pic me lo muestra en un lcd, y asi funciona con algunos detalles a corregir. despues la otra prueba es enviarle los comandos desde el pic al celular y el cel interpreta bien lo que le manda el pic por que conectando el tx del cel al rx del terminal puedo ver la respuesta del celular al pic pero si el tx del cel lo pongo en el rx del pic no pasa nada:unsure:

ahora adjunto el archivo simulado con proteus, el codigo fuente en c18 y el hex. si alguno puede probarlo y decirme si tiene los mismos resultados que yo seria una gran ayuda.

el celular es un sony ericsson t290a y las pruebas las hago con el pic18f4620.

en el codigo solo intento leer los primeros 10 caracteres que le enviaria el pic para mostrarlo en el lcd y uso el comando rec read para leer un mensaje ya leido solo de prueba.

bueno cuendo puedan y si quieren probar el archivo de simulacion les agradezco. saludosss
 

Adjuntos

  • gsmcel(2).rar
    187.1 KB · Visitas: 186
Ya revisé lo que tienes en el archivo que es lo mismo de la página, aquí habría un detalle a checar y es la velocidad de tu PIC, recuerda que no es lo mismo escribir en el hypertérminal que recibir la trama enviada desde el Cel. Según el programa lo agrega a un buffer y de ahí se va a un eco que compara por un switch que tipo de caracter se envió, lo cual considero puede tomarle algunos ciclos importantes al PIC que pueden hacer que se pierda información importante...
Si el programa lo usas como está, sería prudente que le quites la parte del eco, aunque lo mejor es que hagas una rutina que se dedique a recibir los caracteres sin que nada mas lo interrumpa y de ahí entonces sacarlo por el LCD y/o hacer otras pruebas.
Saludos
 
hola eric, pido dispulpas el archivo que subi es lo que habia subido moyano y yo me confundi jej.
ahora subo mi codigo y hex con el archivo de proteus para simularlo, al circuito lo probe con oscilador de 4Mhz y de 20Mhz y los resultados son los mismos. pero ahora eric me hiciste pensar otra idea y es que el pic trate los caracteres recibidos por medio de interrupciones, voy a probarlo y comento, gracias.

saludos
 

Adjuntos

  • CELGSM18F4620.rar
    16.3 KB · Visitas: 227
Revisando el programa solo me queda la duda de como se reciben los datos desde el usart ya que la rutina
getsUSART(sms,10); no la tienes dentro del programa principal, solo puedo asumir que el problema esté ahí. Como te dije en el post anterior, el cel no hace pausas entre caracter y caracter por lo que si la rutina en el PIC no está pendiente de esto pues se puede quedar el PIC esperando hasta que se cumpla que reciba 10 caracteres...también puede pasar que el cel no te envíe 10 caracteres que no suena muy creible pero puede pasar.
Lo que pienso es que si este programa lo pruebas entre hyperterminal y el cel y solo en el hyperterminal funciona bien, quiere decir que no se está cumpliendo los 10 caracteres de recepción desde el Cel por lo que habría que checar el porque de esto.
Saludos
 
Hola eric, la rutina getsUSART(sms,10) es una funcion de la libreria del compilador c18 no se como esta implementada.

modifique el programa y ahora lo que hago una vez que mando los comandos at para leer el mensaje es quedarme en un bucle y esperar recibir caracteres hasta encontrar una coma",", pero los guardo en un buffer a medida que llegan por medio de interrupciones.

es decir: una vez que mando el comando para leer msj habilito interrupcion y empieza a leer lo que va llegando. uso un oscilador de 20Mhz, los resultados? no anda jeje.

la verdad que no entiendo.
por mas que el cel envie todos los caracteres concecutivamente, el tiempo de periodo de la señal del puerto es de unos 100 us y ese tiempo es suficiente para tratar la rutina de interrupcion y mas teniendo en cuenta que con un cristal de 20M un ciclo de instruccion es de 200ns.
asi que no encuentro logica a por que el pic no recibe los datos del cel.
subo denuevo el codigo por si alguien lo quiere probar, yo me rindo. voy a seguir con esto cuando consiga un modulo gsm.

no entiendo como a rizi le funciono, sera el pic?
 

Adjuntos

  • RS232INTERRUPCION.rar
    24.8 KB · Visitas: 103
Última edición:
Hola de nuevo Sdel, no te me desanimes siempre hay solución para todo...vamos desde el comienzo, yo lo que creo puede estar pasando aquí es que dejas al PIC en espera de recibir cierta cantidad de caracteres, y sino los recibe ahí se queda!!! Pon algún Sw externo que te permita sacar al PIC de ese estado y checar que has recibido en el buffer, y cuantos caracteres recibiste. Que tal que de repente el Cel te este respondiendo solo OK o ni eso, puede ser que las sentencias de printf no esten completas, que se yo, lo que más te importa ahora es saber que cel te está respondiendo.
Si es así, entonces te concentras más en el PIC, posiblemente sean problemas de configuración o del mismo C18.
Un consejo, no inicialices las variables desde su declaración, acostúmbrate a inicializarlas desde el main o dentro de la subrutina donde se usen, algunos compiladores no siempre respetan esto y puedes romperte la cabeza por algo tan simple.
Checa entonces y comentas de nuevo, no tires la toalla jejeje que casi siempre los problemas más difíciles son de soluciones simples.
Saludos
Si el Cel no te está respondiendo o solo te envía el "OK", quiere decir que el printf tiene problemas o que algo más te falta para que el Cel lo interprete bien.
 
Hola de nuevo Sdel, no te me desanimes siempre hay solución para todo...vamos desde el comienzo, yo lo que creo puede estar pasando aquí es que dejas al PIC en espera de recibir cierta cantidad de caracteres, y sino los recibe ahí se queda!!! Pon algún Sw externo que te permita sacar al PIC de ese estado y checar que has recibido en el buffer, y cuantos caracteres recibiste. Que tal que de repente el Cel te este respondiendo solo OK o ni eso, puede ser que las sentencias de printf no esten completas, que se yo, lo que más te importa ahora es saber que cel te está respondiendo.
Si es así, entonces te concentras más en el PIC, posiblemente sean problemas de configuración o del mismo C18.
Un consejo, no inicialices las variables desde su declaración, acostúmbrate a inicializarlas desde el main o dentro de la subrutina donde se usen, algunos compiladores no siempre respetan esto y puedes romperte la cabeza por algo tan simple.
Checa entonces y comentas de nuevo, no tires la toalla jejeje que casi siempre los problemas más difíciles son de soluciones simples.
Saludos
Si el Cel no te está respondiendo o solo te envía el "OK", quiere decir que el printf tiene problemas o que algo más te falta para que el Cel lo interprete bien.

jeje, gracias eric, gracias por el animo, voy a hacer lo que me decis. por las pruebas que hice, el cel si responde a los comandos enviados desde el pic, esto lo pude ver por el hiperterminal conectando el tx del cel en paralelo al pic con el terminal. lo que voy hacer ahora es recibir un solo caracter. el primero que llegue veo cual es y ver si el pic esta recibiendo datos.

te mando un abrazo eric, cuando tenga algo comento. saludos
 
hola amigos, hace tiempo que estoy sigueindo este tema y he hecho un programa para recibir y enviar sms, pero quede estancado. El programa funciona, inicia con AT luego lo configua en modo texto, realiza una llamada de prueba y la corta y finalmente envia el comando para que este atento a recibir un mensaje. luego pasa al programa principal que enciende y apaga un led cada 200 ms. esta ahi hasta qe recibe una llamada que envia el comando RING desde el telefono a la pic, ahi deberia encenderse otro led. el problema que en proteus funciona bien pero al momento de implementarlo en la pic no funciona, hace todo pero no llega al parpadeo de los leds.

me podrian ayudar porfavor, les dejo el programa que he hecho. gracias :)

#include <16f628.h>
#use delay(clock=4000000)
#use rs232 (baud=9600, bits=8, parity=N,xmit=PIN_B2,rcv=PIN_B1)
#include <stdlib.h>
#byte TRISA = 0x85
#byte PORTA = 0x05

#fuses xt,nowdt,nobrownout,nolvp,noprotect // Fusibles

int i;
char dato[3];
char mensaje[6];
char ok[3];

#INT_rda
void rda_isr()//función de interrupción por recepción de datos USART
{
gets(dato);
gets (mensaje);

if(dato[0]=='R'&&dato[1]=='I'&&dato[2]=='N'&&dato[3]=='G') //enciende led
output_high(PIN_A3);
else
output_low(PIN_A3);
return;
}

void main()
{
enable_interrupts(INT_RDA); // Interrupcion RS232
enable_interrupts(INT_EXT); // interrupcion externa
ext_int_edge(H_TO_L); // por flanco de bajada
enable_interrupts(GLOBAL);
disable_interrupts(INT_RDA);
set_tris_a(0x00); // puerto A como salida
OUTPUT_A(0x00); // estabiliza la salida a cero
output_high(PIN_A0);
printf("AT\r\n"); // Le llama la atención al teléfono.
gets(ok);
delay_ms(1000);
printf("AT+CMGF=1\r\n"); // Modo texto
gets(ok);
delay_ms(1000);
printf("ATD87663847;\r\n"); // realiza una llamada telefonica
delay_ms(5000);
delay_ms(5000);
printf("AT+CHUP\r\n"); // corta la llamada.
delay_ms(1000);
printf("AT+CNMI=1,2,0,0,0\r\n"); // espera mensaje
delay_ms(1000);
enable_interrupts(INT_RDA);

while(TRUE)
{
output_high(PIN_A0);
delay_ms(200);
output_low(PIN_A0);
delay_ms(200);
}
}
 
claro quedaba esperando datos pero ya lo solucione, el problema es que cuando llamo al cel este no reconoce la palabra RING. alguien sabe como se puede solucionar por favor??
 
Hola bacocio, dos detalles super importantes...la función "gets()" no la estás colocando dentro de tu rutina por lo que no se sabe exáctamente como opera la recepción, lo obvio sería pensar en que solo transfiere el dato recibido a la variable que estás colocando, el gran problema aquí es que tu jamás incrementas la variable del buffer( mensaje,dato ) por lo tanto como puedes checar que recibiste el "RING" si solo el primer registro del buffer almacena los datos recibidos??
La otra es que tu comparación del if puede funcionarte así como está si corriges la parte de almacenamiento en buffer, pero en lo personal yo te recomendaria implementar un contador que además de apuntar a la dirección dentro de los buffers te sirva para saber en que momento recibes la cantidad de datos necesario para entonces compararlos con el string "RING".
Checa estas dos y comentas.
Saludos
 
ok, voy a checar esos dos tips que me dijiste, pero lo hare el viernes en la noche, ya que estoy realizando mi practica en la semana.

Otra cosa, por que si quito los gets(ok) del programa cuando envia los comandos al celular este se queda pegado en la interrupcion rs232, me explico, al enviar el ultimo comando, el printf("AT+CNMI=1,2,0,0,0\r\n"); el micro no pasa a la parte de encender y apagar el led constantemente?

le puse esos gets(ok), por que asi me permite llegar hasta esa parte.

gracias
 
en tu pregunta está la misma respuesta entonces, si te das cuenta tanto ok como dato tienen una longitud de 3 bytes, al parecer entonces( no me explico como ) la función gets() te llena el buffer con los datos recibidos, pero recuerda que la función se cicla en esperar a que lleguen esos datos, por lo que si solo te llegan 3 o 4 al momento de poner gets(mensaje) el sistema se va a quedar esperando recibir más y si no lo hace simplemente se cicla. Y como solo activas la interrupción después de esperar 1seg, creo es lógico suponer que el Cel te esta respondiendo en un tiempo mucho menor...checa de nuevo sin la instrucción Delay().
Saludos
 
pucha.. probe sacando los delay, y probe solamente con un ok, o sea, cuando envio AT y la respuesta es OK este deberia encender un led, peor no paso nada. Creo que es problema de conexion, estoy utilizando el cable DKU-5 conctado directamente a la pic, sin resistencias ni zener. Quisas por ahi anda el problema, lo otro, probe los pines del conector al cel y estos son 6, 7, y el 2, donde el 2 es Gnd, en otros lados dicen que hay que ocupar los pines 6,7 y 8. pero creo que utilizando el 2 igual funcionaria por que es comun.

Si alguien tiene un ejemplo de como recibir el mensaje y encender un led con un RING o un OK, me lo podria prestar porfa.

Gracias
 
NO has probado por hyperterminal para saber que tus conexiones están bien???
Sino lo has hecho, empieza por ahí. De nada te serviría un programa "funcional" sino estás seguro que te estás comunicando bien con el Cel.
Saludos
 
Entonces si ya hiciste esa prueba no queda de otra más que confirmar que el programa es el problema, como dato curioso es que tanto tu bacocio como Sdel usan el mismo compilador que es C18...será por ahí que también el probleam sea en común a la función gets()???
Traten de cambiar de compilador como al CCS y prueben su código.
Saludos
Ok...debido a una recién formateada de mi PC no había instalado el CCS, y como la función "gets()" nunca la usé no sabía que le pertenecía al CCS. En fin, les dejo lo que la ayuda explica sobre esta función:
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.
Lo resaltado en negro define drásticamente el porque del problema.
 
Última edición:
claro, estoy ocuapando el CCS con la PIC 16F877A.

tanto como el en hyperterminal como en serial port monitor, pude enviar sms, llamar, cortar una llamada, leer memoria, recibir mensajes, pero, con la pic no puedo recibirlos.

solamente, llamar, enviar mensaje cuando se presiona un pulsador con la interrupcion externa.

ahora conecte un display lcd a la pic para ver que me guarda en el string. pero no se ve nada, conecte el cel a la pic y le envie el comando AT para recibir un OK pero no muestra nada el lcd

** En la interrupcion rs232 puse un gets() para capturar el string completo, y no caracter por caracter.

#INT_rda
void rda_isr()//función de interrupción por recepción de datos USART
{
gets(buffer);
if(buffer[0]=='O'&&buffer[1]=='K')
output_high(PIN_D3);
delay_ms(1000);
output_low(PIN_D3);
lcd_putc('\f');
for(i=0;i<10;i++)
printf(lcd_putc,"%c",buffer);
for(i=0;i<10;i++)
buffer=0;
}

pero sigue sin funcionar
 
Última edición:
bacocio te respondí brevemente en el mensaje anterior, cuando usas el gets() no se aconseja que uses interrupción alguna, tu buffer debe ser n+1 donde n es número de caractéres máximos que debes recibir. Si le pones una variable buffer con una menor cantidad de bytes vas a desbordar el puntero y corromper tu programa. Siempre ten en mente esto.
Un ejemplo de uso puede ser este:
Código:
char  string[30];

gets(string);
 if(strcmp(string, password))
    printf("OK");
donde password puede ser otro buffer de valor variable o constante, es decir:
Código:
const char password[]="RING";
ó
Código:
char password[4];//Ya luego tu le pones con que string compararlo
Espero con esto puedas trabajar mejor.
Saludos
Puedes probar haciendo esto, sin la interrupción:
Código:
char dato[6];


printf("AT+CHUP\r\n");             // corta la llamada.  
delay_ms(1000); 
printf("AT+CNMI=1,2,0,0,0\r\n");           // espera mensaje
gets( dato );
if(strcmp(dato, "RING")){
    output_high(PIN_A0);
    delay_ms(1000);
    output_low(PIN_A0);
}else{
    output_high(PIN_A3);
    delay_ms(1000);
    output_low(PIN_A3);
}
//delay_ms(1000); 
//enable_interrupts(INT_RDA);
 
Última edición:
Atrás
Arriba