Ejemplo basico Alarma GSM con wavecom y arduino atmega-8 RS232

Hola

Un compañero de trabajo me pidio que su alarma pudiera enviar sms o llamar a varios telefonos para avisar de la intrusion, empleando una salida de esta, le he realizado un montaje empleando un modem wavecom por RS232 y aprovechando una placa de arduino clonico con RS232 incorporado, por lo de no emplear modulos conversores TTL-RS232 externos.

Como el envio de mensajes SMS tiene un coste y cada x mensajes podria quedarse sin saldo en la tarjeta la opcion que he elegido es que cuando suene o detecte intrusion realize unas llamadas a los numeros de telefono almacenados en la SIM.

Esta opcion no le hace consumir saldo pues son llamadas perdidas (el usuario en su telefono ha cambiado el tono para cuando recibe una llamada del sistema de alarma bien escandaloso) aparte que le he añadido un pulsador para que pueda verificar cuando este en el lugar que funciona bien pues este pulsador realiza una llamada solo al primer numero de la guia.

El sistema es muy sencillo, la programacion tambien, sin florituras pues un atmega8 no tiene nada de espacio para almacenar un programa decente, os dejo el codigo para cualquier aficionado que este empezando y quiera entender un poco como conectar un modem gsm a un arduino.

Este es el montaje:

Este es el cable para conectar modem GSM y Arduino RS232 (los conectores de ambos son hembras SuB-D)

Y este es el codigo que he empleado, veran muchos delays pero son necesarios para que la SIM quede preparada.
(Estoy intentando arreglar los saltos de linea que quedan hechos un churro al copiarlo al foro)

//  ????????????????????????????????????????????????????????????????????????????????
//  ? PROGRAMA: ALARMA GSM  REALIZA LLAMADAS PERDIDAS A USUARIOS CUANDO HAY ALARMA     
//  ? Autor: HEKE               Mail:                      TF:                                                               
//  ????????????????????????????????????????????????????????????????????????????????
//  ? Fecha Inicio:   06 JULIO DE 2013                                                                                    
//  ? Version 0.9 Modem Wavecom y Arduino clonico con chip Atmega-8 CON TTL--> RS232             
//  ? Observaciones: Dar de alta los numeros en la SIM añadiendo numero de orden al                     
//  ? nombre en la agenda, ej: 1Heke  2OtroNombre 3OtroMas etc...  maximo 9 nombres              
//  ????????????????????????????????????????????????????????????????????????????????

//  ??????????????????????????????????????????????????????????????????
//  ?     ****   CONECTOR SUBD-9 HEMBRA DE LA PLACA ATMEGA-8                        
//  ??????????????????????????????????????????????????????????????????
//          
//  ?????????????????????????????????????????????      1.-DCD    7.-RTS
//  ?     ?????????????????????????????         ?      2.-RX     8.-CTS
//  ???  \ (05)  (04)  (03)  (02)  (01) /  ??   ?      3.-TX     9.-RI
//  ???   \   (09)  (08)  (07)  (06)   /   ??   ?      4.-DTR
//  ?        \_______________________/          ?      5.-GND
//  ?????????????????????????????????????????????      6.-DSR
//          
//          
//  ????????????????????????????????????????????????????????
//  ?     ****   CONECTOR SUBD-15 HEMBRA DEL MODEM WAVECOM               
//  ????????????????????????????????????????????????????????
//            
//  ?????????????????????????????????????????????????   1.-CD       8.-DTR    15.-SPK2N
//  ?    ??????????????????????????????????????     ?   2.-TX       9.-GND 
//  ??? \   (05)  (04)  (03)  (02)  (01)     / ??   ?   3.-BOOT    10.-SPK2P
//  ???  \     (10)  (09)  (08)  (07)  (06) /  ??   ?   4.-MIC2P   11.-CTS
//  ?      \ (15)  (14)  (13)  (12)  (11)  /        ?   5.-MIC2N   12.-RTS
//  ?        \____________________________/         ?   6.-RX      13.-RI
//  ?????????????????????????????????????????????????   7.-DSR     14.-RESET
//          
//   CABLE DEL WAVECOM AL ARDUINO CLONICO
//  =======================================
//    DB15         DB9
//
//     2 -------->  2
//     6 -------->  3
//     9 -------->  5
//    11??
//    12??


