Go Down

Topic: Cambio de nº telefono modem GSM (Read 882 times) previous topic - next topic

Katynga

Hola de nuevo.

Sigo con mi proyecto de envio de mensajes.
Ahora despues de probarlo y reprobarlo, funciona perfectamente, pero quiero reordenar el código y hacerlo mas sencillo de modificar.
Pretendo asígnar una variable al número de telefono y otra al mensaje, por si tengo que modificarlas, no entrar en el código.
En un futuro los modificaré via LCD y teclado.

Os dejo el código ya que la modificación no me funciona.
La compilación para en la línea "  SIM900 . println ("AT + CMGS = \"%s\"\r",NUMERO);  "

Quote
#include <SoftwareSerial.h>

SoftwareSerial SIM900 ( 0 , 1 ) ;


const int Alarm_ON = 9;
const int Alarm_OFF = 11;
const int LED = 13;
/*El PIN 6 esta en establecido al modem GSM
   Lo usa para apagar o encender el modem*/
   
char NUMERO [] = "+346--------";
char MENSAJE [] = "Mensaje desde Arduino";


void setup()
{
  pinMode( Alarm_ON, INPUT);
  pinMode( Alarm_OFF, INPUT);
  pinMode( LED , OUTPUT);
 
//Apagamos MODEM
  delay(10000);
  digitalWrite(6,HIGH); 
  delay(5000);
  digitalWrite(6,LOW);
  delay(5000);
  delay(10000);
  digitalWrite(6,HIGH); 
  delay(5000);
  digitalWrite(6,LOW);
  delay(5000);
}


void SIM900power()
{
   // Secuencia equivalente a darle al Botón "Power" del GSM
   // Un pulso mediante el pin6
   digitalWrite ( 6 , HIGH ) ;
   delay ( 3000 ) ;
   digitalWrite ( 6 , LOW ) ;
   delay ( 5000 ) ;

}
void SIM900_Caracteristicas()
//Definimos velocidad del modem GSM
{
   SIM900 . begin ( 19200 ) ;
   delay ( 20000 ) ; // Tiempo de arranque del modem.
}

