Pages: [1]   Go Down
Author Topic: Desesperado con programa  (Read 62 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola, tengo un proyecto de discriminador de llamadas telefónicas usando un Arduino Uno R3, un modem, un modulo serie y una tarjeta SD. El sistema lee los números que llaman, los compara con los almacenados en un fichero de la tarjeta SD y si coinciden, bloquea la llamada. El sistema funciona perfectamente. Pero le he intentado añadir una funcionalidad mas, grabar los números de llamadas recibidas, leerlos y grabarlos en el fichero de números bloqueados. Para ello estoy usando un keypad shied que lleva un LCD 16x02 por el que puedo ver los números llamantes, elegirlos y bloquearlos. El problema está en que cada vez que intento activar el Void que lanza el sistema de botonadura buttonselect(), el sistema deja de ejecutar el código que lee los números bloqueados, no importa que lo coloque tras un if condicional que impida que se ejecute hasta que todos los números del fichero hayan sido leídos, lo sigue haciendo. He comprobado colocando puntos de impresion de sucesos en el LCD que el bucle de lectura se ejecuta perfectamente, pero parece que el sistema " if(strcmp(charBuf, charBuf2)" no se ejecuta en presencia de  buttonselect(). Os dejo el codigo (en dos post ya que no cabe en uno solo):

Code:
/* 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.
*/
//Sample using LiquidCrystal library
#include <LiquidCrystal.h>

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

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

// 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[20];
char numerotst[20];
char numllam[20];
char charBuf[50];
char charBuf2[50];
int numblock = 50;//cantidad de lineas de numeros del fichero
File myFile2; //fichero llamadas recibidas
int llamadas = 0;


File myFile3; //grabacion fichero llamadas recibidas
int i2 = 0;

// read the buttons
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor
 // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 // For V1.1 us this threshold
 if (adc_key_in < 50)   return btnRIGHT; 
 if (adc_key_in < 250)  return btnUP;
 if (adc_key_in < 450)  return btnDOWN;
 if (adc_key_in < 650)  return btnLEFT;
 if (adc_key_in < 850)  return btnSELECT; 
 
 // For V1.0 comment the other threshold and use the one below:
/*
 if (adc_key_in < 50)   return btnRIGHT; 
 if (adc_key_in < 195)  return btnUP;
 if (adc_key_in < 380)  return btnDOWN;
 if (adc_key_in < 555)  return btnLEFT;
 if (adc_key_in < 790)  return btnSELECT;   
*/
 
 
 return btnNONE;  // when all others fail, return this...
}
// FIN READ BUTTONS


//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

void setup()
{
  lcd.begin(16, 2);              // start the library
 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);
  // 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");
  lcd.setCursor(0,1);
  lcd.print("Starting....");
 
  // 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");
  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(chipSelect)) {
  //Serial.println("Error inicializar SD!");
  lcd.setCursor(0,1);
  lcd.print("Error ini.SD!");
  return;
 }
 
 //Serial.print("SD inicializada...OK");
 //Serial.print("\n");
 lcd.setCursor(0,1);
 lcd.print("SD ini...OK");
 delay(2000);
 
 if (SD.exists("RECIB.TXT")){
        lcd.setCursor(0,1);
        lcd.print("RECIB.TXT exists");
        SD.open("RECIB.TXT", FILE_WRITE).close();
     }
     //else {File Archivo1;
     //Archivo1 = SD.open("RECIB.TXT", FILE_WRITE);
     //SD.open("RECIB.TXT", FILE_WRITE).close();}
  delay(2000);
  if (SD.exists("test.txt")){
        lcd.setCursor(0,1);
        lcd.print("test.txt exists");
        SD.open("test.txt", FILE_WRITE).close();
     }
    // else {File Archivo1;
    // Archivo1 = SD.open("test.txt", FILE_WRITE);
    //SD.open("test.txt", FILE_WRITE).close();}
  delay(2000);
 
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("Waiting call...");
}

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Resto del código:
Code:
void loop()
{
  static char buffer[80];
  if (readline(mySerial.read(), buffer, 80) > 0)
  {
    //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 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, 50);//convierte el numero string a char para strcmp
     
     lcd.setCursor(0,1);
     lcd.print(charBuf);
     
     //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);
    myFile2.close();// close the file:
   
    llamadas = llamadas + 1;// Calcula el 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");
   
   
    //Serial.println("done.");
    //lcd.print("done.");
  } 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
     
    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");
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Numero detec.:");
      lcd.setCursor(0,1);
      lcd.print(charBuf); // print a simple message
     
     //Codigo contestar y colgar
     //mySerial.write("ATA\r\n");//Coge el tlf
     //delay(2000);
     //mySerial.write("ATH1\r\n");//Cuelga el tlf
     //delay(2000);

    }// Fin deteccion numero bloqueado
     if (i = numblock)// Condicion de que se han leido todos los numeros bloqueados
    {
     buttonselect();//Activacion del sistema de botonadura
    }
   }//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(9,1);            // move cursor to second line "1" and 9 spaces over
 
 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.print("RIGHT ");
     break;
     }
   case btnLEFT:
     {
     //lcd.setCursor(7,0);   
     //lcd.print("LEER   ");
     leer();
     break;
     }
   case btnUP:
     {
     lcd.print("UP    ");
     break;
     }
   case btnDOWN:
     {
     lcd.print("DOWN  ");
     break;
     }
   case btnSELECT:
     {
     lcd.setCursor(7,0); 
     lcd.print("Bloquear");
     bloquear();
     break;
     }
     case btnNONE:
     {
     break;
     }
 }
 
}