String Texto = "";           // Variable para sacar por display lo que devuelve el modem
String Texto1 = "";          // Variable para sacar por display lo que devuelve el modem
int ManualPin = 14;          // Entrada para pulsar y comprobar que funciona  
int AlarmaPin = 15;          // Entrada cuando se activa la alarma
int Guia = 0;
int PrimeraComa = 0; 
char Usuarios[1];
   
// ????????????????????????????????????????????????
// ?  FUNCION Setup                                                                  
// ????????????????????????????????????????????????
void setup(){
   pinMode(ManualPin, INPUT);     
   pinMode(AlarmaPin, INPUT);  
   digitalWrite(ManualPin, HIGH);  
   digitalWrite(AlarmaPin, HIGH);  
  
   Serial.begin(9600);         // 9600 baudios velocidad del wavecom
   Serial.flush();             // Limpiamos puerto serie
   delay(2000);

   Envia("AT+CFUN=1");         // Inicializacion
   delay(4000);

   Serial.print("AT+CPBS=");
   Serial.write((byte)0x22);   // Envia comillas
   Serial.print("SM");
   Serial.write((byte)0x22);   // Envia comillas
   Serial.write((byte)0x0D);   // Envia intro
   LeeSerie(); 
   delay(12000);

   Envia("ATE0");        
   delay(29000);  
 
   while (Guia < 1){ 
       Envia("AT+CPBS?");      // Pregunta cuantos numeros de TF hay en la SIM
       PrimeraComa = 0; 
       Usuarios[1] = '0';
       delay(3000);
       int PrimeraComa = Texto.indexOf(',');   // Busca la primera coma en la respuesta 
       Texto.substring((PrimeraComa+1),(PrimeraComa+3)).toCharArray(Usuarios, 2);
       Guia = atoi(Usuarios);         
      }

   delay(2000);
   LeeSerie();
   Serial.flush();
   delay(1000);
}

// ????????????????????????????????????????????????
// ?  FUNCION Loop                                                                  
// ????????????????????????????????????????????????
void loop(){
  Texto,Texto1="";
  LeeSerie();
  Texto1=Texto.trim();      
         
  if (digitalRead(AlarmaPin) == LOW) {
     for (int Posicion=1; Posicion < Guia+1; Posicion=Posicion+1){
        Envia("ATH0");               // Cuelga cualquier posible llamada
        delay(2000);
        String Listin = "ATD>SM";
        Envia(Listin+Posicion+";");  // Llama uno por uno a todos los numeros de la lista de la SIM
        delay(16000);
        Envia("ATH0");               // Cuelga la llamada antes de pasar al siguiente numero
        delay(2000);   
        }
      } 

  if (digitalRead(ManualPin) == LOW) {
      Envia("ATH0");                // Cuelga cualquier posible llamada
      Envia("ATD>SM1;");            // Llama al primer numero de la lista de la SIM PARA COMPROBACION
      delay(18000);
      Envia("ATH0");                // Cuelga la llamada de comprobacion
      delay(2000);   
      }    
}


// ????????????????????????????????????????????????
// ?  FUNCION Envia comando al Modem                                              
// ????????????????????????????????????????????????
void Envia(String Comando) {
  Serial.print(Comando);
  Serial.write((byte)0x0D);   // Envia retorno de carro o INTRO
  delay(300);                 // Le da tiempo a respirar al bicho
  LeeSerie(); 
}

// ????????????????????????????????????????????????
// ?  FUNCION LeeSerie                                                              
// ????????????????????????????????????????????????
String LeeSerie(){
  Texto="";
  while (Serial.available() > 0){
        char inChar = Serial.read();
        Texto += inChar;
        }
  return Texto;
 }

Como podeis ver es muy simple y obvia todos los mensajes que envia el modem excepto cuando le pedimos que nos diga cuantos numeros de telefono tiene almacenados en la SIM, con la orden AT+CPBS? entonces si leemos la respuesta pues el usuario puede haber dado de alta 1, 2 o 9 (9 es el maximo porque creo que una alarma que tenga que marcar mas de 10 numeros es una burrada).

Luego pondre unos ejemplos de como he leido las respuestas para cuando ingresamos el pin y otros tipos de comandos pero en ese montaje no lo he empleado, de hecho he quitado la libreria LCD pues se me iba de memoria (8k) y he dejado la SIM sin peticion de PIN.

Simplemente le hago un bucle hasta que me devuelva un valor numerico de numeros almacenados en la guia, esto significa que el modem esta operativo, se ha registrado en la red y esta listo para llamar.

Os aconsejo descargaros los manuales del wavecom o dle modem que querais usar y los comandos AT, necesarios para entender como funciona un modem GSM.

