Buongiorno a tutti. Sto cercando di realizzare un sistema per il controllo accessi con Arduino e una tastiera/ lettore RFID 125 mhz con interfaccia wiegand. La tastiera passa l'imput a Arduino che invia una richiesta http get con il codice a una pagina web che restituisce 0 (non autorizzato) o 1 (autorizzato). Ma questa è un'altra storia.
Sto utilizzando questa libreria
https://github.com/monkeyboard/Wiegand-Protocol-Library-for-Arduino
La tastiera è collegata ai pin di arduino (D0 - PIN2 , D1 - PIN3). Oltre alla tastiera c'è 1 led rgb, una scheda relè per l'elettroserratura e la ethernet shield tutto originale.
Il tutto funziona bene in test da settimane. Ho però un problema che si verifica saltuariamente (1 lettura-o massimo 2 consecutive ogni 30/50 come ordine di grandezza - per questo non mi riesce facile replicarlo e diagnosticarlo) e in maniera assolutamente random e non riesco a venirne a capo.
Praticamente Leggo il tag, Arduino riceve i dati (ho messo un led che mi segnala quando l'ingresso D0 va in stato basso per vedere se arduino ricevevea o era un problema di tastiera) e li si ferma.
In poche parole
if(wg.available()) {
non diventa vero.
Avete idea del motivo?
Vi lascio il codice.
Grazie
#include <String.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Wiegand.h>
WIEGAND wg;
//ETHERNET CONFIG
byte mac[] = {0xA8, 0x61, 0x0A, 0xAE, 0x87, 0x52}; //+++++++ MAC_ADDRESS ++++++
IPAddress dnServer(8, 8, 8, 8); //+++++++ DNS_SERVER +++++++
IPAddress gateway(10, 0, 1, 254); //+++++++ GATEWAY ++++++++++
IPAddress subnet(255, 255, 255, 0);
IPAddress ip(10, 0, 1, 119); //+++++++ IP_ADDRESS +++++++
// initialize the library instance:
EthernetServer server(80); //server port
EthernetClient client;
byte HOST_IP [ ] = { 10 , 0 , 1 , 53 } ; //; //+++++++ IP_SERVER +++++++
String PATH_NAME = "/accessi/verifica.php"; //+++++++ URL +++++++++++++
String queryString = "?code="; //+++++++ QUERY_STRING ++++
String queryString2 = "&porta=";
//PIN CONFIG
#define PIN_LED_GREEN 8
#define PIN_LED_RED 9
#define PIN_LED_BLUE 5
#define PIN_RELE_LED 6
#define PIN_RELE_SERRATURA 7
//FUNZIONI CONFIG
#define NUMERO_PORTA 2 //++++++++ NUMERO PORTA ASSOCIATA A DB +++++++++++
#define TEMPO_APERTURA 5000 //++++++++ TEMPO APERTURA ELETTROSERRATURA +++++++
#define EMERGENCY_CODE "99999999" //++++++++ CODICE DI EMERGENZA SEMPRE VALIDO CHE BYPASSA DB +++++++
String codice;
long digit;
char verifica;
String readString; //string
int stato_led_green;
unsigned long timer_led_green;
int stato_led_red;
unsigned long timer_led_red;
int stato_led_blue;
unsigned long timer_led_blue;
int stato_rele_led;
unsigned long timer_rele_led;
int stato_rele_serratura;
unsigned long timer_rele_serratura;
unsigned long timer_codice;
//******FUNZIONE CHE STABILISCE AZIONI APERTURA PORTA IN BASE A ESITO (Passare l'esito ricevuto da webserver)
// 1=OK 2=ERRORE CONNESSIONE 3=NON_AUTORIZZATO
void apriporta (char esito) {
if(esito == '1') {
stato_led_green = 1;
timer_led_green = millis();
stato_rele_serratura = 1;
timer_rele_serratura = millis();
delay(400);
stato_rele_led = 1;
timer_rele_led = millis();
} else if (esito == '2') {
stato_led_green = 1;
timer_led_green = millis();
stato_led_red = 1;
timer_led_red = millis();
} else {
stato_led_red = 1;
timer_led_red = millis();
}
}
//********FINE FUNZIONE AZIONI
//********FUNZIONE CHE VERIFICA SU DB TRAMITE RICHIESTA HTTP ESITO AUTORIZZAZIONE
char verificadb(String codicedaverificare, char tipocodice){
//------------------VERIFICA ETHERNET
verifica='N';
// connect to web server on port 80:
if(client.connect(HOST_IP, 80)) {
delay(100);
// if connected:
Serial.println("Connesso al server");
// make a HTTP request:
// send HTTP header
client.println("GET " + PATH_NAME + queryString + codicedaverificare + queryString2 + NUMERO_PORTA + "&tipocode=" + tipocodice + " HTTP/1.0");
//client.println("Host: " + String(HOST_IP));
Serial.println("GET " + PATH_NAME + queryString + codicedaverificare + queryString2 + NUMERO_PORTA + "&tipocode=" + tipocodice + " HTTP/1.0");
client.println("Connection: close");
client.println(); // end HTTP header
char risposta;
while(client.connected()) {
if(client.available()){
// read an incoming byte from the server and print it to serial monitor:
risposta = client.read();
//Serial.print(risposta); //stampa tutta la risposta del server
}
}
return(char)risposta; // ritorna la risposta a 1 carattere
// the server's disconnected, stop the client:
client.stop();
} else {// if not connected:
Serial.print("connection failed errore: ");
Serial.println(client.connect(HOST_IP, 80));
apriporta('2');
}
//------------------FINE VERIFICA ETHERNET
}
// ********** FINE FUNZIONE VERIFICA DB
void setup() {
SPI.begin();
stato_led_green = 0;
timer_led_green = 0;
stato_led_red = 0;
timer_led_red = 0;
stato_led_blue = 0;
timer_led_blue = 0;
stato_rele_led = 0;
timer_rele_led = 0;
stato_rele_serratura = 0;
timer_rele_serratura = 0;
Serial.begin(9600);
Ethernet.begin(mac, ip, dnServer, gateway, subnet);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
delay(5000);
Serial.print(" assigned IP ");
Serial.println(Ethernet.localIP());
// default Wiegand Pin 2 and Pin 3 see image on README.md
// for non UNO board, use wg.begin(pinD0, pinD1) where pinD0 and pinD1
// are the pins connected to D0 and D1 of wiegand reader respectively.
wg.begin();
pinMode(PIN_LED_GREEN, OUTPUT);
pinMode(PIN_LED_RED, OUTPUT);
pinMode(PIN_LED_BLUE, OUTPUT);
pinMode(PIN_RELE_LED, OUTPUT); // rele led
pinMode(PIN_RELE_SERRATURA, OUTPUT); // rele porta
pinMode(4, OUTPUT);
digitalWrite(PIN_RELE_LED, HIGH);
digitalWrite(PIN_RELE_SERRATURA, HIGH);
digitalWrite(4, HIGH);
}
void loop() {
//solo per verifica se riceve segnali SUI PIN WG
if (digitalRead(2) == LOW) {
stato_led_blue = 1;
timer_led_blue = millis();
}
////////////////////////////
/*Client ----- apre porta da web*/
EthernetClient client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
readString.concat(c); //storages each character of the packet
//if HTTP request has ended
if (c == '\n' && currentLineIsBlank) {
Serial.print(readString);
if(readString.indexOf("A=1") > 0) {// Reads the information for the led to turn on
apriporta('1');
Serial.print("Apro serratura da web");
}
// Web page:
client.println("HTTP/1.1 200 OK.....");
client.println("Content-Type: text/html");
client.println();
client.print("<html><head><title>Controllo Serratura</title><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' ></head><body>");
client.println("<h1>CONTROLLO ACCESSI</h1>");
client.println("<hr />");
client.print("<h1>Porta n. ");
client.print(NUMERO_PORTA);
client.println("</h1>");
client.println("<br />");
client.print("<h2><a href='/?A=1'>APRI PORTA</a></h2>");
client.println("<hr />");
client.println("<hr />");
client.println("</div>");
client.println("</body></html>");
readString="";
client.stop();
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
// TIMER VARI ---------------------------------
// GREEN
if(stato_led_green == 1) {
digitalWrite(PIN_LED_GREEN, HIGH);
if(millis() - timer_led_green > 3000) {
stato_led_green = 0;
digitalWrite(PIN_LED_GREEN, LOW);
timer_led_green = 0;
}
}
// RED
if(stato_led_red == 1) {
digitalWrite(PIN_LED_RED, HIGH);
if(millis() - timer_led_red > 3000) {
stato_led_red = 0;
digitalWrite(PIN_LED_RED, LOW);
timer_led_red = 0;
}
}
// BLUE
if(stato_led_blue == 1) {
digitalWrite(PIN_LED_BLUE, HIGH);
if(millis() - timer_led_blue > 3000) {
stato_led_blue = 0;
digitalWrite(PIN_LED_BLUE, LOW);
timer_led_blue = 0;
}
}
// RELE SERRATURA
if(stato_rele_serratura == 1) {
digitalWrite(PIN_RELE_SERRATURA, LOW);
if(millis() - timer_rele_serratura > TEMPO_APERTURA) {
stato_rele_serratura = 0;
digitalWrite(PIN_RELE_SERRATURA, HIGH);
timer_rele_serratura = 0;
}
}
// LED TASTIERINO
if(stato_rele_led == 1) {
digitalWrite(PIN_RELE_LED, LOW);
if(millis() - timer_rele_led > 500) {
stato_rele_led = 0;
digitalWrite(PIN_RELE_LED, HIGH);
timer_rele_led = 0;
}
}
// TIMER CODICE NON DIGITATO RESET A VUOTO
if(codice != "") {
/////////////////////
if(millis() - timer_codice > 5000) {
codice = "";
timer_codice = 0;
Serial.println("reset timer codice");
}
}
// TIMER VARI ---------------------------------
if(wg.available())
{
digit = wg.getCode();
// devo capire se il codice è intero o digitato singolarmente
Serial.println(digit);
digitalWrite(PIN_LED_GREEN, HIGH);
delay(20);
digitalWrite(PIN_LED_GREEN, LOW);
//Serial.print(", Type W");
//Serial.println(wg.getWiegandType());
if(digit > 100) { //SE > 100 non è un codice ma è un badge
codice = digit;
//############### ATTIVITA DI VERIFICA CON BADGE ##############################
Serial.print("BADGE = ");
Serial.println(codice); //codice completato da poter verificare da badge
verifica = (verificadb(codice, 'B'));
apriporta(verifica);
Serial.print("Risposta dal server: ");
Serial.println(verifica);
//FINE ATTIVITA DI VERIFICA
//RESET CODICE A VUOTO PER LA PROSSIMA VERIDFICA
codice = "";
} else {
//quando leggo il carattere # (13) chiudo il codice e faccio la verifica
if(digit != 13) {
codice += digit; //compongo il codice fino a quando non trovo carattere 13
timer_codice = millis();
} else {
//################ ATTIVITA DI VERIFICA CON CODICE ##############################
Serial.print("codice finale = ");
Serial.println(codice); //codice completato da poter verificare
//se il codice corrisponde a EMERGENCY_CODE Bypasso DB e fornisco subito consenso apertura
if (codice == EMERGENCY_CODE) {
Serial.println("emergency_code");
apriporta('1'); // esito 1 = apri la porta
} else {
verifica = (verificadb(codice, 'C'));
apriporta(verifica);
Serial.print("Risposta dal server: ");
Serial.println(verifica);
}
//RESET CODICE A VUOTO PER LA PROSSIMA VERIDFICA
codice = "";
}
}
}
}