void leer()
{
    char Recib[10] = {'R', 'E', 'C', 'I', 'B', '.', 'T', 'X', 'T', '\0'};//establece nombre fichero tlfs bloqueados
       
    String numllam = ReadFile2(i2,Recib);//Leemos linea de archivo en la SD
   
    lcd.setCursor(0,0);
    lcd.print("              ");
    lcd.setCursor(0,0);
    lcd.print("Numero Leido..");
    lcd.setCursor(14,0);
    lcd.print("  ");
    lcd.setCursor(14,0);
    lcd.print(i2);
    lcd.setCursor(0,1);
    lcd.print("      ");
    lcd.setCursor(0,1);
    lcd.print(numllam); // Muestra el numero leido
    lcd.setCursor(12,1);
    lcd.print("  ");
    delay (1000);
    i2++;
    if (i2 > llamadas)
    {
    i2 = 0;
    //SD.remove("RECIB.TXT");//borra fichero RECIB.TXT
    //myFile = SD.open("RECIB.TXT", FILE_WRITE);//Crea fichero RECIB.TXT vacio
    //myFile.close();
    }
}

void bloquear()
{
  //myFile3 = SD.open("test.txt", FILE_WRITE);
  if (SD.exists("test.txt")){
  myFile3 = SD.open("test.txt", FILE_WRITE); 
  lcd.setCursor(0,0);
  lcd.print("Numero bloqueado");
  lcd.setCursor(0,1);
  lcd.print("      ");
  lcd.setCursor(0,1);
  lcd.print(numllam); // Muestra el numero bloqueado
  myFile3.println(numllam);
  SD.open("test.txt", FILE_WRITE).close();
  lcd.setCursor(12,1);
  lcd.print("BQ");
  }
}

// Codigo de lectura del fichero de llamadas recibidas
String ReadFile2(int Linea,char Recib[]){
int Lin=0;
String Resultado;
File myFile2;
byte Bin;
myFile2 = SD.open(Recib);;
if (myFile2) {
while (myFile2.available()) {
Bin=myFile2.read();
if (Bin==13){Lin++;myFile2.read();}
else
{
if (Lin==Linea){Resultado=Resultado+(char(Bin));}
if (Lin>Linea){myFile2.close();return Resultado;}
}
}
myFile2.close();return Resultado;
}
}



Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 337
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Primera cosa rara, jamas vi que se usen {} en un switch case luego del case no van {}

Code:
switch (lcd_key)               // depending on which button was pushed, we perform an action
 {
   case btnRIGHT:
     lcd.print("RIGHT ");
     break;
   case btnLEFT:
     //lcd.setCursor(7,0);  
     //lcd.print("LEER   ");
     leer();
     break;
 ................
sigue el siguiente case-break sin {}

probá a ver porque simular tu código es dificil por el modem

Corregir esto en
String ReadFile2(int Linea,char Recib[]){

Code:
myFile2 = SD.open(Recib);;

Quitar un ;
« Last Edit: September 17, 2014, 10:26:53 pm by surbyte » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gracias por tu ayuda. Al final he conseguido que funcione el sistema de selección por botones junto al de detección de la llamada (es decir el conjunto de lecturas de distintos ficheros y la botonadura). Mi código está escrito para usar modem que tengan Caller ID, y para eso envía los comandos Hates del inicio, estos comandos difieren para cada modem, así que quizás el tuyo necesite un comando Hayes diferente para funcionar. De todas formas estoy observando que el sistema de lectura y escritura de la SD, junto con el uso de la botonadura y la escritura en el LCD hacen que Arduino no sea fluido y se cometan errores que hacen fracasar las actividades que ordena el sketch. No entiendo por ejemplo que el copiar y pegar un código exactamente igual procedente de una versión del sketch anterior a una reciente, pueda solucionar problemas de funcionamiento del programa, como realmente ocurre.
De todas maneras ahora estoy nuevamente atascado. El sistema graba perfectamente los números de las llamadas recibidas que no están incluídos en el fichero de números bloqueados. Pero no consigo hacer que funcione el sistema de escritura en el fichero de números bloqueados,  estos son previamente leídos del fichero de llamadas recibidas y seleccionados con la botonadura para grabarse, pero no se graban, aun mas si intento leerlos o  grabarlos, el sistema de bloqueo por detección del número llamante no funciona, es decir no es capaz de leer de la SD el fichero de números bloqueados. Esta situación no se revierte hasta que no se recarga el programa, ni abrir terminal para que se reinicie ni apagar y encender, sirven.
Logged

Pages: [1]   Go Up
Jump to: