Les presento un prototipo que estoy probando muy basico pero funcional, lo que les permitirá a varios probar.
Explicacion del programa
Las llaves son fijas, alojadas en la memoria flash para ahorrar memoria ram.
Los defines es igual, ahorran mucho codigo
- El programa lee la tarjeta o llavero RFID, en este caso uso el ID20 de innovations que lo tenia guardado hace 2 años sin usar.
- Cuando lee una tarjeta valida activa la salida por el tiempo definido, a la vez que suena un buzzer.
- Si la tarjeta es invalida envia el codigo por Serial para poder copiarlo y anotarlo en el codigo.
- La busqueda es secuencial, pero hice la prueba con 100 registros y no hay demora.
- Tiene 2 modos de activacion, Magnetico o liberapestillo, si es magnetico se activa apenas se enciende y desactiva cuando el codigo es correcto.
- Tiene antipassing, que no deja que la misma tarjeta sea leida 2 veces almenos que pasen 10 segundos, tambien configurable.
- Tiene un boton de activacion manual para los casos en que se ingresa con llave y se puede salir sin llave.
- Uso el led de la salida 13 para un testigo de que el programa no se ha colgado, parpadeando indefinidamente
Lo dejé conectado 2 dias sin que se disparara ni colgara el programa, ahora en breve lo conecto a la realidad para ver como se comporta.
Haa notarán que no uso el loop(), pues por consejo de alguien que estudió mucho el ide asegura que el loop() solapa variables llevando a cuelques inesperados.
Espero sirva para alguien mas.
#include <Event.h>
#include <Timer.h>
#include <avr/pgmspace.h>
#define PINRESET 3
#define PINLED 13
#define PINRELE A1
#define PINSONIDO A2
#define PINBOTON A0
#define PINMODORELE 6
#define INTERVALO 100
#define NUM_TAGS 10
#define TIEMPORELE 3000
#define REPITETAG 10000
const char tag_0[] PROGMEM = "8500622A09"; //
const char tag_1[] PROGMEM = "850061E734"; //
const char tag_2[] PROGMEM = "85006268A9"; //
const char tag_3[] PROGMEM = "85005E1E15"; //
const char tag_4[] PROGMEM = "8500623EE1"; //
const char tag_5[] PROGMEM = "8500623428"; //
const char tag_6[] PROGMEM = "8500625FFE"; //
const char tag_7[] PROGMEM = "850066E458"; //
const char tag_8[] PROGMEM = "85006238DD"; //
const char tag_9[] PROGMEM = "8500620776"; //
const char* const tags_table[] PROGMEM =
{
tag_0,
tag_1,
tag_2,
tag_3,
tag_4,
tag_5,
tag_6,
tag_7,
tag_8,
tag_9,
};
Timer T;
char codeant[11]="0000000000";
boolean MODORELE=HIGH; //si es magnetico LOW si es libera pestillo HIGH
void setup()
{
Serial.begin(9600); // connect to the serial port
pinMode(PINRESET ,OUTPUT);
pinMode(PINRELE ,OUTPUT);
pinMode(PINSONIDO,OUTPUT);
pinMode(PINBOTON ,INPUT_PULLUP);
pinMode(PINMODORELE ,INPUT_PULLUP);
//configurar modo de activacion del rele
if (digitalRead(PINMODORELE)== false)
MODORELE=LOW; //si es magnetico LOW
else
MODORELE=HIGH; //si es libera pestillo HIGH
DesactivarRele(); //inicializo
T.oscillate(PINLED,500,HIGH); //parpadeo del led
ResetReader();
char xcode[11];
while (1)
{
if (LeerTarjetaID20(xcode))
{
if (strcmp(codeant,xcode)!=0) //es una tarjeta nueva
{
if (Existe_Tag(xcode))
Abrir();
else
SonidoError();
strcpy(codeant,xcode); //copiar la tarjeta leida
T.after(REPITETAG, LimpiarTarjeta);
//lanzar el borrado de tarjeta en 10 segundos
}
ResetReader();
Serial.println(xcode);
Serial.println();
Serial.flush();
}
if (!digitalRead(PINBOTON)) //se presionó el boton
{
while(!digitalRead(PINBOTON)) //mientras se mantenga el boton presionado esperar
T.update();
Abrir();
}
T.update();
}
}
void Abrir()
{
T.every(INTERVALO,SonidoAbre,((TIEMPORELE-INTERVALO)/INTERVALO)); //le resto INTERVALO para compensar el delay.
ActivarRele();//activamos rele manualmente
T.after(TIEMPORELE, DesactivarRele); //despues de transcurrido el tiempo lo desactivamos
}
void SonidoAbre()
{
tone(PINSONIDO,1000);
delay(50);
tone(PINSONIDO,1200);
delay(50);
noTone(PINSONIDO);
}
void LimpiarCodigo()
{
for(byte f=0;f<10;f++)
codeant[f]=0;
codeant[10]='\0';
}
boolean Existe_Tag(char codigo[])
{
char buffer[30];
for(int f=0;f<NUM_TAGS;f++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(tags_table[f])));
buffer[10]='\0';//agrego el fin de linea para que funcione la comparacion
if (strcmp(buffer,codigo)==0)
return true;
}
return false; //si recorrio todo el array y no la encontró devolver falso
}
void ParpadeaLed()
{
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(PINLED, ledState);
}
boolean LeerTarjetaID20(char pcode[])
{
byte i = 0;
byte val = 0;
byte code[16];
byte checksum = 0;
byte bytesread = 0;
byte tempbyte = 0;
if(Serial.available() > 0)
{
if((val = Serial.read()) == 2)
{ // check for header
bytesread = 0;
while (bytesread < 12)
{ // read 10 digit code + 2 digit checksum
if( Serial.available() > 0)
{
val = Serial.read();
if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02))
{ // if header or stop bytes before the 10 digit reading
break; // stop reading
}
code[bytesread]=val;
bytesread++;
}
}
// si se leyeron los 12 digitos pasarlos al paramero
if (bytesread == 12)
{
for (i=0; i<10; i++)
{
pcode[i]=code[i];
}
pcode[10]='\0';//agregar fin de linea
}
}
}
return bytesread == 12;
}
void ResetReader()
{
digitalWrite(PINRESET, LOW);
delay(10);
digitalWrite(PINRESET, HIGH);
}
void ActivarRele()
{
digitalWrite(PINRELE,MODORELE);
}
void DesactivarRele()
{
digitalWrite(PINRELE,!MODORELE);
}
void LimpiarTarjeta()
{
strcpy(codeant,"0000000000"+'\0');
}
void SonidoError()
{
for(byte f =0; f < 5; f++)
{
tone(PINSONIDO,800);
delay(100);
noTone(PINSONIDO);
}
noTone(PINSONIDO);
}
void loop ()
{
}