bclose

ENVIAR Y RECIBIR LLAMADAS Y SMS

Optimizando el funcionamiento del módulo GPRS SIM900
tienda online prometec

Objetivos

 

 

    • Optimizar la programación del GPRS.
    • Dotarlo de mayor autonomía.
    • Crear una función para enviar los comandos AT
    • Agrupar el envío y la recepción de llamadas y SMS en un sólo programa.
 

Material requerido.

Imagen de Arduino UNOArduino UNO o equivalente
modulo gprsUn Shield GPRS SIM900
conexionesAlgunos cables de protoboard.
Power supply

 Una fuente de alimentación para Arduino.

 

OPTIMIZAR EL PROGRAMA

 

En las sesiones anteriores dedicadas al GRPS hemos visto cómo conectarlo correctamente y los comandos AT necesarios para enviar y recibir llamadas y SMS de una forma bastante sencilla. Sin embargo, para el que se haya fijado, aunque los comandos AT se envían correctamente y el módulo cumple la función que buscamos, hay algunas cosillas que se pueden mejorar.

Y es que al parecer la librería SoftwareSerial no se lleva del todo bien con el módulo GPRS y los comandos AT; y al enviar simplemente estos comandos con función SIM900.println(); algunas respuestas se quedan en el limbo.

A esto podríamos añadir que, siendo el GPRS un módulo orientado hacia proyectos autónomos y sin supervisión, no tendremos acceso al monitor serie (hasta ahora lo hemos supervisado desde ahí), no estaremos seguros de que las cosas estén yendo bien y estemos realmente conectados a la red móvil.

Y por último, podría ser que durante el periodo que tengamos funcionando nuestro proyecto perdiera la alimentación del Arduino o del GPRS, o se desconectase de la red móvil por alguna razón. Así que también vamos a implementar una serie de funciones para que sea capaz de reiniciarse y configurarse de forma autónoma, y de que se asegure que estemos conectados a la red antes de enviar llamadas o SMS.

Para poder reiniciarlo de esta forma y dotarle de autonomía es imprescindible haber realizado la soldadura que habilita el encendido por software del módulo GPRS mediante un pulso en el pin 9, y conectarlo al pin 9 de Arduino que usaremos para ello (ya hablamos de esto en las sesiones anteriores).

activar tarjeta software

 

FUNCIÓN PARA ENVIAR LOS COMANDOS AT

 

Al parecer el error al recibir algunas respuestas de los comandos AT por el monitor serie se debe a que enviamos el comando siguiente antes de recibir la respuesta, y los “delays” no parecen solucionarlo, sino todo lo contrario (como casi siempre).

Por lo tanto crearemos una función sendATcommand2 con los siguientes objetivos:

 
  • Enviar el comando AT.
  • Esperar una respuesta del SIM900.
  • Comprobar que la respuesta es correcta.
  • Mostrar por el monitor serie la respuesta recibida. 

La programación de la función queda de la siguiente forma:

int enviarAT(String ATcommand, char* resp_correcta, unsigned int tiempo)
{

  int x = 0;
  bool correcto = 0;
  char respuesta[100];
  unsigned long anterior;

  memset(respuesta, '\0', 100); // Inicializa el string
  delay(100);
  while ( SIM900.available() > 0) SIM900.read(); // Limpia el buffer de entrada
  SIM900.println(ATcommand); // Envia el comando AT
  x = 0;
  anterior = millis();
  // Espera una respuesta
  do {
    // si hay datos el buffer de entrada del UART lee y comprueba la respuesta
    if (SIM900.available() != 0)
    {
        respuesta[x] = SIM900.read();
        x++;
      // Comprueba si la respuesta es correcta
      if (strstr(respuesta, resp_correcta) != NULL)
      {
        correcto = 1;
      }
    }
  }
  // Espera hasta tener una respuesta
  while ((correcto == 0) && ((millis() - anterior) < tiempo));
  Serial.println(respuesta);

  return correcto;
}

Está función la usaremos siempre que enviemos un comando AT, y si queremos verificar la respuesta, simplemente la incluiremos dentro de un if que verifique que nos el módulo nos haya devuelto la respuesta que buscamos.

