Necesito ayuda urgente para mi proyecto con la gsm shield!

Hola a todos!!
Ante todo, quiero daros las gracias por intentar ayudarme.
Llevo mucho tiempo utilizando arduinos, pero ahora me an encomendado un trabajo, y me e estancado.
Os resumo:
tengo la GSM shield, y necesito crear una base de datos en el arduino, y que con una llamada se active el rele, siempre y cuando el numero que ha llamado esté registrado en esa base de datos. la base de datos tendrá alrededor de 200 teléfonos.
Primera cuestión:
como puedo hacer para que mandando le un sms desde un numero concreto incluyendo en el sms el numero de teléfono a dar de alta, se guarde y añada en esa base de datos?
Segunda cuestión:
como puedo comparar el numero entrante con todos los de la base de datos? y sin que se tire media hora en compararlos...

en el resto no hay problema, pero en esto me e estancado.

Gracias Compañeros

Pues creo que lo esencial es planificar bien esa base de datos.
Para evitar tener que leerla entera para cotejar cada teléfono debería estar ordenada. Por ello es muy importante que cada vez que se agregue un número de teléfono hacerlo insertándolo en la posición correspondiente. De esa forma, para las búsquedas iremos "dividiendo" entre dos la base de datos:
Primero comparamos con el número de la mitad de la tabla, si es menor, comparamos con el número que está en la posición media de la primera mitad, y así sucesivamente. Con ocho comparaciones, por ejemplo, deberíamos poder encontrar un número entre 256.
Otro punto que puede agregar rendimiento es el modo de almacenamiento de los teléfonos. Dependiendo de cuántas cifras quieras almacenar, puedes optar por almacenar en forma de texto (1 byte por número), en bcd (1 byte por cada dos números) o, si el número no requiere más de nueve dígitos, en formato long directamente (4 bytes para todo el número). Yo utilizaría este último, por ser el más compacto. No por problemas de almacenamiento, pues en ningún caso un archivo con 1000 registros telefónicos va a ocupar más que unos pocos kb, sino porque cada comparación de dos teléfonos requerirá cotejar menos bytes. Por cierto, si el resto del programa no consume mucha ram y si la tabla no es muy grande no descartaría cargar toda la base de datos en memoria (256 números long vendrían a ocupar 1kb de memoria), con lo que la búsqueda sería prácticamente instantánea.

Gracias por contestae tan rapido colega! Si, no seran mas de 9 numeros, asin que lo podemos hacer como tu me dices.
En el asunto de “base de datos” voy muy perdido, porque yo pensava que era lo que se ponia encima del programa como "int variable1 = 0;
Y e visto por internet que utilizan otros sistemas desconocidos por mi.
Te rogaria que me lo intentaras explicar de la forma mas sencilla posible? Y si pudieras ponerme algun ejemplo, te lo agradrceria en vida.
Ayer consegui que comparara un numero de telefono que puse arriva del todo en un formato char primer numero; con el numero entrante, y funcionó!

Pero si tengo que hacer lo mismo para cada numero que añada, puede ser mortal.
Yo habia pensado en ( no se si seria posible ) crear algun tipo de variable, o algo, en el cual tubiera en su interior todos los telefonos separados por comas (por ejemplo):

Int telefonos: 611111111, 622222222, 633333333;

Y poder hacer algun tipo de bucle para que los fuera comparando todos sin crear un programa mega grande.
Quizas e dicho una chorrada, jejeje. Que opinas??

Dame un punto de partida (el código que vayas construyendo) y te puedo ir ayudando a avanzar. Ten en cuenta que de la librería gsm no tengo ni idea de qué forma entrega los números de teléfono, ni de otras cosas.
Como te dije, si tus números no ocupan más de nueve dígitos, los puedes guardar directamente como long, con lo que la comparación será muy sencilla.
Por ejemplo, este código buscaría el número compara entre todos los del array numero:

long numero[5]={555666555, 555989000, 666999888, 123456789, 987654321};
long compara=987654321; 
for (int a=0;a<5;a++)
     if (compara==numero[a]) {
             Serial.print("Se ha encontrado el numero ");
             Serial.print(compara);
             Serial.print(" en la posicion ");
             Serial.print(a+1);
    }

