Nuevo Proyecto Discriminador llamadas telefónicas

Hola estoy desarrollando un proyecto de crear un discriminador de llamadas telefónicas que utiliza un Arduino Uno R3, un modem serie USR56k y un módulo RS232. El código que tengo me permite comunicarme con el modem, leer el número entrante y tomar el control de la comunicación al primer RING. La cuestión que quiero completar es la manera de almacenar todos los números a bloquear en un archivo de lectura/escritura bque sea accesible a Arduino a traves de acceso a una tarjeta SD y que pueda ser leido secuencialmente para poder comparar dichos números con el que lee arduino desde el modem en cada llamada. El proyecto completo incluye un keypad shield 16x2 de 5 botones, que permita seleccionar el almacenar en la SD el número llamante que aparece en el LCD o borrarlo de esta. Mi código actual es este:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

char string1[ ] = "NMBR = 12345678";//numero a bloquear

int readline(int readch, char *buffer, int len)
{
 static int pos = 0;
 int rpos;

 if (readch > 0) {
   switch (readch) {
     case '\n': // Ignore new-lines
       break;
     case '\r': // Return on CR
       rpos = pos;
       pos = 0;  // Reset position index ready for next time
       return rpos;
     default:
       if (pos < len-1) {
         buffer[pos++] = readch;
         buffer[pos] = 0;
       }
   }
 }
 // No end of line has been found, so return -1.
 return -1;
}

void setup()
{
 Serial.begin(9600);
 mySerial.begin(9600);
 Serial.println("Setup is Ready\n");
 mySerial.write("ATZ\r\n");
 delay(4000);
 //mySerial.write("AT+VCID=1\r\n");//Conceptronics CID ON
 mySerial.write("AT#CID=1\r\n");//USR Robotics CID ON
 delay(2000);
 mySerial.write("ATS7=5\r\n");//USR Robotics Answer Wait 7 seg
 delay(2000);
 mySerial.write("ATS0=0\r\n");//USR Robotics Auto Answer OFF
 delay(2000);
}

void loop()
{
 static char buffer[80];
 if (readline(mySerial.read(), buffer, 80) > 0) {
   Serial.print("Datos: >");
   Serial.print(buffer);
   Serial.println("<");
   
    if(strcmp(string1, buffer) == 0)
   {
    Serial.print("Antonio Movil\n");
    mySerial.write("ATA\r\n");//Coge el tlf
    delay(2000);
    mySerial.write("ATH1\r\n");//Cuelga el tlf
    delay(2000);
   }
  }
}

El proyecto va avanzando, nuevo codigo generado, a falta de añadir la lectura/escritura en SD de los números a bloquear y el código de presentación de los números llamantes en un LCD 16x2.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

char nmbrstring[ ] = "NMBR";
char numerodete[20];
char numerotst[ ] ="123456789";
char charBuf[50];

int readline(int readch, char *buffer, int len)
{
  static int pos = 0;
  int rpos;

  if (readch > 0) {
    switch (readch) {
      case '\n': // Ignore new-lines
        break;
      case '\r': // Return on CR
        rpos = pos;
        pos = 0;  // Reset position index ready for next time
        return rpos;
      default:
        if (pos < len-1) {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
    }
  }
  // No end of line has been found, so return -1.
  return -1;
}

void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
  Serial.println("Setup is Ready\n");
  mySerial.write("ATZ\r\n");
  delay(4000);
  //mySerial.write("AT+VCID=1\r\n");//Conceptronics CID ON
  mySerial.write("AT#CID=1\r\n");//USR Robotics CID ON
  delay(2000);
  mySerial.write("ATS7=5\r\n");//USR Robotics Answer Wait 7 seg
  delay(2000);
  mySerial.write("ATS0=0\r\n");//USR Robotics Auto Answer OFF
  delay(2000);
 }