void sendSMS ( )
{
   SIM900power ( );    // Encendemos el modulo GSM
   delay ( 100 );
   SIM900_Caracteristicas ( );
   delay ( 100 );
   SIM900 . print ("AT+CMGF=1\r");                         //AT command para enviar SMS
   delay ( 100 ) ;
   SIM900 . println ("AT + CMGS = \"%s\"\r",NUMERO);      // Nº Tfno a enviar el SMS
   delay ( 100 ) ;
   SIM900 . println ("%s", MENSAJE);                       // Mensaje a enviar
   delay ( 100 ) ;
   SIM900 . println ( ( char ) 26 );                       // Fin Comando AT con un ^Z, ASCII code 26
   delay ( 100 ) ;
   SIM900 . println ( );
   delay ( 5000 );                                      // Tiempo del módulo para enviar el SMS
 
   SIM900power ( ); // Apagamos el modulo GSM



Falta el módulo Loop, pero  de estas líneas no pasa.
Quote
SIM900 . println ("AT + CMGS = \"%s\"\r",NUMERO);      // Nº Tfno a enviar el SMS
   delay ( 100 ) ;
   SIM900 . println ("%s", MENSAJE); 


Trabajaré sobre el tema.
Se admiten sujerencias.

Gracias



Daklon

no tengo experiencia con ese módulo... ¿podrías poner que error te da exactamente?

¿porque pones el retorno de carro? ¿println no lo añadía ya?

Katynga

Quote
no tengo experiencia con ese módulo... ¿podrías poner que error te da exactamente?

¿porque pones el retorno de carro? ¿println no lo añadía ya?


Perdonar pero igual no me explique bien.
El código normal que hay para este módulo: http://www.dx.com/es/p/arduino-compatible-gsm-gprs-shield-wireless-extension-board-module-w-antenna-adapter-144865?tc=EUR&gclid=CI_e3t337r4CFTLMtAod3zEAZw

Es este:

Quote
void SIM900power ( )
// Secuencia equivalente a darle al Botón "Power" del GSM ---- Un pulso mediante el pin6

{
   digitalWrite ( 6 , HIGH ) ;
   delay ( 1000 ) ;
   digitalWrite ( 6 , LOW ) ;
   delay ( 5000 ) ;
}

void sendSMS ( )
{
   SIM900 . print ("AT+CMGF=1\r");                                    // AT command para enviar SMS
   delay ( 100 ) ;
   SIM900 . println ("AT + CMGS = \"+346111111\"");                // Numero de telefono con numeracon internacional
   delay ( 100 ) ;
   SIM900 . println (" Mensaje desde Arduino");          // mensaje a enviar
   delay ( 100 ) ;
   SIM900 . println ( ( char ) 26 );                        // Fin Comando AT con un ^Z, ASCII code 26
   delay ( 100 ) ;
   SIM900 . println ( );
   delay ( 5000 );                                      // Tiempo del módulo para enviar el SMS
   SIM900power ( );                                    // Lo mandamos de nuevo a SIM900Powe para apagar el modulo GSM
}


Lo que pretendo hacer es poner una variable al número de telefono y al mensaje, de forma que cada vez que quiera modificarlo no tenga que ingresar en el código.
Si soy capaz, luego por medio de un LCD y un teclado, podría modificar esos datos sin tener que traerme el arduino para conectarlo en el ordenador.

Al modificar el Codigo de los comandos AT, ya me da error.
No soy capaz de incluir esa variable.
Quote
SIM900 . println ("AT + CMGS = \Numero Telefono"); 
[/size][/size]

Quizas así lo se entienda mejor.

Un saludo

noter

Hola, Katynga.
El problema es que estás utilizando el método print como si fuera printf, y por defecto no es así (creo que se puede modificar la librería Print.h para que lo acepte).
Como método alternativo, puedes construir tu cadena en un buffer de memoria con sprintf:

Code: [Select]

char myBuffer[100]; // buffer de 100 bytes para almacenar la cadena construida. Puedes contar los caracteres necesarios y ajustar más el tamaño
setup(){
sprintf(myBuffer, "AT + CMGS = \"%s\"\r", NUMERO);
}
loop(){
SIM900 . println (myBuffer);      // Nº Tfno a enviar el SMS
}


El mensaje, al ser una cadena única lo puedes imprimir directamente:
   SIM900 . println (MENSAJE);                       // Mensaje a enviar

Saludos

Katynga

Muchisimas gracias, lo probaré.

Lo que no entiendo es si tengo que incluir alguna librería para que funcione la función "sprintf".
He leido el enlace que me adjuntas y no me ha quedado es como tengo que incluir el código que indican en el archivo de cabecera. ¿Donde está ese archivo de cabecera?

Quote
Inserte el siguiente código en el archivo de cabecera PRINT.H. El código debe ser insertado en la definición de clase de impresión. Sólo tienes que copiar y pegar este código en la parte inferior de la sección pública.

# Include <stdarg.h>
# Define PRINTF_BUF 80 / / define el tamaño del buffer tmp (modificar si lo desea)
void printf (const char * formato, ...)
{
char buf [PRINTF_BUF];
va_list ap;
va_start (ap, formato);
vsnprintf (buf, sizeof (buf), formato, ap);
for (char * p = & buf
  • ; * p, p + +) / / emular el modo de cocinado para los saltos de línea
    {
    if (* p == '\ n')
    write ('\ r');
    write (* p);
    }
    va_end (ap);
    }
    # Ifdef F / / comprobar si F (macro) está disponible
    void printf (const __ FlashStringHelper * formato, ...)
    {
    char buf [PRINTF_BUF];
    va_list ap;
    va_start (ap, formato);
    # Ifdef __ AVR__
    vsnprintf_P (buf, sizeof (buf), (const char *) formato, ap); / / PROGMEM para AVR
    # Else
    vsnprintf (buf, sizeof (buf), (const char *) formato, ap); / / para el resto del mundo
    # Endif
    for (char * p = & buf
  • ; * p, p + +) / / emular el modo de cocinado para los saltos de línea
    {
    if (* p == '\ n')
    write ('\ r');
    write (* p);
    }
    va_end (ap);
    }
    # Endif
[/size][/size]

noter

Hola. El sprintf lo puedes utilizar directamente, al menos en las últimas versiones del IDE, así que a priori sería lo más fácil de implementar.
Lo de modificar la librería print.h no lo he probado nunca, pero sé que se encuentra en varios sitios y dependiendo de tu modelo de arduino le afecta una u otra.
En resumen, yo apostaría por sprintf, que te puedo asegurar que funciona.
Saludos.

Katynga

Ok.
Reordenaré el código y a principios de la semana que viene lo pruebo.
Te mantendré informado.

Muchisimas gracias.

pacoooh

#7
Jun 14, 2014, 10:52 am Last Edit: Jun 14, 2014, 10:59 am by pacoooh Reason: 1
hola a todos

También puedes crearte tu propio sprinf, mira este código que te dará la idea perfecta

Code: [Select]


#include <avr/pgmspace.h>
#include <stdarg.h>

#define PC PROGMEM char
#define MAXLIN 128                     /* Output line buffer size             */
#define SUB '#'                        /* Substitution character              */
/*----------------------------------------------------------------------------*/
/* Define the format strings                                                  */
/*----------------------------------------------------------------------------*/
PC f000[] = "<p>The phone number of # is #</p>";
PC f001[] = "<p>#'s membership type is #</p>";
/*----------------------------------------------------------------------------*/
/* Array of pointers to above format strings                                  */
/*----------------------------------------------------------------------------*/
PROGMEM PGM_P fdata[] =                /* There must be an entry here for     */
{  f000,f001                           /*  each string above                  */
};                                     /*  end: array of pointers             */
/*----------------------------------------------------------------------------*/
/* Retrieve format string, make substitutions, and output formatted line      */
/*----------------------------------------------------------------------------*/
void putline(unsigned fmt,...)
{  static char buffer[MAXLIN];         /* Line buffer (SRAM)                  */
  char c;                             /* Character from format string        */
  char *p = buffer;                   /* Output pointer                      */
  PGM_P f = (PGM_P)pgm_read_word(&(fdata[fmt]));  /* Format string pointer   */
  char *q;                            /* Substitution data pointer           */
  va_list ap;                         /* Parameter list reference            */

  va_start(ap,fmt);                   /* Initialize ap                       */
  while (c = pgm_read_byte(f))        /* While format characters remain      */
  {  ++f;                             /* Advance format pointer              */
     if (c == SUB)                    /* Is this a substitution character    */
     {  q = va_arg(ap,char *);        /* If so, get string pointer param     */
        while (*q) *p++ = *q++;       /* Append param string to buffer       */
     }                                /*  end: if substitution               */
     else *p++ = c;                   /* Output ordinary char to buffer      */
  }                                   /*  end: while format chars remain     */
  va_end(ap);                         /* Done with parameter list            */
  *p = '\0';                          /* Terminate the output string         */
  Serial.println(buffer);             /* Output the buffered string          */
}                                      /*  end: putline()                     */
/*----------------------------------------------------------------------------*/
/* Test program (Arduino)                                                     */
/*----------------------------------------------------------------------------*/
void setup(void)
{  char *name = "John Smith";          /* 1st substitution item               */
  char *phone = "123-456-7890";       /* 2nd substitution item               */
  char *mtype = "Senior";             /* 3rd substitution item               */

  Serial.begin(9600);               /* Initialize serial connection        */
  putline(0,name,phone);              /* O/P formatted line with subs        */
  putline(1,name,mtype);              /* O/P second formatted line           */
}                                      /*  end: setup()                       */
void loop(void)
{  /* stub */
}


saludos

Katynga

Al final me pueden las ganas y he ido a por el módulo GSM.
Debo de estar escribiendo mal el código ya que no me funciona.
Os lo dejo entero:

Quote
#include <SoftwareSerial.h>
SoftwareSerial SIM900 (0, 1);

char NUMERO [] = "+34626212324";
char MENSAJE [] = "Hola Mundo.";
char myBuffer[100]; // buffer de 100 bytes para almacenar la cadena construida.
                    //Puedes contar los caracteres necesarios y ajustar más el tamaño


void setup()
{
  SIM900.begin(19200);
  SIM900power(); 
  delay(20000);  // give time to log on to network.
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(6, HIGH);
  delay(1000);
  digitalWrite(6, LOW);
  delay(5000);
}

void sendSMS()
{
  SIM900.print("AT+CMGF=1\r");                                                        // AT command to send SMS message
  delay(100);
   SIM900 . println (myBuffer);                            // Nº Tfno a enviar el SMS
   delay ( 100 ) ;
   SIM900 . println (MENSAJE);                       // Mensaje a enviar
  delay(100);
  SIM900.println((char)26);                       // End AT command with a ^Z, ASCII code 26
  delay(100);
  SIM900.println();
  delay(5000);                                     // give module time to send SMS
  SIM900power();                                   // turn off module
}

void loop()
{
  sendSMS();
  do {} while (1);
[/size][/size]

Pacooh graciñas por el codigo que aportas, pero no soy capaz de entenderlo.
Y menos encajarlo en medio del que tengo.
¿En teoria que hace ese código?

noter

En tu código no has llenado con nada myBuffer, así que probablemente sólo contendrá ceros. Te falta llenarlo con tu comando.
sprintf(myBuffer, "AT + CMGS = \"%s\"\r", NUMERO);

pacoooh

Hola!

Pues ese código crea un array de String grabada en la SRAM. y la función putline(unsigned fmt,....) lo que hace es recuperar el String del array del fdata con la variable fmt , que luego la manda por el serial sustituyendo "#" por el String que le pongas a la función putline
ejemplo: putline(0,"juan")

putline es una función parecida a sprintf, solo que mucho mas sencilla
te paso otro código rectificado que se me ha ocurrido para integrarlo en tu código, desconozco el funcionamiento de SIM900, y los comandos que necesita para establecer la conexión, míratelo y cambia si es necesario
Se trata de una función comandos que devuelve(no imprime en el serial) un String  al que le añades el otro String que luego tu mandas al SIM900
es una idea...

Code: [Select]


                             
                           
/*----------------------------------------------------------------------------*/
/* Define un String en SRAM de los comandos a enviar                                                */
/*----------------comandos SIm900-----------------------------------*/
PROGMEM char f000[] = "AT+CMGF=#\r";
PROGMEM char f001[] = "AT+CMGS=\"#\"\r";
PROGMEM char f002[] = "MENSAJE ARDUINO:#";

/*----------------------------------------------------------------------------*/
/* Creamos un array que contendra los comandos                               */
/*----------------------------------------------------------------------------*/
PROGMEM char *fdata[] =               
{  f000,f001,f002                   
};                                     
/*----------------------------------------------------------------------------*/




/* funcion que devuelve un String de la base de datos de comandos Sim900     */
/* El String se indica con la variable fmt en la funcion comandos    */
/*Los String contienen una "#" que es sustituida por por una cadena de caracteres*/
char *comandos(int fmt,...)
{  static char buffer[128];         
   char c;                         
   char *p = buffer;               
   PGM_P f = (PGM_P)pgm_read_word(&(fdata[fmt]));   
   char *q;                       
   va_list ap;                   

   va_start(ap,fmt);                   
   while (c = pgm_read_byte(f))       
   {  ++f;                             
      if (c == '#')                   
      {  q = va_arg(ap,char *);       
         while (*q) *p++ = *q++;       
      }                               
      else *p++ = c;                   
   }                                   
   va_end(ap);                       
   *p = '\0';                         
  return buffer;             
}                                     
/*----------------------------------------------------------------------------*/
/* Test program (Arduino)                                                     */
/*----------------------------------------------------------------------------*/
void setup( )


   Serial.begin(9600);             
   Serial.println(comandos(0,"1"));             
   Serial.println(comandos(1,"34626212324"));               
   Serial.println(comandos(2,"Hola Mundo."));             
}                                                         
void loop(void)

}