Buenas! algo e conseguido.
funciona a la perfeccion. lo unico que falta aqui, que no e conseguido hacerlo, es que mandandole un sms desde un numero especifico, se sobreescriba una posicion de numero de telefono en el array.

el codigo que tengo es el siguiente:

//------------------------------------------------------------------------------
char* telefonos[]={ 
"679734177", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", 
"600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "600000000", "619611378"};







//-------------------------------------------------------------------------------

int pulsador = 13;
#include <GSM.h>
#define PINNUMBER ""

GSM_SMS sms;
GSM gsmAccess;
GSMVoiceCall vcs;
char numtel[20];       // el numero entrante de llamada      
char senderNumber[20]; // el numero entrante de SMS

void setup()
{
  pinMode(pulsador, OUTPUT);
  Serial.begin(9600);
  Serial.println("Arrancando el programa de recepcion de llamadas");
  boolean notConnected = true;
  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("No Conectado");
      delay(1000);}}
  vcs.hangCall();
  Serial.println("Esperando la llamada");
}

void loop()
{
//----------------------------------------------------------Cuerpo Del Programa---------------------------------------------------------------
  char c;                                    // Donde guardaremos el contenido del mensaje
 
  digitalWrite(pulsador, HIGH);              // Encendemos el LED Indicando que el sistema ya esta Operativo
  switch (vcs.getvoiceCallStatus())          // Mirar el estado de la llamada
  {
    case IDLE_CALL:                          // En caso de que no pase nada
    break;                                   // Volvemos al Inicio
      
    case RECEIVINGCALL:                      // En caso de entrar una llamada
    Serial.println("Recibiendo llamada");    // Anunciamos una LLamada entrante
    vcs.retrieveCallingNumber(numtel, 20);   // Recuperar el número de llamadas
    Serial.print("Numero Entrante:");        // Mostramos el numero en la Pantalla
    Serial.println(numtel);
    delay(500);
    vcs.hangCall();                          // colgamos  
    comparador();                            // Ejecutamos Modulo Comparador
    break;                                   // Finalizamos y volvemos al Principio
}
  delay(1000);
  
  
  
  
  
//----------------------------------------------------------Fin del cuerpo del Programa---------------------------------------------------

}


//---------------------------------------------------------------Modulo Abrepuerta--------------------------------------------------------

void Puerta() {
  
    digitalWrite(pulsador, HIGH);
    delay(1000);
    digitalWrite(pulsador, LOW);
    delay(1000);
    digitalWrite(pulsador, HIGH);
    delay(1000);
    digitalWrite(pulsador, LOW);
}

//----------------------------------------------------------------Modulo Comparador-----------------------------------------

void comparador() {
  
  for (int i = 0; i < 200; i++){
   Serial.println(telefonos[i]);
   //delay(500);
   
   if (strcmp(telefonos[i], numtel) == 0) {
     
      Serial.println("Aceptado!"); 
      delay(1500);
      Puerta();}}}

recivir_llamada_con_arduino2.ino (5.37 KB)

A ver si te sirve de ayuda.
El siguiente código no está probado, pero el setup debería rescatar de la EEPROM de Arduino los números almacenados, la función agrega debería añadir un teléfono y la función enguia debería retornar la posición en el array de un teléfono o -1 si no existe. He optado por almacenar los teléfonos como números long como te dije.

#include <EEPROM.h>
//------------------------------------------------------------------------------
byte longuia;
long telefonos[200];
//-------------------------------------------------------------------------------

void setup() {
  byte *pnumtel=(byte *)telefonos;
  Serial.begin(9600);
  if (longuia>200) longuia=0;
  Serial.println("Arrancando el programa de recepcion de llamadas");
  for (int i=0; i<sizeof(telefonos);i++){
        pnumtel[i]=EEPROM.read(i);
  }
  for (longuia = 0; longuia < 200; longuia++){
        if (telefonos[longuia] < 0) 
              break; 
        else
              Serial.println(telefonos[longuia]);
  }
}

void loop() {
  agrega(strtol("987654321", 0, 10));
  for(;;);
}

