Go Down

Topic: Arduino + RFID (SELECT) + MySQL (Sem PHP como intermediário) (Read 161 times) previous topic - next topic

MSMegaron

Olá a todos, estou com um projeto para a faculdade onde tenho que ler um cartão RFID e procurar se o código existe no banco de dados MySQL, como existe um conector do MySQL para Arduino (biblioteca MySQL criada pelo Dr. Charles A. Bell) então a ideia é fazer a conexão utilizando esse conector, ou seja, sem PHP.

Componentes utilizados:
  • Arduino Uno R3, mas será trocado para um Arduino Mega 2560 R3 caso o código funcione;
  • Shield Ethernet R3 5100;
  • SparkFun RFID USB Reader com RFID Reader ID-12LA (125 kHz).


O meu código funciona separadamente a conexão e busca no banco de dados e a leitura do cartão RFID, mas quando integro os dois, não consigo conectar no banco.

Código da Conexão e busca no banco (Funciona quando executado sozinho):
Code: [Select]
#include <Ethernet.h>
#include "MySQL_Connection.h"
#include "MySQL_Cursor.h"

byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server_addr(192, 168, 100, 3); // IP do servidor MySQL
char user[] = "projetobd";              // Usuario do MySQL
char password[] = "arduinobanco";        // Senha do usuario MySQL

// Codigo dos Cartões
String codigo1 = "0A005BB918F0"; // Simulando leitura do cartão RFID
char idCharCard[30]; // Variável que receberá o ID após a conversão para char

// Query SQl
char QUERY_POP[] = "SELECT codigo FROM catraca.cartao WHERE codigo = '%s';";
char query[128];
int num_cols;

EthernetClient client;
MySQL_Connection conn((Client *)&client);
MySQL_Cursor cur = MySQL_Cursor(&conn);

void setup() {
  Serial.begin(9600);
  Serial.println("Iniciando Shield Ethernet...");
  Ethernet.begin(mac_addr);
  Serial.println("Shield Ethernet Configurada!");
  Serial.println("Conectando ao Banco de Dados...");
  if (conn.connect(server_addr, 3306, user, password)) {
    delay(1000);

    codigo1.toCharArray(idCharCard, 30); // Conversão da ID de String para Char, pois sprintf aceita somente char

    delay(1000);
    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
    sprintf(query, QUERY_POP, idCharCard); // Formatação da query
    cur_mem->execute(query); // Executa a query
    column_names *cols = cur_mem->get_columns();
    num_cols = (cols->num_fields) - 1;
    row_values *row = NULL;

    row = cur_mem->get_next_row();
    if (row != NULL) { // Caso seja diferente de NULL, existe o código no banco
      String Texto = row->values[num_cols];
      Serial.println("Codigo existente");
    } else {
      Serial.println("Codigo inexistente");
    }
    delete cur_mem;
  }
  else
    Serial.println("Falha de Conexao.");
}

void loop() {

}


Saída no Monitor Serial para o Banco de dados:


Código de leitura do cartão RFID (Funciona quando executado sozinho):
Code: [Select]
#define FDL_CHAR 3
const int T_BUFFER = 20;
char bufferr[T_BUFFER + 1];

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    int tamanho = Mensagem(FDL_CHAR);
    String texto = bufferr;
    Serial.print("CARTAO Decodificado!. ID: " + texto);
  }
}

// Formatando o dado recebido para uma String
int Mensagem(char eol) {
  int soma = 0;
  char c = eol - 1;
  while (c != eol) {
    if (Serial.available()) {
      c = Serial.read();
      if ((c != 2) && (c != 13) && (c != 10)) { // Detecta STX, CR, LF
        bufferr[soma++] = c;
      }
    }
    if (soma >= T_BUFFER) {
      while (Serial.available()) {
        Serial.read(); // Flush
      }
      break;
    }
  }
  bufferr[T_BUFFER] = 0;
  if (soma < T_BUFFER) {
    bufferr[soma - 1] = 0;
  }
  return (soma - 1);
}


Saída no Monitor Serial para a leitura do RFID (Assim que é lido o cartão):


A ideia é: Ler o cartão e fazer a busca no banco para ver se existe o registro do código. Só que, quando rodo o software completo a conexão falha. Ele trava na linha 42 Serial.println("Conectando ao Banco de Dados...");  , ou seja, ele não chega a conectar o usuário no banco.

Código Completo (Não executa):
Code: [Select]
/*      Ethernet      */
#include <Ethernet.h>

EthernetClient client;