Un saludo.

Buena pinta, si señor.

Gracias Fm

Es muy sencillo y generico pues no empleo libreria alguna y las ordenes no son complicadas, he intentado estructurarlas lo mas facil posible pensando que puede ayudar a entender un poco el manejo del modem con comandos AT a los nuevos.

Un saludo.

Como he comentado antes, algunos ejemplos de codigo que he empleado para leer lo que el wavecom me dice, para quien pueda serle util:

// ????????????????????????????????????????????????
// ?  FUNCION Resetea Modem    Envia: ATZ                                           
// ?                           Responde: ATZ.._OK._                                  
// ????????????????????????????????????????????????
void ResetModem(){
   Envia("ATZ");           // Hacemos un reset del modem
   LeeSerie();  
   if ((Texto.substring(0,3) == ("ATZ")) && (Texto.substring(6,8) == ("OK"))) {
      lcd.print("Reset OK"); 
      } 
}

// ????????????????????????????????????????????????
// ?  FUNCION Quita el Eco     Envia: ATE0                                              
// ?                           Responde: ATE0.._OK._                                   
// ????????????????????????????????????????????????
void QuitaEco(){
   Envia("ATE0");   // Desabilita el eco
   LeeSerie();  
   if ((Texto.substring(0,4) == ("ATE0")) && (Texto.substring(7,9) == ("OK"))) {
      lcd.print("Quitado el eco"); 
      } 
}

// ????????????????????????????????????????????????
// ?  FUNCION Introduce Pin    Envia: AT+CPIN=1234                                    
// ????????????????????????????????????????????????
void CargaPin(){
   String Pin_Texto = "AT+CPIN=";
   Envia(Pin_Texto+Pin_Numero);  // Decimos que el pin es igual a 1234  "AT+CPIN=1234" 
   delay(1000);
}

// ????????????????????????????????????????????????
// ?  FUNCION Comprueba Pin    Envia: AT+CPIN?                                          
// ?                           Responde: ..+CPIN: SIM PIN                              
// ?                           Responde: ..OK....+CPIN READY                            
// ????????????????????????????????????????????????
void VerificaPin(){
   Envia("AT+CPIN?");  
   LeeSerie();  
   if (Texto.substring(2,7) == ("ERROR")) {
      lcd.print("Error en Sim"); 
      } 
   else if (Texto.substring(2,16) == ("+CPIN: SIM PIN"))  {
      lcd.print("Sim ok-Falta Pin"); 
      } 
   else if (Texto.substring(2,4) == ("OK"))  {
      lcd.print("Pin Cargado"); 
      }      
}

Hay que tener presente que cuando "hablamos" con un momem GSM nos puede dar mas respuestas que las que yo he puesto, estas son mero ejemplo de jugar con el para las pruebas que hice, pero hay que leerse el manual de este y comprobar los codigos AT, una respuesta puede ser larga o corta dependiendo si hemos desabilitado el eco p.ej. o no.

para mi es muy bueno y sera util gracias por compartir

La verdad es que te ha quedado algo muy simple de manejar.

Gracias por compartir, Heke

Sobre la tarjeta de prepago, ¿cuál recomendarías por economía?

Hola Curro92

Pues te puedo decir la que yo uso, aunque siempe pueden haber otras opciones ya que cada dia, cada operador saca alguna historia nueva...

Yo uso Simyo, antes tuve airtel-vodafone, movistar, amena, orange y al final me decidi por simyo (Usa las antenas de Orange) desde la tarifa pioneros hasta hoy en dia.

Mantengo simyo en mi familia por economico y el poder llamar 10min gratis a numeros simyo (solo 17 centimos de establecimiento de llamada), el precio minuto pues a elegir... hay varias gamas y compromisos... como la mayoria de operadores pero no tiene cuota minima mi tarifa.

Lo que me influye a dejar con tarjeta simyo la alarma no es en si el precio (igual pepephone tiene mas economico) es el tiempo que me deja antes de tener que volver a recargar, me explico, al principio podias dejar la tarjeta 9 meses sin recargar, despues lo bajaron a 6 y ahora a 4 pero aun asi es el espacio mas largo sin recargar en prepago de las operadoras que conozco. Luego, controlar gasto, consumo o dar de baja es muy facil desde la web y la recarga minima son 5 euros.

Si sirve de referencia a nivel particular, no tengo wassap pero si conecto a internet con el movil esporadicamente para consultas o ver el banco, ebay o cosas pequeñas y el coste de conectarte es de risa... centimos... eso me ahorra una tarifa plana que es lo que todas las operadoras persiguen, enganchar al personal con la tarifa plana... por eso tanto wassap y programas de redes sociales en los moviles defabrica.

Mi hijo viene a consumir unos 8 o 10 euros al mes (tarifa 6 cent) y eso que llama cada 2x3 a la novia o los amigos y se conecta a internet pero no gasta los 300mb gratuitos y mi mujer o yo solemos gastar entre 4 o 5 euros mensuales aprox (cada uno), algun mes puede subir a 7 u 8. Ah, no tenemos que gastar un consumo minimo, es tarifa de 8 cent.(min.) a todos numeros.

Espero sirva de referencia, no es publicidad pues ni me va ni me viene esa empresa, solo comentaros para que podais comparar.

Un saludo.

enhorabuena heke por el tutorial, muy util

yo recomendaria pepephone, no hay consumo minimo, y es muy barato. lo mismo no me llevo nada, pero estoy contento con ellos.

hola qe modelo es el wavecom no se aprecia bien
yo opino lo mismo que Sergegsx pepephone es ok

Wavecom WMOD2

Ref: M1203A

Pero Cualquier Wavecom Fastrack o RS232 te vale, son los mismos comandos mas o menos.

Como este Q2303A
http://www.ebay.es/itm/GSM-Modem-Wavecom-Q2303A-Wireless-Module-COM-RS232-AT-Commands-/251284461002?pt=UK_Computing_Other_Computing_Networking&hash=item3a81b895ca

La unica cosa a tener en cuenta es que el protocolo de comunicaciones sea RS232 porque hay otros wavecom pero son por USB y te haria falta un USB host para controlarlo.

Como la forma de controlarlo es por medio de comandos AT, practicamente la mayoria de modems son compatibles, recordar este enlace del foro de arduino que hizo Igor en su momento y que explica muy bien el uso de estos modem con ejemplos claros:
http://www.arduino.cc/es_old/Tutoriales/SMS

Añado a la pregunta de un compañero por MP :

Estos comandos son estandar, llamados conjunto de comandos Hayes Conjunto de comandos Hayes - Wikipedia, la enciclopedia libre Aunque estos que estoy empleando son para controlar un modem GSM, los que se emplean para controlar un modem de linea telefonica son practicamente muy parecidos, para ello hay que remitirse al conjunto de comandos AT y practicamente seran los que emplea un modem analogico de los de toda la vida.
http://www.usr.com/support/3cxm756/3cxm756-spanish-ug/atcoms.htm

Si recordais hace unos post años (2009) gobernaba con esta misma "patata" de atmega8 un modem Vayris n56 analogico:

Si quereis emplear un modem RS232 con un arduino que no tenga ese interface, hay que conectar una placa conversora de TTL a RS232 como esta:

Y hacer un cable null modem para conectar ambos.

Respecto a la ultima pregunta de algun error de compilacion, es posible, yo emplee el ide 022 porque un ide mas avanzado me daba error con el programador USBTINY que tengo V.2 no extrañe que o bien los comandos de la libreria String puedan dar fallo en ides posteriores... o que el compilador no contemple un micro tan antiguo como es este atmega8.

Un saludo.

PD: He encontrado algunos comandos que empleaba, el IDE creo que era el 17, no es un programa son trozos de uno que emplee

// ????????????????????????????????????????????????
// ?  FUNCION inicia Inicializa el modem                                          ?
// ????????????????????????????????????????????????
void inicia(){
  mensaje1("Iniciando Modem " );
  Serial.flush();
//  Serial.println("AT&D&S0=2&E0"); 
  Serial.println("AT&D1&S0=0&S7=18&E0");
  delay(500);
  }