Esta estructura condicional la usaremos para verificar que realmente estemos conectados a la red móvil, aunque podríamos usarlo en todos los comandos AT para que, en caso de que algo falle, nos saque un mensaje por pantalla indicándonos dónde está el error.  Realmente no totalmente necesario ya que leyendo el monitor serie se puede ver dónde falla con sólo  mirar las respuestas a los comandos AT.

 

ENCENDER EL MÓDULO POR SOFTWARE

 

Ya hemos hablado anteriormente acerca de cómo encender y apagar el módulo sin tener que presionar el pulsador del GPRS, enviando un pulso de un segundo desde Arduino al pin 9 de la tarjeta. Sin embargo, imaginad que enviamos las instrucciones para encenderlo y resulta que ya estaba encendido. Lo que haríamos sería apagarlo.

Así que vamos a crear también una función para encender el módulo pero comprobando antes que no está encendido ya. Es muy sencillo, si enviamos el comando “AT”  y nos devuelve OK es que estaba encendido. Si no devuelve nada tendremos que enviar el pulso para encenderlo.

void power_on()
{
  int respuesta = 0;

  // Comprueba que el modulo SIM900 esta arrancado
  if (enviarAT("AT", "OK", 2000) == 0)
  {
    Serial.println("Encendiendo el GPRS...");

    pinMode(9, OUTPUT);
    digitalWrite(9, HIGH);
    delay(1000);
    digitalWrite(9, LOW);
    delay(1000);

    // Espera la respuesta del modulo SIM900
    while (respuesta == 0) {
      // Envia un comando AT cada 2 segundos y espera la respuesta
      respuesta = enviarAT("AT", "OK", 2000);
      SIM900.println(respuesta);
    }
  }
}

 

Complementariamente a esta función vamos a crear otras dos muy sencillitas, una que apague el módulo y otra que incluya estás dos que para reiniciar el módulo, y que usaremos si perdemos la conexión a la red.

void power_off()
{
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(1000);
}

void reiniciar()
{
  Serial.println("Conexion a la red perdida. Reiniciando el modulo...");
  power_off();
  delay (5000);
  power_on();
}

FUNCIONES PARA CONFIGURAR EL MÓDULO Y ENVIAR LLAMADAS Y SMS

 

También tenemos funciones que ya hemos usado anteriormente, pero que tenemos que adaptar a la filosofía de esta sesión. Es decir, enviaremos los comandos AT utilizando la función que hemos creado y comprobaremos que estemos conectados correctamente a la red móvil.

Estas funciones son las que usamos para configurar el módulo correctamente y las que propiamente realizan el envío de las llamadas y los SMS.

void iniciar()
{
  enviarAT("AT+CPIN=\"1867\"", "OK", 1000);
  Serial.println("Conectando a la red...");
  delay (5000);

  //espera hasta estar conectado a la red movil
  while ( enviarAT("AT+CREG?", "+CREG: 0,1", 1000) == 0 )
  {
  }
  Serial.println("Conectado a la red.");
  enviarAT("AT+CLIP=1\r", "OK", 1000); // Activamos la identificacion de llamadas
  enviarAT("AT+CMGF=1\r", "OK", 1000); //Configura el modo texto para enviar o recibir mensajes
  enviarAT("AT+CNMI=2,2,0,0,0\r", "OK", 1000); //Configuramos el modulo para que nos muestre los SMS recibidos por comunicacion serie
  Serial.println("Preparado.");
}

void mensaje_sms()
{
  if (enviarAT("AT+CREG?", "+CREG: 0,1", 1000) == 1) //comprueba la conexion a la red
  {
    Serial.println("Enviando SMS...");
    enviarAT("AT+CMGF=1\r", "OK", 1000); //Comando AT para mandar un SMS
    sprintf(aux_str, "AT+CMGS=\"XXXXXXXXX\"", strlen(sms)); //Numero al que vamos a enviar el mensaje
    //Texto del mensaje
    if (enviarAT(aux_str, ">", 10000) == 1)
    {
      enviarAT(sms, "OK", 10000);
    }
    Serial.println("SMS enviado");
  }
  else
  {
    reiniciar();
    iniciar();
  }
}
void llamar()
{
  if (enviarAT("AT+CREG?", "+CREG: 0,1", 1000) == 1) //Comprueba la conexion a la red
  {
    Serial.println("Realizando llamada...");
    enviarAT("ATDXXXXXXXXX;", "OK", 1000);
    delay(20000); // Espera 20 segundos mientras realiza la llamada
    enviarAT("ATH", "OK", 1000); // Cuelga la llamada
    Serial.println("Llamada finalizada");
  }
  else
  {
    reiniciar();
    iniciar();
  }
}