bool agrega(long newtel){
      if (longuia>=200){
            Serial.println("No se pudo agregar tel. Guia llena");
            return(false);
      } else {
            telefonos[longuia] = newtel;
            int direccionEEPROM=longuia*sizeof(long);
            byte *memdir = (byte *) &telefonos[longuia];
            for ( int i=0; i<sizeof(long); i++)
                  EEPROM.write(direccionEEPROM++, memdir[i]);
            longuia++;
      }
}

int enguia(long tel){
      for (int i=0; i< longuia; i++)
            if (tel==telefonos[longuia])
                  return(i);
      return(-1);
}

Mersi! Oy lo pruebo por la noche!!

Lo que pasa, es que ahora como hago ña comparacion de todos esos numeros con el entrante como tenia antes?

Hola. Es verdad que no te lo he puesto. La llamada sería similar a la de agrega. Por ejemplo enguia(strtol(“987654321”, 0, 10)) debería devolver la posición en la que se encuentra el número o -1 si no se encontró.

no entiendo el concepto amigo…

mira, este es el programa como lo tengo actualmente incluyendo la parte que tu me as puesto, mas la lectura de los sms.

//------------------------------------------------------------------------------
byte longuia;
long telefonos[200];
long newtel;


//-------------------------------------------------------------------------------

int pulsador = 13;
#include <GSM.h>
#include <EEPROM.h>
#define PINNUMBER ""

GSM_SMS sms;
GSM gsmAccess;
GSMVoiceCall vcs;
char numtel[20];       // el numero entrante de llamada      
char senderNumber[20]; // el numero entrante de SMS

void setup()
{
  pinMode(pulsador, OUTPUT);
 
  Serial.begin(9600);
  Serial.println("Arrancando el programa de recepcion de llamadas");
  boolean notConnected = true;
  //----------------------------------------------------------


  byte *pnumtel=(byte *)telefonos;
  if (longuia>200) longuia=0;
  
    for (int i=0; i<sizeof(telefonos);i++){
        pnumtel[i]=EEPROM.read(i);
  }
  for (longuia = 0; longuia < 200; longuia++){
        if (telefonos[longuia] < 0) 
              break; 
        else
              Serial.println(telefonos[longuia]);
  }
  
  //---------------------------------------------------------------
  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("No Conectado");
      delay(1000);}}
  vcs.hangCall();
  Serial.println("Esperando la llamada");
}

void loop()
{
//----------------------------------------------------------Cuerpo Del Programa tema llamada---------------------------------------------------------------
  char c;                                    // Donde guardaremos el contenido del mensaje
 
  digitalWrite(pulsador, HIGH);              // Encendemos el LED Indicando que el sistema ya esta Operativo
  switch (vcs.getvoiceCallStatus())          // Mirar el estado de la llamada
  {
    case IDLE_CALL:                          // En caso de que no pase nada
    break;                                   // Volvemos al Inicio
      
    case RECEIVINGCALL:                      // En caso de entrar una llamada
    Serial.println("Recibiendo llamada");    // Anunciamos una LLamada entrante
    vcs.retrieveCallingNumber(numtel, 20);   // Recuperar el número de llamadas
    Serial.print("Numero Entrante:");        // Mostramos el numero en la Pantalla
    Serial.println(numtel);
    delay(500);
    vcs.hangCall();                          // colgamos  
    comparador();                            // Ejecutamos Modulo Comparador
    break;                                   // Finalizamos y volvemos al Principio
}
  delay(1000);
  
//-----------------------------------------------------------Recepccion de mensaje------------------------------------------------------------------------------

if (sms.available())
  {
    Serial.println("Mensaje recibido de:");
    
    
    sms.remoteNumber(senderNumber, 20);
    Serial.println(senderNumber);

    
    if(sms.peek()=='#')
    {
      Serial.println("SMS Descartado");
      sms.flush();
    }
    
     if(senderNumber =="938765432")  // numero autorizado (ejemplo) para grabar numeros de telefono en la lista de la memoria
    {
      Serial.println("Acceso Autorizado. NUMERO A AÑADIR: ");
      
      while(c=sms.read())
      Serial.print(c);
      
      newtel = c;                    // esta es la idea, que el numero que contenga el sms, sea el que se guarde.
      
      Serial.println("\nFin del mensaje");}
      sms.flush();
      Serial.println("MENSAJE BORRADO");// borramos el mensaje
  }
  
} 
  