if (inString.contains("NO CARRIER"))
    {
     mensaje1("Sin Portadora   ");
    }

  if (inString.contains("ERROR"))
    {
     mensaje1("Error !!      ");
    }

  if (inString.contains("CONNECT"))
    {
     mensaje1("Conectado ");
    } 

  if (inString.contains("BUSY"))
    {
     mensaje1("Ocupado");
    } 

  if (inString.contains("NO DIALTONE"))
    {
     mensaje1("Sin tono llamada");
    } 

  if (inString.contains("NO ANSWER"))
    {
     mensaje1("Sin respuesta  ");
    } 
    
  if (inString.contains("OK"))
    {
     mensaje1("OK");

En esta funcion realizaba una llamada de alarma con el modem analogico:

// ????????????????????????????????????????????????
// ?  FUNCION alarma  genera una alarma y llama al telefono programado               ?
// ????????????????????????????????????????????????
void alarma(){
    if (ha_llamado == '1')
      {
      mensaje1("Alarma entregada");
      sin_averias = '0';
      }
      
    else if ((sin_averias == '2') && (RTC.get(DS1307_HR,true) > 7) && (RTC.get(DS1307_HR,true) < 22))
          {  
          mensaje1("Alarma llamando");      // Telefono 1
          Serial.println("ATDTW971696@;");
          delay(11000);
          Serial.println("ATH0");
      
          Serial.println("ATDTW961590@;");  // Telefono 2
          delay(11000);
          Serial.println("ATH0");
      
          Serial.println("ATDTW968395@;");  // Telefono 3
          delay(11000);
          Serial.println("ATH0");
          ha_llamado = '1';
          sin_averias = '0';
          }

    else if (sin_averias == '1')
          {  
          mensaje1("Alarma llamando");      // Telefono 1
          Serial.println("ATDTW971696@;");
          delay(11000);
          Serial.println("ATH0");
      
          Serial.println("ATDTW961590@;");  // Telefono 2
          delay(11000);
          Serial.println("ATH0");

          Serial.println("ATDTW968395@;");  // Telefono 3
          delay(11000);
          Serial.println("ATH0");
          ha_llamado = '1';
          sin_averias = '0';
          }
 }

hola gracias por esta respuesta sobre el ide tienes razon use la ultima version y es la que da error bueno me pondre con el tema este a ver si soy capaz de que funcione
repito gracias por compartir

yo intenten montar este pero no se por que solo me funciono 2 veces seguro que algo hacia mal

hola esto seria lo correcto para conectar el arduino al moden rs232 esta un poco borrosa la imagen

Esta borrosa la imagen pero esa plaquita parece un conversor USB a RS232, me parece distinguir un puerto miniUSB.

Si es asi, no te vale porque ese arduino tiene un "USB client" y la plaquita conversora parece ser tambien un "USB Client" te haria falta un USB Host o master.

Esa placa te vale seguramente para enchufarla al PC, al usb Host y que convierta a RS232.

Lo que tu necesitas es o un arduino con USB host (hay un modelo pero no recuerdo nombre) y sus drivers correspondientes o una placa conversora TTL a RS232 como ya comentaba en post anteriores.

hola el que esta en la foto es este
http://www.mabisat.com/modulos-electronicos/1128-conversor-rs232-a-ttl-usb.html

Hola, estoy tratando de mediante arduino recibir una trama gps de aproximadamente 70 caracteres, pero a partir del carácter 56 no me recibe mas y no se que pueda hacer.

Hola, manunieto. Si no nos pones el código que estás usando, va a ser difícil ayudarte.

Hola.
Tengo un problema que me trae frito.
Tengo un cable USB-RS232, ya que no tengo puerto serie en el PC
Me comunico con un módem wavecom si problemas. Tambien me conecto con la placa MEGA 2560 y la UNO R3. mediante un adaptador TTL-RS232 como este
http://www.ebay.es/itm/221326032896?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2648

Mi problema es que no puedo conectar el Arduino con el módem mediante dicho adaptador y un cable de módem nulo.
Algo estaré haciendo mal. Y no es el baudrate.

El código es un replicador de puerto de los ejemplos de Arduino

Lo mas facil es que no hayas comprobado los pines de tu conector al conector del wavecom.

Tienes el esquema en este hilo, en el primer post, siguelos y comprueba que tu TX del PC va al RX del wavecom, el RX al Tx respectivamente y masa...

Esto es velocidad de respuesta.

Al final estoy conectando el db15 y el db9 del conversor TTL directamente 2-2 3-6 5-9 y pedo realizar llamadas, pero no me responde a los comandos AT. (estoy frito por leer un SMS)
Vamos que es lo mismo que desconecte el 3-6 o no. Sin embargo si conecto el rs232 del pc si obtengo tx y rx en el arduino (pc-arduino). Hay algún problema en la recepción de datos del wavecom. he cambiado de placa arduino y lo mismo.
El wavecom si manda respuesta al pc (pc-wavecom).

Me pasa lo mismo con los shield GPRS con chip SIM900, puedo enviar pero no recibir. Y las placas arduino están bien pues se comunican con el PC por el conversor ttl y los puertos seriales tanto sw como hw.