y ahora todo integrado en tu código

Code: [Select]

                             
                           
/*----------------------------------------------------------------------------*/
/* Define un String en SRAM de los comandos a enviar                                                */
/*----------------comandos SIm900-----------------------------------*/
PROGMEM char f000[] = "AT+CMGF=#\r";
PROGMEM char f001[] = "AT+CMGS=\"#\"\r";
PROGMEM char f002[] = "MENSAJE ARDUINO:#";

/*----------------------------------------------------------------------------*/
/* Creamos un array que contendra los comandos                               */
/*----------------------------------------------------------------------------*/
PROGMEM char *fdata[] =               
{  f000,f001,f002                   
};                                     
/*----------------------------------------------------------------------------*/




/* funcion que devuelve un String de la base de datos de comandos Sim900     */
/* El String se indica con la variable fmt en la funcion comandos    */
/*Los String contienen una "#" que es sustituida por por una cadena de caracteres*/
char *comandos(int fmt,...)
{  static char buffer[128];         
   char c;                         
   char *p = buffer;               
   PGM_P f = (PGM_P)pgm_read_word(&(fdata[fmt]));   
   char *q;                       
   va_list ap;                   

   va_start(ap,fmt);                   
   while (c = pgm_read_byte(f))       
   {  ++f;                             
      if (c == '#')                   
      {  q = va_arg(ap,char *);       
         while (*q) *p++ = *q++;       
      }                               
      else *p++ = c;                   
   }                                   
   va_end(ap);                       
   *p = '\0';                         
  return buffer;             
}                                     
/*----------------------------------------------------------------------------*/
/* Test program (Arduino)                                                     */
/*----------------------------------------------------------------------------*/