ESTRUCTURA DEL PROGRAMA

 

Una vez hemos creado las funciones que vamos a necesitar, la estructura del programa no tiene nada demasiado complicado. Con este programa realizaremos una llamada al teclear una “l” en el monitor serie y enviaremos un SMS con la letra “s”. Evidentemente también recibiremos llamadas y SMS y mostraremos la información de ambas en pantalla, del número de teléfono y del contenido del mensaje en el caso de que sea un SMS.

#include <SoftwareSerial.h> 

SoftwareSerial SIM900(7, 8); // Configura el puerto serial para el SIM900. Para el Arduino MEGA utilizar pines 10 y 11

int respuesta;
char aux_str[50];

//Contenido del sms que enviamos. \x1A corresponde al caracter de finalizacion
char sms[] = "Mensaje enviado desde el Arduino de Prometec! \x1A \r\n";

void setup()
{
  SIM900.begin(19200); //Configura velocidad del puerto serie para el SIM900
  Serial.begin(19200); //Configura velocidad del puerto serie del Arduino
  delay(1000);
  Serial.println("Iniciando...");
  power_on();
  iniciar();
}

void loop()
{
  if (Serial.available())
    switch (Serial.read())
    {
      case 'l':
        llamar();
        break;
      case 's':
        mensaje_sms();
        break;
    }
  if (SIM900.available()) {
    Serial.write(SIM900.read());
  }
}
comandos AT gprs

Podéis descargar aquí el programa completo: Envio_y_recepcion_de_llamadas_y_SMS.

Con este programa creemos que ya podréis afrontar vuestros proyectos con mayores garantías de éxito, otorgándoles un cierto nivel de autonomía y confianza. La estructura de tipo switch() que hemos creado nos da la posibilidad de incluir de forma muy sencilla otros casos en los que sean las lecturas de ciertos sensores las que activen las llamadas o los SMS, e incluso podrías incluir en estos últimos el valor de las lecturas dentro del texto del SMS en el caso que sea necesario.

 

Resumen de la sesión

 

En esta sesión hemos aprendido varias cosas importantes:

 
    • A enviar correctamente los comandos AT y asegurarnos de recibir la respuesta del módulo GPRS.
    • A verificar la respuesta cuando lo creamos necesario.
    • Asegurarnos de que estamos correctamente conectado a la red móvil.
    • A encender y reiniciar el módulo por software.
    • Hemos creado un programa para recibir y enviar llamadas y SMS, al que hemos dotado de capacidad de trabajar de forma autónoma con ciertas garantías de éxito.
 
 
 

LikeUsOnFacebook_Icon

 