/*      MySQL      */
#include "MySQL_Connection.h"
#include "MySQL_Cursor.h"

byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server_addr(192, 168, 100, 3); // MySQL Server IP Address
//int port = 3306; // MySQL Server Port

char user[] = "projetobd"; // MySQL username login
char password[] = "arduinobanco"; // MySQL password login

char QUERY_CMD[] = "SELECT codigo FROM catraca.cartao WHERE codigo = '%s';";
char query[128];
char codigo1[] = "0A005BB918F0";

int num_cols;
int rows;

MySQL_Connection mysql_conn((Client *)&client);
MySQL_Cursor cur = MySQL_Cursor(&mysql_conn); // Create an instance of the cursor passing in the connection

/*     RFID     */
#define FDL_CHAR 3
const int T_BUFFER = 20;
char bufferr[T_BUFFER + 1];
//char cardId[32];
String cardId;
char idCharCard[12];
//const char id[] = "7F0045BA66E6";

void setup() {
  Serial.begin(9600);
  Serial.println("Inicializando Shield ETHERNET...");
  Ethernet.begin(mac_addr);
  Serial.println("Shield Ethernet inicializada!");
  Serial.println("Conectando ao Banco de Dados...");
  if (mysql_conn.connect(server_addr, 3306, user, password)) {
    delay(1000);

  } else {
    Serial.println("Falha de conexão ao Banco de Dados");
  }
}

void loop() {
  if (Serial.available()) {
    int tamanho = Mensagem(FDL_CHAR);
    cardId = bufferr;
    //strcpy(cardId, buffer);
    Serial.print("CARTAO Decodificado!. ID: ");
    Serial.print(cardId);


    if (cardId != NULL) {
      Serial.println("");
      Serial.println("Not NULL");
      CodeCheck(cardId);
    }
  }
}

/*      Functions      */

int Mensagem(char eol) {
  int soma = 0;
  char c = eol - 1;
  while (c != eol) {
    if (Serial.available()) {
      c = Serial.read();
      if ((c != 2) && (c != 13) && (c != 10)) { // Detecta STX, CR, LF
        bufferr[soma++] = c;
      }
    }
    if (soma >= T_BUFFER) {
      while (Serial.available()) {
        Serial.read(); // Flush
      }
      break;
    }
  }
  bufferr[T_BUFFER] = 0;
  if (soma < T_BUFFER) {
    bufferr[soma - 1] = 0;
  }
  return (soma - 1);
}

bool CodeCheck(String ID) {
  ID.toCharArray(idCharCard, 13); // Conversão da ID de String para Char, pois sprintf aceita somente char

  MySQL_Cursor *cur_mem = new MySQL_Cursor(&mysql_conn);
  sprintf(query, QUERY_CMD, idCharCard); // Formatação da query
  cur_mem->execute(query); // Executa a query
  column_names *cols = cur_mem->get_columns();
  num_cols = (cols->num_fields) - 1;
  row_values *row = NULL;

  row = cur_mem->get_next_row();
  if (row != NULL) { // Caso seja diferente de NULL, existe o código no banco
    String Texto = row->values[num_cols];
    Serial.println("Codigo existente");
  } else {
    Serial.println("Codigo inexistente");
  }
  delete cur_mem;
}


Saída no Monitor Serial para o Código Completo:


Já tentei utilizar o SoftwareSerial para separar as portas RX/TX colocando as portas 9 e 11 como Serial Virtual (RX/TX respectivamente) para o RFID, mas notei que quando declaro a SoftwareSerial o banco não conecta.

Gostaria que alguém analisasse e apontasse o meu erro.
Desde já, agradeço a colaboração.

bubulindo

Diria que a tua conclusão está errada...

Code: [Select]

  if (mysql_conn.connect(server_addr, 3306, user, password)) {
    Serial.println("estou aqui"); //coloca isto aqui...
    delay(1000);

  } else {
    Serial.println("Falha de conexão ao Banco de Dados");
  }

}


Se colocares o print como indicado em cima, ficas a saber se o arduino liga ao banco de dados ou não.

Outra coisa que pode estar a acontecer é o Arduino ficar sem memória... no entanto, isso costuma reiniciá-lo.

Diria também que perderes tempo a tentar perceber o que se passa com a porta série neste arduino quando um Mega tem 4 portas série de hardware é pouco eficiente.

Por último, já pensaste em conectar ao banco de dados quando alguém passar um cartão e não no início? Que acontece se perderes a ligação? Como é que o Arduino vai saber que perdeu a ligação ao banco e tentar ligar de novo?
This... is a hobby.

Go Up