//----------------------------------------------------------Fin del cuerpo del Programa---------------------------------------------------




//---------------------------------------------------------------Modulo Abrepuerta--------------------------------------------------------

void Puerta() {
  
    digitalWrite(pulsador, HIGH);
    delay(1000);
    digitalWrite(pulsador, LOW);
    delay(1000);
    digitalWrite(pulsador, HIGH);
    delay(1000);
    digitalWrite(pulsador, LOW);
}

//----------------------------------------------------------------Modulo Comparador-----------------------------------------

void comparador() {
  

 
  
  // aqui va la parte del codigo que no logro desarrollar. 
  // representa que en este punto tengo que comparar TODOS los numeros de la lista telefonica, creo que ahora la as llamdo telefonos,
  // con el numero entrante del modulo, que se llama numtel.
  // E intentado esto pero me da error:
  
  
   for (int i = 0; i < 200; i++){
   Serial.println(telefonos[i]);
   //delay(500);

 /*  if (strtol(telefonos[i], numtel) == 0) {
     
      Serial.println("Aceptado!"); 
      delay(1500);
      Puerta();}
*/    
  }}
  
  
 
 
 




//------------------------------------------------ayuda------------------------------------------------------

bool agrega(long newtel){
      if (longuia>=200){
            Serial.println("No se pudo agregar tel. Guia llena");
            return(false);
      } else {
            telefonos[longuia] = newtel;
            int direccionEEPROM=longuia*sizeof(long);
            byte *memdir = (byte *) &telefonos[longuia];
            for ( int i=0; i<sizeof(long); i++)
                  EEPROM.write(direccionEEPROM++, memdir[i]);
            longuia++;
      }
}

int enguia(long tel){
      for (int i=0; i< longuia; i++)
            if (tel==telefonos[longuia])
                  return(i);
      return(-1);
}

//-------------------------------------------------------------------------------------------------------------

donde tengo el problema, “creo” que es solo en void comparador.

me interesaria poder, aparte, hacer alguna funcion para que me imprima todos los numeros añadidos. es muy complicado? gracias colega!!

Hola.
La función enguia que te proporciono debería valerte para tu comparador. Partiendo de tu código:

.....
    Serial.print("Numero Entrante:");        // Mostramos el numero en la Pantalla
    Serial.println(numtel);
    int pos=enguia(strtol(numtel, 0, 10));
    if (pos>=0) 
        // el teléfono estará en la posición pos del array
    else
        // el teléfono no se encuentra en la guía.
......

Y el código para agregar un teléfono en la guía sería:

    if(agrega(strtol(newtel, 0, 10)))
            //el teléfono se agregó a la guía
    else
            //el teléfono no se pudo agregar a la guía

A ambas funciones les deberías entregar un long con el número de teléfono a buscar/agregar. La función strtol convierte una cadena en un long.

tengo el siguiente codigo, pero tiene fallos y me pierdo amigo.

//------------------------------------------------------------------------------
byte longuia;
long telefonos[200];
long newtel;
long telin;





//-------------------------------------------------------------------------------

int pulsador = 13;
#include <GSM.h>
#define PINNUMBER ""
#include <EEPROM.h>

GSM_SMS sms;
GSM gsmAccess;
GSMVoiceCall vcs;
char numtel[20];       // el numero entrante de llamada      
char senderNumber[14]; // el numero entrante de SMS
char admin[] ={"+34679734177"}; // numero del Administrador

void setup()
{
  pinMode(pulsador, OUTPUT);
  Serial.begin(9600);
  Serial.println("Arrancando el programa de recepcion de llamadas");
  boolean notConnected = true;
  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("No Conectado");
      delay(1000);}}
  //vcs.hangCall();
  Serial.println("Esperando la llamada");
  
 //----------------------------------------------------------

    byte *pnumtel=(byte *)telefonos;
  if (longuia>200) longuia=0;
  
    for (int i=0; i<sizeof(telefonos);i++){
        pnumtel[i]=EEPROM.read(i);
  }
  for (longuia = 0; longuia < 200; longuia++){
        if (telefonos[longuia] < 0) 
              break; 
        else
              Serial.println(telefonos[longuia]);
  }
 
 //------------------------------------------------------------- 
  
  
  
}