#include <SoftwareSerial.h>
SoftwareSerial SIM900 (0, 1);

char NUMERO [] = "+34626212324";
char MENSAJE [] = "Hola Mundo.";
char myBuffer[100]; // buffer de 100 bytes para almacenar la cadena construida.
                    //Puedes contar los caracteres necesarios y ajustar más el tamaño

void setup()
{
  SIM900.begin(19200);
  SIM900power(); 
  delay(20000);  // give time to log on to network.
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(6, HIGH);
  delay(1000);
  digitalWrite(6, LOW);
  delay(5000);
}

void sendSMS()
{
  SIM900.print(comandos(0,"1");                                                        // AT command to send SMS message
  delay(100);
   SIM900 . println (comandos(1,NUMERO));                            // Nº Tfno a enviar el SMS
   delay ( 100 ) ;
   SIM900 . println (comandos(2,MENSAJE));                       // Mensaje a enviar
  delay(100);
  SIM900.println((char)26);                       // End AT command with a ^Z, ASCII code 26
  delay(100);
  SIM900.println();
  delay(5000);                                     // give module time to send SMS
  SIM900power();                                   // turn off module
}

void loop()
{
  sendSMS();
  do {} while (1);


Saludos

Katynga

#11
Jun 24, 2014, 12:18 pm Last Edit: Jun 24, 2014, 12:57 pm by Katynga Reason: 1
Teneis que perdonar pero no he podido conectarme antes, y menos verificar todas las ideas que me habeis puesto.

"noter" he incluido el comando: sprintf(myBuffer, "AT + CMGS = \"%s\"\r", NUMERO);
Muchas gracias por la anotación. Son demasiadas cosas y se me había pasado incluir el sprintf.
Otra cosa que tenia mal son los puertos Rx y Tx. Al estar utilizando un MEGA tengo que cambiarlos a (2,3)

Os dejo el código modificado, probrado y funcionando, para un Arduino Mega

Quote
#include <SoftwareSerial.h>
SoftwareSerial SIM900 (2, 3);

char NUMERO [] = "+34626212324";
char MENSAJE [] = "Hola Mundo.";
char myBuffer[100]; // buffer de 100 bytes para almacenar la cadena construida.
                   //Puedes contar los caracteres necesarios y ajustar más el tamaño


void setup()
{
 SIM900.begin(19200);
 SIM900power();
 delay(20000);  // give time to log on to network.
 sprintf(myBuffer, "AT + CMGS = \"%s\"\r", NUMERO);
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
 digitalWrite(6, HIGH);
 delay(1000);
 digitalWrite(6, LOW);
 delay(5000);
}

void sendSMS()
{
 SIM900.print("AT+CMGF=1\r");                                                        // AT command to send SMS message
 delay(100);
  SIM900 . println (myBuffer);                            // Nº Tfno a enviar el SMS
  delay ( 100 ) ;
  SIM900 . println (MENSAJE);                       // Mensaje a enviar
 delay(100);
 SIM900.println((char)26);                       // End AT command with a ^Z, ASCII code 26
 delay(100);
 SIM900.println();
 delay(5000);                                     // give module time to send SMS
 SIM900power();                                   // turn off module
}

void loop()
{
 sendSMS();
 do {} while (1);
}


Pacooh no soy capaz de entender para que vale una array de String.

Te agradecería que me explicaras, para tontos como funcionay para que sirve,
Por mas que lo leo, no entiendo por donde van los tiros. Ni siquiera el porque pones esto al principio del código.

Quote
PROGMEM char f000[] = "AT+CMGF=#\r";
PROGMEM char f001[] = "AT+CMGS=\"#\"\r";
PROGMEM char f002[] = "MENSAJE ARDUINO:#";


Muchas gracias a todos.
Un saludo.

pacoooh

Hola katinga
Busca PROGMEM en la referencia,
http://arduino.cc/es/Reference/PROGMEM 
PROGMEM registra en la memoria de programa un tipo de variable, lo bueno es que no ocupa memoria sram(por cierto me equivoqué anteriormente ) y luego con la macro pertinente la recuperas de la memoria de programa
http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html
Declarar variables de esta manera no ocupa memoria sram(que hay muy poca)

puedes crear cadena de caracteres de la siguientes maneras por ejemplo:
char mensaje1[]="0123456789"; ocupa 12 bytes de memoria sram
String mensaje2="0123456789";ocupa 38 bytes de memoria sram, como puede ser eso?
PROGMEM char mensaje3[]="0123456789";queda almacenada en la memoria de programa ocupa 0 bytes en sram

creo haber leído que utilizas un mega con  un lcd, y el gsm, necesitarás crear cadena de caracteres, a ver como las defines......

Mucho ánimo.

Katynga

La madre del cordero!!!!!!!! :smiley-eek:
No crees que esto es un poco complejo para mi?
El día que llegue a este nivel de programación estaré contenta con migo misma.

¿Cuanto cobras por ayudarme a definirlo?  :smiley-yell: :smiley-yell: :smiley-yell:

Go Up