void loop()
{
  static char buffer[80];
  if (readline(mySerial.read(), buffer, 80) > 0) {
    Serial.print("Datos: >");
    Serial.print(buffer);
    Serial.println("<");
    
    char* numero1 = strchr(buffer, 'NMBR =');
    char* prefinmbr = strtok(buffer, " =");
    char* numero2 = strchr(numero1, ' ');
    /* // Comprobador serie deteccion numero
    Serial.println("Numero:");
    Serial.print(numero2);
    Serial.println("Prefinmbr:");
    Serial.print(prefinmbr);
    Serial.print("==");
    Serial.print(nmbrstring);
    Serial.print("\n");
    */
    if(strcmp(prefinmbr, nmbrstring) == 0)
    {
     //Lector de numero
     char* numerodete = numero2;
     /*
     Serial.print("Numero llamante es:\n");
     Serial.print(numerodete);
     Serial.print("\n");
     */
     String stringOne = numerodete;
     stringOne.trim();
     /*
     Serial.print("Numero llamante sin espacios:\n");
     Serial.print(stringOne);
     Serial.print("\n");
     */
     stringOne.toCharArray(charBuf, 50);
     
    if(strcmp(charBuf, numerotst) == 0)
    {
      Serial.print("Numero detectado es:\n");
      Serial.print(charBuf);
      Serial.print("\n");
      //Serial.print("==");
      //Serial.print(numerotst);
      //Codigo contestar y colgar
     //mySerial.write("ATA\r\n");//Coge el tlf
     //delay(2000);
     //mySerial.write("ATH1\r\n");//Cuelga el tlf
     //delay(2000);
    }
    }
   }
}

Sigo avanzando, aquí va el código con el sistema de lectura de los números bloqueados en un archivo de una SD, y almacenamiento de los números de las llamadas recibidas en otro archivo de la SD. Pronto vendrá el modulo LCD que muestra el número y el control por botonadura de la grabación del número a bloquear en el fichero de la SD.

/* Proyecto de discriminador de llamadas telefonicas no deseadas, tras la llamada se identifica el
numero llamante y se compara con los que están anotados en un fichero almacenado en una tarjeta SD.
El hardware necesario es un Arduino Uno, un modem con CallerID (en mi caso US Robotics 56k), un modulo
SD YL-30, una tarjeta SD, un modulo Serie RS232 y un cable serie modem nulo.
El cable serie modem nulo permite obviar el comportamiento del modem en respuesta a la lineas RTS-CTS,
DTR-DSR, las cuales se unen en los extremos de cada conector, cruzándose las lineas TX-RX y 
uniendo las GND entre si.
*/

#include <SoftwareSerial.h>
#include <SD.h> //CS en pin 4

SoftwareSerial mySerial(8, 9); // RX, TX

// Guardamos en que entrada de arduino esta conectado el pin CS del modulo.
const int chipSelect = 4;
char nmbrstring[ ] = "NMBR";
char numerodete[20];
char numerotst[20];// ="656268358";
char charBuf[50];
char charBuf2[50];
int numblock = 50;//cantidad de lieas de numeros del fichero
File myFile2; //fichero llamadas recibidas