void loop()
{
//----------------------------------------------------------Cuerpo Del Programa---------------------------------------------------------------
  
  
 
 
  digitalWrite(pulsador, HIGH);              // Encendemos el LED Indicando que el sistema ya esta Operativo
  switch (vcs.getvoiceCallStatus())          // Mirar el estado de la llamada
  {
    case IDLE_CALL:                          // En caso de que no pase nada
    break;                                   // Volvemos al Inicio
      
    case RECEIVINGCALL:                      // En caso de entrar una llamada
    Serial.println("Recibiendo llamada");    // Anunciamos una LLamada entrante
    vcs.retrieveCallingNumber(numtel, 20);   // Recuperar el número de llamadas
    Serial.print("Numero Entrante:");        // Mostramos el numero en la Pantalla
    Serial.println(numtel);
    delay(500);
    vcs.hangCall();                          // colgamos  
    comparador();                            // Ejecutamos Modulo Comparador
    break;                                   // Finalizamos y volvemos al Principio
}
 
   
//----------------------------------------------------------Fin del cuerpo del Programa---------------------------------------------------

//---------------------------------------------ejecutamos la lectura de SMS----------------
 
  smsL();
  

}


//---------------------------------------------------------------Modulo Abrepuerta--------------------------------------------------------

void Puerta() {
  
    digitalWrite(pulsador, HIGH);
    delay(1000);
    digitalWrite(pulsador, LOW);
    delay(1000);
    digitalWrite(pulsador, HIGH);
    delay(1000);
    digitalWrite(pulsador, LOW);
}

//----------------------------------------------------------------Modulo Comparador-----------------------------------------

void comparador() {

  
  
  int pos=enguia(strtol(numtel, 0, 10));
    if (pos>=0) {
        Serial.println("Aceptado!"); 
      delay(1500);
      Puerta();} // el teléfono estará en la posición pos del array
    else
       {
        Serial.println("Denegado!");} // el teléfono no se encuentra en la guía.
  

  
  
  
  
  
  
  
  
  
  /*  
  for (int i = 0; i < 200; i++){
   Serial.println(telefonos[i]);
   //delay(500);
   
   if (strcmp(telefonos[i], numtel) == 0) {
     
      Serial.println("Aceptado!"); 
      delay(1500);
      Puerta();}}
    */
  }
  
  //------------------------------------------------ayuda------------------------------------------------------

bool agrega(long newtel){
      if (longuia>=200){
            Serial.println("No se pudo agregar tel. Guia llena");
            return(false);
      } else {
            telefonos[longuia] = newtel;
            int direccionEEPROM=longuia*sizeof(long);
            byte *memdir = (byte *) &telefonos[longuia];
            for ( int i=0; i<sizeof(long); i++)
                  EEPROM.write(direccionEEPROM++, memdir[i]);
            longuia++;
      }
}

int enguia(long tel){
      for (int i=0; i< longuia; i++)
            if (tel==telefonos[longuia])
                  return(i);
      return(-1);
}

//-------------------------------------------------------------------------------------------------------------


void smsL() {
  
   char c;                                    // Donde guardaremos el contenido del mensaje
  if (sms.available())
  {
    
  sms.remoteNumber(senderNumber, 14);
    Serial.println(senderNumber);

      //Serial.println("Acceso Autorizado. NUMERO A AÑADIR: ");
      while(c=sms.read())
      Serial.print(c);
      newtel= c;      // Aqui le digo que el newtel sera igual que el contenido del mensaje leido
      delay (500);
      

      
      if(agrega(strtol(newtel, 0, 10))) {
            Serial.println("telefono añadido ");
            sms.flush();}
    else {
       Serial.println("telefono no añadido ");
            //el teléfono no se pudo agregar a la guía
      sms.flush();}
    

}}

en el comparador, tal i como me lo as puesto, solo me va a comparar el telefono que esta en la memoria 0, no es asi?
como le digo que me mire todas las posiciones para ver si el numero coincide con alguna de ellas?
y la segunda pregunta, no tengo ni idea en como convertir el char c que contiene el mensaje de texto, en long como tu dices, porque el programa peta por eso. he hestado buscando info sobre strol en arduino, pero no veo nada…