(40) Comments

  • Hola que tal disculpa tengo problemas, me sale este error
    Conectando a la red…
    Iniciando…
    AT+CPIN=”1234″

    ERROR

    Conectando a la red…
    AT+CREG?

    +CREG: 0,2

    OK

    Me ayudarias mucho si me guias en una posible solucion, gracias

    • Hola Jonathan ¿estás seguro de que es ese el pin de SIM?

  • Hola se puede realizar con un módulo GSM sim 800L??? Saludos

    • Hola Ignacio, en principio sí deberías poder hacerlo. Las conexiones serían diferentes pero los comandos AT (y por tanto la programación) sería la misma. Un saludo.

    • Jhon

    Ola buenas .me podrías decir que parlantes o altavoces se le puede poner al sin 900

    • BUenas tardes John, La salida de estos modulos es de auriculalres tipica como las de los telefonos celulares, asi que te valen los tipicos auriculares o cualquier altavoz que use mini jack estereo (O sea casi cualquiera de los baratos)

    • Carlos

    Hola, excelente explicación!!. Me encuentro trabajando con el Icomsat 1.1 sim900, que es muy similar al que usas. Probando tú código para comprobar el funcionamiento de este módulo me pasa lo siguiente: me imprime el mensaje Iniciando…. y el mensaje Encendiendo el GPRS…(que de hecho si lo enciende) pero después de ahí no hace nada mas, salvo que el monitor serial va bajando como si imprimiera algo (pero no se ve), tal ves tengas idea de lo que sucede, si fuera así me gustaría que me ayudaras.
    Saludos cordiales.

    • Hola Carlos, lo hariamos encantados, pero tienes que entender que si es diferente placa va a ser dificil porque por lo que veo se comporta de manera diferente

  • Hola buenas tardes, muchas gracia por compartir estos proyectos y en este en particular tengo el siguiente problemas, el programa funciona en su totalidad, menos el envío de sms, el modulo realiza las llamadas y recibe los sms, pero no es capaz de enviar ningún sms, alguna idea de cual podría ser el problema?

    • Hola Carlos, ya está corregido. Era un error de estos tontos pero difíciles de ver… un par de espacios en el comando AT: AT + CMGS en vez de AT+CMGS. Ya está corregido y el programa subido con ese cambio. Un saludo.

      • Vale Ivan, lo probare y comento muchas gracias

      • Estimado Ivan aun lo logro que se envié el mensaje, e estado moviendo algunas cosas y no encuentro el origen.

        • Hola Carlos, he probado el programa y a mí me funciona. Estás probando descargando el programa del enlace o copiando y pegando de la sesión?

          • Ivan, descargue el programa, pero sospecho que sea la sim-card, hoy comprare otra y probare.

          • Imagen de perfil de Ivan

            La verdad es que sería extraño que la tarjeta no te deje enviar SMS, pero bueno por probar… De todas formas si aún así sigues sin conseguirlo me dices y lo miramos un poco más.

          • Ivan, finalmente tuve que realizar dos cambios ufff, espero les sirva a los demás, primero la entena que estaba utilizando era de 900Mhz, por lo que tuve que comprar una cuatribanda (soy de Chile, acá funciona así), lo segundo cambie la Simcard de Movistar por Wom y ahora todo funciona ok, espero les sirva, la antena que instale es una de ventana de 3.5dB, saludos a todos.

          • Imagen de perfil de Ivan

            Ostras! Me3 alegro mucho que hayas podido solucionarlo. Seguro que a mucha gente le sirve de ayuda. Muchas gracias.

  • Hola Ivan.
    Estoy usando esta placa con un Mega. Si en el Mega uso los pines 10 y 11 anda todo bárbaro.
    El problema que esta placa GPRS no trae perforaciones para atornillarla al gabinete, entonces se me ocurrió montarla sobre los conectores del Mega, pero en ese caso tengo que usar los pines 7 y 8, y no funciona.
    Si a la placa la monto sobre un Arduino UNO con el mismo soft, sí funciona.
    Hay alguna restricción en el Mega que no permita usar los pines 7 y 8 y por eso estamos obligados a usar los pines 10 y 11 ?
    Gracias.

    • Hola Gustavo, efectivamente la librería software serial que usamos para simular un puerto serie en dos pines digitales no permite utilizar los pines 7 y 8 del Arduino Mega, por eso no te funciona de esa forma. Un saludo.

  • Hola Ivan

    Estoy realizando un proyecto, lo que deseo es enviar el msje a dos numeros diferentes realizando una sola accion. Queria saber si es posible¿?

    Saludos

    • Hola Fabian, que yo sepa no se puede mandar un sms a varios números a la vez, tendrías que mandar dos mensajes, uno con cada número. De todas formas sois ya varios los que preguntáis por ese tema así que en cuanto tenga algo de tiempo voy a ver si encuentro algo. Un saludo.

      • Yoshio

      puedes mandar dos mensajes a la vez, pero de esta forma, mandado el pulso a algun pin, lo consiguras para que mande dos mensaje

      {if((digitalRead(5) == 1)&&(contador5 == 0)){
      SIM900.print(“AT+CMGF=1\r”);
      delay(100);
      SIM900.println(“AT+CMGS=\”xxxxxxxxxxxxx\””);
      delay(100);
      SIM900.println(“ALERTA 1”);
      delay(100);
      SIM900.println((char)26);
      delay(100);
      SIM900.println();
      delay(1000);
      Serial.println(“ALERTA 1 ENVIADA”);
      SIM900.print(“AT+CMGF=1\r”);
      delay(5000);
      SIM900.println(“AT+CMGS=\”xxxxxxxxxx\””);
      delay(100);
      SIM900.println(“ALERTA 2”);
      delay(100);
      SIM900.println((char)26);
      delay(100);
      SIM900.println();
      delay(1000);
      Serial.println(“ALERTA 2 ENVIADA”);

      con eso mandas dos mensajes a dos numeros diferentes con una sola señal

  • Hola Ivan, acá estoy de vuelta tratando de conectar la SIM900 con un Arduino Mega usando el port serial 3.
    No me anda, repasemos por si me olvidé de algo:
    1) en la SIM cambié los jumpers para usar D0/TX y D1/RX en lugar de los pines 7 y 8
    2) Cambié las conexiones en la SIM y Arduino
    3) En el código, cambié todo lo que era SIM900 por Serial3 (por ejemplo SIM900.begin(19200) por Serial3.begin(19200))
    4) La SIM la enciendo desde el Arduino (eso sigue funcionando)
    5) Me queda la duda cómo configuro la velocidad de la SIM, o la velocidad por defecto es 19200 ?
    Gracias.

    • Hola Gustavo, en teoría viene por defecto a 19200. No veo ninguna cosa rara, pero yo propbaría a seguir utilizando los pines 7 y 8 de la SIM900 pero conectados al puerto serie 3 del Mega. A ver si así te funciona. Un saludo.

    • Estimado a veces vienen con velocidades diferentes, te recomiendo re-programar la velocidad del modulo SIM900, yo utilizo el putty y el comando para cambiar la velocidad es el AT+IPR=xxxx, en mi caso venia por defecto a 4800bps y los cambiea 19200bps, lo que seria AT+IPR=19200, espero te ayude, saludos.

  • Hola amigo eh seguido tus tutoriales desde el inicio muy buenos por cierto e logrado una aplicacion bastante buena solo que tengo un pequeno problema , mi sim900 se queda sin red es decir deja de parpadear el led que parpadea y dice que esta listo para llamar o mandar mensajes, lo que quiero hacer es que cuando la shield se desconecte automaticamente se conecte …

    ya intente agregar la parte de tu programa (ENCENDER EL MODULO POR SOFTWARE) pero al momento de compilar en Arduino Mega me marca un error de compilacion en la variable (enviarAT) me dice que la variable no esta declarada que es lo que tengo que hacer nose como solucionar ese error :S

    espero tu ayuda muchas gracias!

    • Hola Jose, he probado el programa y no me da ningún error. Debe faltarte de declarar alguna de las variables que usa para el reinicio. Si puedes cópiame el error exacto que te sale al compilarlo para ver qué puede ser. Un saludo.

      • Hola Ivan muchas gracias por tu ayuda ! este es el error que me sale

        solo agrego las rutinas:
        power_on()
        power_of()
        Reiniciar()

        llamar.ino: In function ‘void power_on()’:
        llamar.ino:24:32: error: ‘enviarAT’ was not declared in this scope
        Error compiling.

        quisiera mostrarte todo mi codigo para que pudieras entenderme mejor gracias !

        • Hola Jose, he descargado por si acaso el programa que tenemos y compila bien, así que debe haber algún error cuando añades esas funciones. Si quieres puedes contactar con nosotros en info@prometec.net

          Un saludo.

    • Jorge Carranza Torres

    Quiero implementar este proyecto con un arduino DUE y un GPRS SIM900
    y me da este mensaje de error cuando quierocompilar

    Arduino:1.8.1 (Linux), Tarjeta:”Arduino Due (Programming Port)”

    • Hola Jorge, te borro el error para que no ocupe tanto. Sin haber probado y solo “por si acaso”. ¿Tienes instalado el soporte para DUE en Herramientas -> Placa -> Gestor de tarjetas? Un saludo.

    • Jorge Carranza Torres

    Hola tengo un arduino DUE y me da error de compilacion en tarjeta arduino DUE que podra ser?????

    • Hola Jorge, supongo que el problema viene con la librería SoftwareSerial, pero como el Due tiene varios puertos de comunicación puedes prescindir de ella y utilizar uno de ellos. Un saludo.

  • Hola José. excelente tu página, Felicitaciones …!!
    Quisiera hacerte algunas consultas:
    1) Por qué usamos los pines 7 y 8 y no los 0 y 1 en la SIM 900 ?
    2) La misma duda para del Arduino UNO, por qué no usamos los pines 0 y 1 ?
    3) Cuál sería el equivalente al pin 9 de este ejemplo para el Arduino Mega ? Podríamos usar el pin 12 ?
    4) La misma consulta que te hice para el UNO te la repito para el MEGA, por qué no usamos los pines 0 y 1 ?

    Muchas gracias.

    • Hola Gustavo, a ver si te contesto todo bien jeejje

      1) El módulo viene fijado para comunicarse con esos pines.
      2) No utilizamos los pines 0 y 1 del Arduino Uno porque es el único puerto serie que tiene y es que usa a la hora de cargar los programas, así que es más comodo usar la librería software serial de manera que podemos dejar el puerto serie de los pines 0 y 1 libre.
      3) Lo mismo que la 1). El pin 9 delo módulo es el que tiene fijado para encender el módulo por software. Eso sí, podrías usar cualquier pin digital de Arduino para controlarlo, no tiene por qué ser también el 9.
      4) En el Arduino Mega podrías usar cualquiera de los otros 3 puertos de comunicaciones que tiene y no necesitarías usar la librería SoftwareSerial, aunque justo los pines 0 y 1 son los del puerto que usa para cargar los programas así que no usaría ese. Puedes usar cualquiera de los otros que vienen marcados con Rx y Tx.

      Un saludo.

    • José Ignacio

    hola,
    he estado mirando el tutorial de MÓDULO GSM/GPRS: llamar y enviar SMS. Como soy completamente nuevo en esto, me gustaría que me echases una mano y me dijeras como puedo hacer lo que quiero.
    Te explico:

    Necesito tener por un lado un botón-pulsador con un micrófono y un altavoz que me sirva para pulsando el botón, que el arduino con el módulo gsm realice una llamada a un único número predeterminado para mantener una conversación con el micrófono y el altavoz . Al terminar la conversación y colgar el móvil que recibe la llamada, vuelva a estar listo para pulsar el botón y realizar otra vez la misma llamada. También me gustaría que me enviase un sms a otro móvil cada vez que se hiciera una llamada.

    Si me puedes decir por favor, que debo comprar y como conectar y programar…
    Gracias

    • Hola José Ignacio, tienes un programa y una sesión en la página en la que utilizamos el puerto serie para enviar y recibir mensajes y llamadas. Las llamadas las hacemos al introducir un carácter en el monitor serie, pero seria muy fácil cambiar eso en el case por una variable en la que leas el estado del pulsador y al pulsarlo llame o mande un mensaje.

      Y lo mismo con el sms, no tendrías más que cambiar la condición del case.

      En cuanto al micrófono y el altavoz no tienes más que enchufarlos en las tomas que tiene el módulo.

      El enlace a la sesión es este: http://www.prometec.net/gprs-enviar-recibir-llamadas-sms/

      A ver si te sirve, y si tienes alguna duda me dices. Un saludo.

  • Que tal , muy buenos tutoriales la verdad , tengo una consulta yo tengo un shield con el integrado SIM900 , pero no es el mismo al que usted usa , realizé las sesiones donde explica como enviar LLamadas y SMS , y la verdad es que si me funciona , pero en esta sesión usted habla de autonomía del shield , y que para eso es necesario soldar el PIN9 .
    El shield suyo usa el PIN 7 y 8 para comunicarse , pero el mío usa el 2 y 3 , el mío se puedo montar en el arduino UNO , pero no se nada de ese PIN necesario para darle autonomía al shield GSM de mi shield.
    Tengo este mismo que esta en el link
    http://www.dinteltec.mx/product.php?id_product=75
    al final de la página , me hablan de este shield pero nada acerca del pin de autonomía .

    • Hola Antero, pues la verdades que hes intentado buscar información de tu shield pero no he encontrado ningún sitio que especifique ese pin. Un saludo.

Give a Reply

WordPress Anti-Spam by WP-SpamShield