int readline(int readch, char *buffer, int len)
{
  static int pos = 0;
  int rpos;

  if (readch > 0) {
    switch (readch) {
      case '\n': // Ignore new-lines
        break;
      case '\r': // Return on CR
        rpos = pos;
        pos = 0;  // Reset position index ready for next time
        return rpos;
      default:
        if (pos < len-1) {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
    }
  }
  // No end of line has been found, so return -1.
  return -1;
}

void setup()
{
  // Configuramos el puerto serie para informar de fallos a traves de el.
  Serial.begin(9600);
  // Configuramos el puerto serie virtual para comunicarnos con el modem.
  mySerial.begin(9600);
  
  Serial.println("Setup is Ready\n");
  
  // Iniciamos los comandos Hayes para configurar el modem
  mySerial.write("ATZ\r\n");
  delay(4000);
  //mySerial.write("AT+VCID=1\r\n");//Conceptronics CID ON
  mySerial.write("AT#CID=1\r\n");//USR Robotics CID ON
  delay(2000);
  mySerial.write("ATS7=5\r\n");//USR Robotics Answer Wait 7 seg
  delay(2000);
  mySerial.write("ATS0=0\r\n");//USR Robotics Auto Answer OFF
  delay(2000);
  
  //Iniciamos la SD
  Serial.print("Iniciando SD...");
  Serial.print("\n");
  // El pin CS por defecto de la placa arduino debe ser configurado como salida
  // aunque no se use (10 en la mayoria de las placas, 53 en Arduino Mega).
  pinMode(10, OUTPUT);
  // Si ha habido error al leer la tarjeta informamos por el puerto serie.
  if (!SD.begin(chipSelect)) {
  Serial.println("Error inicializar SD!");
  return;
 }
 
 Serial.print("SD inicializada...OK");
 Serial.print("\n");
 
}



void loop()
{
  static char buffer[80];
  if (readline(mySerial.read(), buffer, 80) > 0)
  {
    Serial.print("Datos: >");
    Serial.print(buffer);
    Serial.println("<");
    
    char* numero1 = strchr(buffer, 'NMBR =');
    char* prefinmbr = strtok(buffer, " =");
    char* numero2 = strchr(numero1, ' ');
    /* // Comprobador serie deteccion numero
    Serial.println("Numero:");
    Serial.print(numero2);
    Serial.println("Prefinmbr:");
    Serial.print(prefinmbr);
    Serial.print("==");
    Serial.print(nmbrstring);
    Serial.print("\n");
    */
    if(strcmp(prefinmbr, nmbrstring) == 0)//Detectamos la cadena NMBR que contiene el numero llamante
    {
     //Lector de numero
     char* numerodete = numero2;//detecta numero con 1 espacio al inicio
     String stringOne = numerodete;//convierte numero char a string
     stringOne.trim();//elimina el espacio del inicio del número
     Serial.print("Numero llamante es:\n");
     Serial.print(stringOne);
     Serial.print("\n");
     stringOne.toCharArray(charBuf, 50);//convierte el numero string a char para strcmp
     
     //Inicio codigo escritura llamadas recibidas     
     // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  
  myFile2 = SD.open("RECIB.TXT", FILE_WRITE);
  // if the file opened okay, write to it:
  if (myFile2) {
    Serial.print("Writing...");
    myFile2.println(stringOne);
	// close the file:
    myFile2.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening file");
  }
  // fin codigo escritura llamadas recibidas
     
    char Ruta[9] = {'t', 'e', 's', 't', '.', 't', 'x', 't', '\0'};//establece nombre fichero tlfs bloqueados
      
    for(int i = 0; i < numblock; i++)// secuencialmente se lee cada una de los numeros del fichero
    {
    //Leemos linea de archivo en la SD
    String numerotst = ReadFile(i,Ruta);
    String stringTwo = numerotst;
    stringTwo.toCharArray(charBuf2, 50);// convertimos string to char para strcmp
    
    if(strcmp(charBuf, charBuf2) == 0)// comparamos el numero detectado con el leido en el fichero
    {
      Serial.print("Numero detectado es:\n");
      Serial.print(charBuf);
      Serial.print("\n");
      
     //Codigo contestar y colgar
     //mySerial.write("ATA\r\n");//Coge el tlf
     //delay(2000);
     //mySerial.write("ATH1\r\n");//Cuelga el tlf
     //delay(2000);
    }
   }
  }
 }
}



// Codigo de lectura de los telefonos bloqueados en la SD
String ReadFile(int Linea,char Ruta[]){
int Lin=0;
String Resultado;
File myFile;
byte Bin;
myFile = SD.open(Ruta);;
if (myFile) {
while (myFile.available()) {
Bin=myFile.read();
if (Bin==13){Lin++;myFile.read();}
else
{
if (Lin==Linea){Resultado=Resultado+(char(Bin));}
if (Lin>Linea){myFile.close();return Resultado;}
}
}
myFile.close();return Resultado;
}
}

Hola a todos, gracias a la ayuda de la estupenda gente de este foro ya he terminado el código totalmente y es perfectamente funcional. Es un discriminador de llamadas entrantes por línes telefónica. Recibe las llamadas a través de un modem, el cual lee el número llamante, lo envía por un módulo serie a un Arduino UNO y este lo graba en un fichero de una tarjeta SD. Posteriormente podemos leer los números llamantes con la pulsación de una botonadura y elegir si queremos bloquearlo o no pulsando otro botón. Tras ello se graba el número en un fichero de números bloqueados que es utilizado para leer el número llamante y compararlo con el almacenado en el fichero. Si coinciden, la llamada es tomada y se paran los timbrazos del teléfono durante unos minutos. El código completo en dos partes es este:
Primera parte:

/* Proyecto de discriminador de llamadas telefonicas no deseadas, tras la llamada se identifica el
numero llamante y se compara con los que están anotados en un fichero almacenado en una tarjeta SD. Si
coincide con alguno, la llamada es bloqueada. Ademas graba automáticamente los números que han llamado
 y que posteriormente pueden seleccionarse con la botonadura para ser bloqueados.
El hardware necesario es un Arduino Uno, un modem con CallerID (en mi caso US Robotics 56k), un modulo
SD YL-30, una tarjeta SD, un modulo Serie RS232, un cable serie modem nulo, un modulo LCD de 16x2 y
una botonadura tipo Keypad de resistencias (una botonadura simple con tres resistencias de 3K en serie
conectando GND a Pin A0, p.e.).
El cable serie modem nulo permite obviar el comportamiento del modem en respuesta a la lineas RTS-CTS,
DTR-DSR, las cuales se unen en los extremos de cada conector, cruzándose las lineas TX-RX y 
uniendo las GND entre si.

Conexion pines modulo SD a Arduino:
modulo: GND 3.3v 5v. CS MOSI SCK MISO GND
Arduino:GND 3.3V 5V. 10 11   13  12   GND

Conexion pines modulo LCD 1602 a Arduino:
(X)En modulo unir 1 y 3 con Resitencia 3K.
modulo:  1  2  3  4  5   6 ....11 12 13 14 15 16 
Arduino:GND 5v(X) 2 GND  3 ....4  5  6  7  5v GND

*/
//Sample using LiquidCrystal library
#include <LiquidCrystal.h>

#include <SoftwareSerial.h>
#include <SD.h> //CS en pin 10


SoftwareSerial mySerial(8, 9); // pin 8 a TX y 9 a RX del modulo

// select the pins used on the LCD panel
 LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
 
// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// Guardamos en que entrada de arduino esta conectado el pin CS del modulo.
//const int chipSelect = 10;
char nmbrstring[ ] = "NMBR";
char numerodete[10];
char numerotst[10];
char numllam[10];

char charBuf[10];
char charBuf2[10];
char charThree[10];

int numblock = 50;//cantidad de lineas de numeros del fichero
int i2 = 0;
int llamadas = 0;// Contador de llamadas, debe ser 0. Otro valor es para pruebas.
File myFile; //fichero llamadas recibidas
String stringThree;

unsigned long tAntes = 0;
unsigned long tAntes2 = 0;
unsigned long tAntes3 = 0;
unsigned long tAntes4 = 0;
long time_now = 0;

void setup()
{
 lcd.begin(16, 2);              // start LCD library
 pinMode(A0, INPUT_PULLUP); // sets analog pin for input
 lcd.setCursor(0,0);
 lcd.print("LCD Activado"); // print a simple messag
 delay (2000);
 
  // Configuramos el puerto serie para informar de fallos a traves de el.
  Serial.begin(9600);
  while (!Serial) {
; // Espera para conexion puerto serie, solo necesario para leonardo
}
  // Configuramos el puerto serie virtual para comunicarnos con el modem.
  mySerial.begin(9600);
  
  //Serial.println("Setup is Ready\n");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Setup is Ready");
      
  //Iniciamos la SD
  //Serial.print("Iniciando SD...");
  //Serial.print("\n");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Iniciando SD...");
  // El pin CS por defecto de la placa arduino debe ser configurado como salida
  // aunque no se use (10 en la mayoria de las placas, 53 en Arduino Mega).
  pinMode(10, OUTPUT);
  // Si ha habido error al leer la tarjeta informamos por el puerto serie.
  if (!SD.begin(10)) {
  //Serial.println("Error inicializar SD!");
  lcd.setCursor(0,1);
  lcd.print("Error ini.SD!");
  delay(2000);
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("PULSE RESET");
  pinMode(10, INPUT);
  delay(1000);
  
  //card.init(SPI_HALF_SPEED, 10);
  
  delay(1000);
  setup();
  //return;
 }
 
 //Serial.print("SD inicializada...OK");
 //Serial.print("\n");
 lcd.setCursor(0,1);
 lcd.print("SD ini...OK");
 delay(2000);
 
//REcreando fichero RECIB.TXT
 
File Archivo1;
Archivo1 = SD.open("RECIB.TXT", FILE_WRITE);

if (Archivo1) {
Archivo1.println("111111111");

Archivo1.close();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("RECIB.TXT ini"); 
delay(2000);
lcd.setCursor(0,1);
lcd.print("OK");
delay(2000);
} else {
lcd.setCursor(0,1);
lcd.print("Error SD write");
delay(2000);
}
 
 /* //Codigo test fichero existente
 if (SD.exists("RECIB.TXT")){
        lcd.setCursor(0,1);
        lcd.print("RECIB.TXT exists");
        SD.open("RECIB.TXT", FILE_WRITE).close();
     }
     else {
       lcd.setCursor(0,1);
        lcd.print("NO RECIB.TXT");
       SD.open("RECIB.TXT", FILE_WRITE);
       SD.open("RECIB.TXT", FILE_WRITE).close();
           }
  delay(2000);
  if (SD.exists("BLOQ.TXT")){
        lcd.setCursor(0,1);
        lcd.print("BLOQ.TXT exists");
        SD.open("BLOQ.TXT", FILE_WRITE).close();
     }
    else {
     lcd.setCursor(0,1);
     lcd.print("NO BLOQ.TXT");
     SD.open("BLOQ.TXT", FILE_WRITE);
     SD.open("BLOQ.TXT", FILE_WRITE).close();
         }
  */ // Fin codigo test
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Start Modem....");
  
  // Iniciamos los comandos Hayes para configurar el modem
  mySerial.write("ATZ\r\n");
  delay(4000);
  lcd.setCursor(0,1);
  lcd.print("4.");
  //mySerial.write("AT+VCID=1\r\n");//Conceptronics CID ON
  mySerial.write("AT#CID=1\r\n");//USR Robotics CID ON
  delay(2000);
  lcd.setCursor(2,1);
  lcd.print("3.");
  mySerial.write("ATS7=5\r\n");//USR Robotics Answer Wait 7 seg
  delay(2000);
  lcd.setCursor(4,1);
  lcd.print("2.");
  mySerial.write("ATS0=0\r\n");//USR Robotics Auto Answer OFF
  delay(2000);
  lcd.setCursor(6,1);
  lcd.print("OK");
  
  delay(2000);
 }



void loop()
{
  static char buffer[20];
 
    buttonselect();// Selector botones
  
  if (readline(mySerial.read(), buffer, 80) > 0)
  {
    //Presentador de todos los datos leidos por el puerto serie
    //Serial.print("Datos: >");
    //Serial.print(buffer);
    //Serial.println("<");
    //lcd.clear();
    //lcd.setCursor(0,0);
    //lcd.print("Datos: >");
    //lcd.print(buffer);
    
    char* numero1 = strchr(buffer, 'NMBR =');
    char* prefinmbr = strtok(buffer, " =");
    char* numero2 = strchr(numero1, ' ');
    
    /* // Comprobador por puerto serie deteccion numero
    Serial.println("Numero:");
    Serial.print(numero2);
    Serial.println("Prefinmbr:");
    Serial.print(prefinmbr);
    Serial.print("==");
    Serial.print(nmbrstring);
    Serial.print("\n");
    */
    
    if(strcmp(prefinmbr, nmbrstring) == 0)//Detectamos la cadena NMBR que contiene el numero llamante
    {
     //Lector de numero
     char* numerodete = numero2;//detecta numero con 1 espacio al inicio
     String stringOne = numerodete;//convierte numero char a string
     stringOne.trim();//elimina el espacio del inicio del número
     
     //Serial.print("Numero llamante es:\n");
     //Serial.print(stringOne);
     //Serial.print("\n");
     
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Num.llamante:");
     lcd.setCursor(0,1);
     lcd.print(stringOne);
     
     
     stringOne.toCharArray(charBuf, 10);//convierte el numero string a char para strcmp
     
     lcd.setCursor(0,1);
     lcd.print(charBuf);

segunda parte:

    //Inicio codigo escritura llamadas recibidas     
     // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  
  myFile = SD.open("RECIB.TXT", FILE_WRITE);
  // if the file opened okay, write to it:
  if (myFile) {
    
    myFile.println(stringOne);
    myFile.close();// close the file:
    
    llamadas++;// acumulado de numero de llamadas
    lcd.setCursor(0,0);
    lcd.print("Llamadas.....");
    lcd.setCursor(14,0);
    lcd.print(llamadas);
    
    lcd.setCursor(12,1);
    lcd.print("WCOK");
    
    //Mantiene el tiempo a 0 mientras se pulsa boton lectura
    long time_now = millis();
    tAntes = time_now;
    tAntes2 = time_now;
    tAntes3 = time_now;
    tAntes4 = time_now;
    
    
  } else {
    // if the file didn't open, print an error:
    //Serial.println("error opening file");
  lcd.setCursor(0,1);
  lcd.print("error SD write");
}
  
  // fin codigo escritura llamadas recibidas
     
    //Inicio seccion lectura fichero numeros bloqueados.
    
    char Ruta[9] = {'B', 'L', 'O', 'Q', '.', 'T', 'X', 'T', '\0'};//establece nombre fichero tlfs bloqueados
      
    for(int i = 0; i < numblock; i++)// secuencialmente se lee cada una de los numeros del fichero
    {
    //Leemos linea de archivo en la SD
    String numerotst = ReadFile(i,Ruta);
    String stringTwo = numerotst;
    stringTwo.toCharArray(charBuf2, 10);// convertimos string to char para strcmp
    
    if(strcmp(charBuf, charBuf2) == 0)// comparamos el numero detectado con el leido en el fichero
    {
      //Serial.print("Numero detectado es:\n");
      //Serial.print(charBuf);
      //Serial.print("\n");
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Numero detec.:");
      lcd.setCursor(0,1);
      lcd.print(charBuf); // Muestra el numero bloqueado
      
     /* //Codigo contestar y colgar
     mySerial.write("ATA\r\n");//Coge el tlf
     delay(2000);
     mySerial.write("ATH1\r\n");//Cuelga el tlf
     */
       delay (4000);
       
     }// Fin deteccion numero bloqueado
   }//Fin bucle lectura numeros bloqueados SD
  }//Fin deteccion de llamada NMBR
 }//Fin lectura buffer serie
}



// Codigo de lectura de los telefonos bloqueados en la SD
String ReadFile(int Linea,char Ruta[]){
int Lin=0;
String Resultado;
File myFile;
byte Bin;
myFile = SD.open(Ruta);;
if (myFile) {
while (myFile.available()) {
Bin=myFile.read();
if (Bin==13){Lin++;myFile.read();}
else
{
if (Lin==Linea){Resultado=Resultado+(char(Bin));}
if (Lin>Linea){myFile.close();return Resultado;}
}
}
myFile.close();return Resultado;
}
}

   
/// AÑADIDO CONTROL BOTONADURA Y GRABADO NUMEROS BLOQUEADOS SD

void buttonselect()
{
 lcd.setCursor(0,1);            // move to the begining of the second line
 lcd_key = read_LCD_buttons();  // read the buttons
 
 switch (lcd_key)               // depending on which button was pushed, we perform an action
 {
   case btnRIGHT:
     {
     lcd.clear();
     lcd.setCursor(0,1);   
     //lcd.print(adc_key_in);  
     lcd.print("RIGHT ");
     delay(500);
     break;
     }
   case btnLEFT:
     {
     lcd.print("LEFT  ");
     break;
     }
   case btnUP:
     {
     lcd.print("UP    ");
     break;
     }
   case btnDOWN:
     {
     /*lcd.clear();
     lcd.setCursor(0,1);   
     lcd.print(adc_key_in);
     lcd.print("DOWN ");*/
     leer();
     break;
     }
   case btnSELECT:
     {
     //lcd.setCursor(7,0);  
     //lcd.print("Bloquear");
     bloquear();
     /*lcd.clear();
     lcd.setCursor(0,1);   
     lcd.print(adc_key_in);
     lcd.print("SELECT");*/
     break;
     }
     case btnNONE:
     {
      long time_now = millis();
     
    if ((long)(time_now - tAntes) > 10000) // regulador de tiempo medida datos y presentacion lcd
    {
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Waiting call...");
     lcd.setCursor(0,1);
     lcd.print("Llamadas.....");
     lcd.setCursor(14,1);
     lcd.print(llamadas);
     tAntes = time_now;
    }
     if ((long)(time_now - tAntes2) > 1000)
    {
    lcd.setCursor(15,0);
    lcd.print("*");
    tAntes2 = time_now;
    }
    if ((long)(time_now - tAntes3) > 1500)
    {
    lcd.setCursor(15,0);
    lcd.print(" ");
    tAntes3 = time_now;
    }
    //Reponedor a 0 de lectura llamadas si inactividad en botones
    if ((long)(time_now - tAntes4) > 20000) 
    {
      i2 = 0;
      tAntes4 = time_now;
    } 
      break;
     }
 }
 
}


void leer()
{
    char Ruta[10] = {'R', 'E', 'C', 'I', 'B', '.', 'T', 'X', 'T', '\0'};//establece nombre fichero tlfs bloqueados
        
    String numllam = ReadFile(i2,Ruta);//Leemos linea de archivo como char en la SD
    
    //Proceso conversion de string to char para poder grabar los datos leidos
    String stringThree = numllam; //convertir char to string
    stringThree.toCharArray(charThree, 10);// convertimos string to char 
    
    delay(500);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Numero Leido.....");
    lcd.setCursor(15,0);
    lcd.print((llamadas + 5)- i2);
    //lcd.setCursor(0,1);
    //lcd.print("         "); // Muestra el numero leido
    lcd.setCursor(0,1);
    lcd.print(charThree); // Muestra el numero leido
    lcd.setCursor(12,1);
    lcd.print(".."); // Muestra el numero leido
    delay (500);
    
    i2++;
    
    //Mantiene el tiempo a 0 mientras se pulsa boton lectura
    long time_now = millis();
    tAntes = time_now;
    tAntes2 = time_now;
    tAntes3 = time_now;
    tAntes4 = time_now;
    
    if (i2 > (llamadas + 5))
    {
    i2 = 0;
    llamadas = 0;
    delay (1000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Borrando las");
    lcd.setCursor(0,1);
    lcd.print("LLamadas...");
    
    myFile.close();
    delay(2000);
    
    //Borrando fichero RECIB.TXT
    SD.remove("RECIB.TXT");
    delay(2000);
    
    myFile.close();
    
    //REcreando fichero RECIB.TXT
 
File Archivo1;
Archivo1 = SD.open("RECIB.TXT", FILE_WRITE);

if (Archivo1) {
Archivo1.println("111111111");

Archivo1.close();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("RECIB.TXT ini"); 
delay(2000);
lcd.setCursor(0,1);
lcd.print("OK");
delay(2000);
} else {
lcd.setCursor(0,1);
lcd.print("Error SD write");
delay(2000);
lcd.clear();
lcd.setCursor(0,1);
lcd.print("PULSE RESET");
delay(2000);
}
    // fin recreo
  
    }
 }
//funcion para escribir el número leido de RECIB.TXT y grabarlo en
//el fichero de numeros bloqueados BLOQ.TXT
void bloquear()
{
  myFile = SD.open("BLOQ.TXT", FILE_WRITE);
  if (myFile){
  myFile.println(charThree);
  myFile.close();
  }  else  {
  lcd.setCursor(0,1);
  lcd.print("error SD write");
  }
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Numero bloqueado");
  lcd.setCursor(0,1);
  lcd.print("         "); // Limpia espacio numero
  lcd.setCursor(0,1);
  lcd.print(charThree); // Muestra el numero bloqueado
  lcd.setCursor(12,1);
  lcd.print("BQ");
  //Mantiene el tiempo a 0 mientras se pulsa boton lectura
    long time_now = millis();
    tAntes = time_now;
    tAntes2 = time_now;
    tAntes3 = time_now;
    tAntes4 = time_now;
    delay(2000);
}

//Sistema de lectura del puerto serie
int readline(int readch, char *buffer, int len)
{
  static int pos = 0;
  int rpos;

  if (readch > 0) {
    switch (readch) {
      case '\n': // Ignore new-lines
        break;
      case '\r': // Return on CR
        rpos = pos;
        pos = 0;  // Reset position index ready for next time
        return rpos;
      default:
        if (pos < len-1) {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
    }
  }
  // No end of line has been found, so return -1.
  return -1;
}
// fin programa lectura puerto serie

// read the buttons
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor 

//Valores para botonadura simple de 3 resistencias de 3k Ohm en serie

 if (adc_key_in > 1000) return btnNONE; // Ningun boton pulsado
 
 if (adc_key_in < 95 && adc_key_in > 90)   return btnRIGHT;  
 //if (adc_key_in < 250)  return btnUP; 
 if (adc_key_in < 200 && adc_key_in > 100)  return btnDOWN; 
 //if (adc_key_in < 650)  return btnLEFT; 
 if (adc_key_in > 200 && adc_key_in < 300)  return btnSELECT;  
 
 return btnNONE;  // when all others fail, return this...
}
// FIN READ BUTTONS

en lugar de ponerlo asi que requiere para todos nosotros tener que copiar y pastearlo y luego cambiar el nombre y bla bla bla no es mas facil ir a Additional Options y subirlo como .ino?

OK, cosas de novato. Lo siento. Aquí os subo las versiones para SD.h y para SDfat.h, como .ino :slight_smile:

Una cuestión final, los sketch están pensados para que al ser instalados con el hardware correspondiente funcionen sólamente indicando en el LCD el número a bloquear y NO cojan la llamada ( cuestiones de gasto de llamadas de prueba con el móvil). Para activar el sistema de bloqueo real, sólo hay que ir a la sección correspondiente y activarla, para el que no lo vea claro es esta:


/* //Codigo contestar y colgar
mySerial.write("ATA\r\n");//Coge el tlf
delay(2000);
mySerial.write("ATH1\r\n");//Cuelga el tlf
*/

modem_sd_bt3_39.ino (15 KB)

modemsdfat_bt3_39.ino (14.5 KB)

Una cuestión adicional a este proyecto es lo que a mí me gustaría que hiciese finalmente.
Se puede hacer que la pantalla LCD se mantenga presentando la hora y el día exactos, ya que tras cada llamada esta información es enviada por el módem a Arduino, con lo cual sería sólo cuestión de implementar el modo de recuperar dichos datos, y usarlos para mantener al día los datos de un reloj interno por soft, sin añadir un módulo RTC. Hoy por hoy no he encontrado la manera de borrar un número del fichero de números bloqueados o añadir un número a bloquear que no haya llamado previamente, estas operaciones que hay que hacerlas extrayendo la tarjeta SD y editando a mano el fichero BLOQ.TXT . De igual manera, la posibilidad de hacer un backup automatizado de los datos del fichero de números bloqueados es algo que escapa de mi conocimiento actual. Otra cuestión es poder reflejar alfabéticamente el nombre del llamante, para ello habría que mantener un fichero adicional con correspondencia de números y nombres, que debería ser editado manualmente en un ordenador.
En la cuestión del hardware, el módem es un aparato relativamente voluminoso y el cable serie trasero es casi siempre molesto a la vista. Existe un procedimiento para conectar al puerto serie del módem un módulo serial bluetooth que se comunica con otro módulo serial bluetooth conectado a Arduino (tengo experiencia con ellos ya que los uso en otro proyecto, un lector/presentador de datos de un coche por OBD ELM 27), eso evita tener que colocar los dos componentes: Arduino y módem, juntos, e incluso permite distanciarlos unos metros. El uso de la conexión por bluetooth abre un abanico de posibilidades ilimitadas para poder leer y escribir datos en los ficheros de la tarjeta SD, siendo indispensable para ello una profunda modificación del sketch para incluir esa posibilidad.

Cosas para mejorar en tu proyecto
Simplemente he transcripto tus inquietudes para que sean mas entendibles.
Ahora podremos ir atacando punto a punto si te parece.
comienza informando el punto 1) y seguiremos avanzando.
Por favor, provee copias de los archivos BLOQUEO.TXT y los que tengas para asi poder avanzar sin tener que creasr dichos datos.

  1. Presentar en el LCD, la hora y el día exactos, ya que tras cada llamada esta información es enviada por el módem a Arduino,
    Como envia el modem dicha información?, no lo has precisado, indica como es la cadena que incluye esos datos

  2. borrar un número del fichero de números bloqueados o añadir un número a bloquear que no haya llamado previamente
    Hacerlo considerando archivo BLOQUEO.TXT

  3. hacer un backup automatizado de los datos del fichero de números bloqueados

  4. Reflejar alfabéticamente el nombre del llamante, para ello habría que mantener un fichero adicional con correspondencia de números y nombres, que debería ser editado manualmente en un ordenador

  5. Usar un BT como bridge entre Arduino y MODEM.

Bueno, en el punto 1 te puedo dar los datos que lee el puerto serie conectado a Arduino:

Datos: >RING<
Datos: >DATE = 1011< //fecha formato MM:DD
Datos: >TIME = 1204< //hora formato HH:MM 24h.
Datos: >NMBR = 692616563<
Datos: >RING<

El dato NMBR = 692616563 es el que uso para el discriminador de llamadas. Todos los datos son proporcionados por la compañía telefónica y no se leen de ningún registro interno del módem.

De los ficheros BLOQ.TXT y RECIB.TXT te puedo decir que son sólo secuencias de 1 número por línea. El fichero RECIB.TXT se borra cada vez que se lee completamente línea a línea pulsando la tecla de lectura (la numero 2) (un contador regresivo nos indica el último número a leer), creandose al finalizar la lectura un nuevo fichero con una línea inicial de un sólo número, el 111111111. El fichero BLOQ.TXT se va llenando de líneas con números a medida que se van eligiendo para bloquear con la pulsación de la tecla de bloqueo (la numero 1).

bien comunidad tenemos trabajo!!!!
Comienza entonces con
Datos: >RING<
Datos: >DATE = 1011< //fecha formato MM:DD
Datos: >TIME = 1204< //hora formato HH:MM 24h.
Datos: >NMBR = 692616563<
Datos: >RING<

Que pasa con el año no lo indica? pones
Datos: >DATE = 1011< //fecha formato MM:DD
o sea debo interpretar 11/10 u 11 de octubre? Año no?

Datos: >TIME = 1204<
hora lo mismo, no da segundos?

Hola, los datos son como ves, no da valor de año, ni da valor de segundos.

Otra cuestión es que me he replanteado el uso del puerto serie virtual ya que el proyecto terminado no lo necesita, y fué sólo una ayuda en el proceso de creación de los sketch. Por tanto he modificado los sketch para que usen el puerto serie normal de Arduino (Pin 0 y 1), dejando libres los pines 8 y 9, y evitendo el uso de la biblioteca SoftwareSerial.h. Los ino están como adjuntos.

modem_sd_SR_bt3_40.ino (13.2 KB)

modemsdfat_SR_bt3_40.ino (13.2 KB)