Hola.
El comparador repasa todos los números de la guía desde el guardado en pos 0 hasta la posición que detecta como longitud de la guía (longuia).
Como te he dicho, no he podido probarlo pero creo que va más o menos bien apuntado. Me interesaría saber si es correcta la detección de ese número (número de teléfonos almacenados en eeprom), ya que la hago dando por sentado que tras subir el sketch la eeprom queda llena con FF. Al iniciar el programa, en el setup saca por serial los números guardados. Cuando agregues uno o varios, resetea a ver si aparecen correctamente.
En cuanto al char c, ten en cuenta que un char sólo almacena un carácter, y necesitas tener el número en una cadena.
Es decir, deberías declarar char c[10] y almacenar el número de teléfono de la siguiente manera cuando empieces a leer los caracteres del sms correspondientes al número:

for (int i=0; i<9; i++)    c[i]=sms.read();
c[9] =0; // escribimos un terminador de cadena al final del número

Y ahora strtol(c, 0, 10) debería funcionar correctamente, siempre que la cadena c contenga un número válido. Los parámetros que se pasan son la cadena, un puntero opcional para guardar el long que no usamos, y la base en que está el número (en este caso decimal).

Por cierto, la línea en setup
if (longuia>200) longuia=0;
no hace nada. Puedes quitarla de momento. Sí sería interesante que al final del setup mostraras por serial la variable longuia a ver si contiene el número de teléfonos almacenados correcto. De momento debería ser cero, ya que deduzco que aún no has podido almacenar ninguno, pero por si acaso.
En un próximo paso deberás controlar que antes de agregar un teléfono lo busque por si ya existe, la posibilidad de modificar o borrar un teléfono…
¡Ah! Y recordarte que la EEPROM tiene un número de unos 100000 ciclos de escritura. Habría que escribir muuuuchas veces en la guía para que la eeprom se deteriore, pero un programa mal pensado podría dedicarse a escribir a lo loco y alcanzar el límite de escrituras en corto plazo.

hola compañero!
e conseguido añadir un telefono desde un sms!
y cuando arranca luego el programa me sale en el serial:

//-----------------------------------------------------
Arrancando el programa de recepcion de llamadas
Esperando la llamada
987654321
987654321
987654321
987654321
679734177
679734189
//--------------------------------------------

los 2 ultimos son los que yo he añadido XD

lo que no hace es la comparacion correcta, porque si le llamo sale:

//--------------------------------------------

Arrancando el programa de recepcion de llamadas
Esperando la llamada
987654321
987654321
987654321
987654321
679734177
679734189
Recibiendo llamada
Numero Entrante:679734177
Denegado!

//---------------------------------------------

yo opino que no los compara todos, o solo el primero… la verdad es que no entiendo todavia que hace la operacion :

//---------------------------------------------

int pos=enguia(strtol(numtel, 0, 10));
if (pos>=0) {
Serial.println(“Aceptado!”);
delay(1500);
Puerta();} // el teléfono estará en la posición pos del array

//-----------------------------------------------

te sabria mal explicarmelo como a los tontos paso a paso palabra por palabra que funcion hace el que en cada sitio puesto?
es que pienso que la mejor manera de hacer un programa y aprender, es saber como utilizar cada cosa, pero hay muchas cosas aqui puestas que no las e tocado nunca…

esque yo antes tenia esto:

//------------------------------------------------

for (int i = 0; i < 200; i++){
Serial.println(telefonos*);*

  • //delay(500);*

_ if (strcmp(telefonos*, numtel) == 0) {*_

* Serial.println(“Aceptado!”);*
* delay(1500);*
* Puerta();}}*
//--------------------------------------------------
y buscaba los telefonos en un array, y me funcionaba, pero veo que en el tuyo, no hay nada que haga cambiar de telefono ni nada para comprobarlos todos…
por cierto, fijate como esta hecho lo del sms. no se si asi es la manera correcta, pero lo a añadido :wink:
me gustaria crear las siguientes funciones, ya que tengo la intencion de colocar una pantalla y un encoder mas adelante,
y quisiera poner una funcion que dependiendo de una variable ( int pos_encoder=0;) me mostrara la posicion de cada numero en la memoria, y luego otra funcion para poder borrarla, y hacer que no quede ninguna memoria entre medio vacia para no perder ninguna posicion.
desde luego compadre, ten por seguro que en cuanto acabe esto, no me ire por donde e venido. tendras un presente por averme ayudado tanto en este trabajo que se me esta haciendo un mundo. Mil gracias!!

creo que ya veo el porque no compara bien:

//------------------------------------------------
int enguia( long tel){
for (int i=0; i< longuia; i++)
if (tel==telefonos[longuia]){
return(i);}
else{
return(-1);}
}

//----------------------------------------------------

aqui no hay nada que asocie el numero de llamada entrante (numtel) con el que tiene que comparar

Hola.
Como puedes ver, la función enguia recibe un teléfono en formato long y devuelve la posición en la que se ha encontrado o bien -1 si no se encontró. Como ves sí tiene un for, pero en vez de recorrer hasta 200 sólo recorre hasta la posición del último teléfono grabado (longuia).
Es decir, cuando llamamos a la función
pos=enguia(strtol(numtel, 0, 10));

Llama a la función enviandole para comparar el long obtenido de la variable numtel, que se supone que es una cadena.
Saca por serial antes de esa llamada la cadena numtel y también strtol(numtel,0,10), a ver si el número que se envía a la función enguia es correcto o estamos haciendo mal la conversión.
Respecto a lo del sms para agregar, no me muestras el código, así que no puedo verlo; pero supongo que si funciona estará bien :slight_smile:

mira, este es el programa tal y como lo tengo ahora:

//------------------------------------------------------------------------------
byte longuia;
long telefonos[200];
long newtel;
long telin;
long tel;




//-------------------------------------------------------------------------------

int pulsador = 13;
#include <GSM.h>
#define PINNUMBER ""
#include <EEPROM.h>

GSM_SMS sms;
GSM gsmAccess;
GSMVoiceCall vcs;
char numtel[20];       // el numero entrante de llamada      
char senderNumber[14]; // el numero entrante de SMS
char admin[] ={"+34679734177"}; // numero del Administrador

void setup()
{
  pinMode(pulsador, OUTPUT);
  Serial.begin(9600);
  Serial.println("Arrancando el programa de recepcion de llamadas");
  boolean notConnected = true;
  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("No Conectado");
      delay(1000);}}
  //vcs.hangCall();
  Serial.println("Esperando la llamada");
  
 //----------------------------------------------------------

    byte *pnumtel=(byte *)telefonos;
  if (longuia>200) longuia=0;
  
    for (int i=0; i<sizeof(telefonos);i++){
        pnumtel[i]=EEPROM.read(i);
  }
  for (longuia = 0; longuia < 200; longuia++){
        if (telefonos[longuia] < 0) 
              break; 
        else
              Serial.println(telefonos[longuia]);
  }
 
 //------------------------------------------------------------- 
  
  
  
}

void loop()
{
//----------------------------------------------------------Cuerpo Del Programa---------------------------------------------------------------
  digitalWrite(pulsador, HIGH);
  

  telefono();
  smsL();
  

}


//---------------------------------------------------------------Modulo Abrepuerta--------------------------------------------------------

void Puerta() {
  
    digitalWrite(pulsador, HIGH);
    delay(1000);
    digitalWrite(pulsador, LOW);
    delay(1000);
    digitalWrite(pulsador, HIGH);
    delay(1000);
    digitalWrite(pulsador, LOW);
}

//----------------------------------------------------------------Modulo Comparador-----------------------------------------

void comparador() {



  
   long tel = strtol(numtel,NULL,10);
   Serial.println("TEL");
   Serial.println(tel);
   delay (50);


 

  int pos = enguia(strtol(numtel, 0, 10));

    if (pos>=0) {
        Serial.println("Aceptado!"); 
      delay(1500);
      Puerta();} // el teléfono estará en la posición pos del array
 
    else
       {
        Serial.println("Denegado!");}} // el teléfono no se encuentra en la guía.



  

  //------------------------------------------------ayuda------------------------------------------------------

bool agrega(long newtel){
      if (longuia>=200){
            Serial.println("No se pudo agregar tel. Guia llena");
            return(false);
      }
      else {
            telefonos[longuia] = newtel;
            int direccionEEPROM=longuia*sizeof(long);
            byte *memdir = (byte *) &telefonos[longuia];
            for ( int i=0; i<sizeof(long); i++)
                  EEPROM.write(direccionEEPROM++, memdir[i]);
            longuia++;
      }
}



int enguia(long tel){
      for (int i=0; i< longuia; i++)
            if (tel==telefonos[longuia]){
                  return(i);}
     else{
       return(-1);}}



//----------------------------------------------------------TELEFONO------------------------------------------
void telefono(){
  switch (vcs.getvoiceCallStatus())          // Mirar el estado de la llamada
  {
    case IDLE_CALL:                          // En caso de que no pase nada
    break;                                   // Volvemos al Inicio
      
    case RECEIVINGCALL:                      // En caso de entrar una llamada
    Serial.println("Recibiendo llamada");    // Anunciamos una LLamada entrante
    vcs.retrieveCallingNumber(numtel, 20);   // Recuperar el número de llamadas
    Serial.print("Numero Entrante:");        // Mostramos el numero en la Pantalla
    Serial.println(numtel);
    delay(500);
    vcs.hangCall();                          // colgamos  
    comparador();                            // Ejecutamos Modulo Comparador
    
    break;                                   // Finalizamos y volvemos al Principio
}
}




//------------------------------------------------------MENSAJES-------------------------------------------------------


void smsL() {
  
   char c[10];   // Donde guardaremos el contenido del mensaje
   
  if (sms.available())
  {
    
  sms.remoteNumber(senderNumber, 14);
    Serial.println(senderNumber);

      
    for (int i=0; i<9; i++)    c[i]=sms.read();
    c[9] =0; // escribimos un terminador de cadena al final del número 
    newtel=strtol(c, 0, 10);
    Serial.println(c);
    
         
     strtol(c, 0, 10);  
     if(agrega(strtol(c, 0, 10))) {
        Serial.println("telefono añadido ");
        sms.flush();}
      
/*
    else {
       Serial.println("telefono no añadido ");
            //el teléfono no se pudo agregar a la guía
      sms.flush();}
   */ 

delay (1500);
sms.flush();    

}}

cuando le llamo me imprime:

//------------------------------------------------

Arrancando el programa de recepcion de llamadas
Esperando la llamada
987654321
987654321
987654321
987654321
679734177
679734189
Recibiendo llamada
Numero Entrante:679734177 //------este es el numero desde el que llamo, es el (numtel) que escrive el programa del telefono
TEL
679734177 //-----------este es el numero que a convertido la funcion " long tel = strtol(numtel,NULL,10); "
Denegado!
//------------------------------------------

y no me lo a haceptado. teoricamente los dos son long, cierto? o son long de tipos diferentes??

Hola de nuevo.
Creo que he descubierto mi craso error. Es lo que tiene no probar el código (no tengo módulo gsm).

Mi craso error explicado, y así de paso te explico la función:

int enguia(long tel){  // la función enguia recibe un long y devuelve un int con el número de posición en que se encontró el teléfono o -1 si no se encontró.
      for (int i=0; i< longuia; i++)     // Recorro el array telefonos desde 0 hasta longuia (último grabado)
            if (tel==telefonos[longuia]){   // si coincide el entero con uno de los recorridos por el array salimos inmediatamente, retornando el valor de índice del array (posición del teléfono)
                  return(i);}
     else{    //// Este else sobra. Caca :).  Porque retornaría tras mirar el primer teléfono y no coincidir.
       return(-1);}} // El return se ejecutará tras finalizar el for sin encontrar resultado.

El código corregido (he añadido las llaves del for, aunque no serían necesarias porque sólo tiene una instrucción, pero para más claridad):

int enguia(long tel)
{
      for (int i=0; i< longuia; i++){
            if (tel==telefonos[longuia]){
                  return(i);}
      }
      return(-1); // Sólo si tras haber recorrido todo el array desde 0 hasta longuia no hemos retornado por coincidencia.
}

La llamada, tal como tienes el código también podría ser
int pos = enguia(tel);
en lugar de volver a repetir el strtol.
Y en agrega puedes usar agrega(newtel) por la misma razón. Tienes, además, justo antes de la llamada a agrega un
strtol(c, 0, 10);
sin más, que no está haciendo nada.
A ver si ahora hay suerte ;).

Me pasa lo mismo compadre...