Realizzare un semplice apri porta utilizzando tag rfid

La realizzazione di sistemi basati sulla tecnologia rfid è oggi alla portata di tutti vista la disponibilità di componenti a basso costo necessaria alla produzione di un prodotto completo. Il prototipo che ho realizzato per questo articolo si basa principalmente su un Netduino, versione standard, e sul lettore rfid ID-12 della Innovations, utilizzato in un precedente articolo.

Lo scopo del progetto è quello di permettere l’accesso controllato in una particolare area utilizzando unicamente il Netduino per memorizzare una lista di utenti autorizzati. In caso di riconoscimento il circuito azionare un classico relè che potrebbe essere collegato ad un apri porta elettromeccanico tipico dei sistemi citofonici.

Il circuito è il seguente:

Per quanto riguarda il codice caricato sul Netduino osserviamo che i codici dei tag rfid sono memorizzati in un array di stringhe. Questi valori vengono confrontati con il codice ottenuto dal lettore ID-12 e quando si verifica un’uguaglianza viene attivato il relè che andrà a comandare l’apri porta.
Nel codice è presente anche il calcolo del crc che permette di ottenere una maggiore sicurezza nella lettura ed interpretazione del codice del tag.

public static Byte ConvHexToByte(String Value)
{
  if (Value.Length == 2)
  {
    String str1 = Value.Substring(0, 1);
    String str2 = Value.Substring(1, 1);

    if (str1.ToUpper() == "A")
      str1 = "10";

    if (str1.ToUpper() == "B")
      str1 = "11";

    if (str1.ToUpper() == "C")
      str1 = "12";

    if (str1.ToUpper() == "D")
      str1 = "13";

    if (str1.ToUpper() == "E")
      str1 = "14";

    if (str1.ToUpper() == "F")
      str1 = "15";

    //###########################
    if (str2.ToUpper() == "A")
      str2 = "10";

    if (str2.ToUpper() == "B")
      str2 = "11";

    if (str2.ToUpper() == "C")
      str2 = "12";

    if (str2.ToUpper() == "D")
      str2 = "13";

    if (str2.ToUpper() == "E")
      str2 = "14";

    if (str2.ToUpper() == "F")
      str2 = "15";

    //converto i singoli caratteri in valori byte
    Byte b1 = Byte.Parse(str1);
    Byte b2 = Byte.Parse(str2);
    //onverto i duebyte in un valore hex
    Byte cv = (Byte)(b1 * 16 + b2);

    //Debug.Print(cv.ToString());
    return cv;

  }

  return 0;

}

public static void Main()
{

  String[] Codice = { "06003906B1",
                      "060030EF42",
                      "060039EF42",
                      "060038EF42",
                      "060037EF42",
                      "060036EF42",
                      "060035EF42",
                      "060034EF42",
                      "060033EF42",
                      "060032EF42",
                      "060031EF42",
                      "060038EF02",
                      "060038EF92",
                      "060038EF82",
                      "060038EF72",
                    };

  //Creao un oggetto per lavorare con
  //la porta seriale
  SerialPort sp = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
  OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
  OutputPort Porta = new OutputPort(Pins.GPIO_PIN_D7, false);
  OutputPort LedAut = new OutputPort(Pins.GPIO_PIN_D8, false);
  OutputPort LedNoAut = new OutputPort(Pins.GPIO_PIN_D9, false);

  //Apro la porta
  sp.Open();

  while (true)
  {
    //Attesa di 200 millisecondi
    Thread.Sleep(200);

    //aspetto la lettura di tutti i 16 byte
    if (sp.BytesToRead == 16)
    {
      led.Write(true);
      //creo un buffer di 16 byte
      Byte[] b = new Byte[sp.BytesToRead];
      Byte[] crcTag = new Byte[2];
      Byte[] tag = new Byte[10];
      Byte Hex01, Hex02, Hex03, Hex04, Hex05, crcRfid, crc;

      //leggo dalla seriale i dati inviati dall'ID-12
      sp.Read(b, 0, b.Length);

      //copio i 10 byte dell'ID del tag in un array dedicato
      Array.Copy(b, 1, tag, 0, 10);
      Array.Copy(b, 11, crcTag, 0, 2);

      //converto i byte in una stringa ASCII
      String ValoriAsc = new String(UTF8Encoding.UTF8.GetChars(tag));
      String ValoreCrc = new String(UTF8Encoding.UTF8.GetChars(crcTag));

      //ottengo i valori esadecimali dalla coppia di byte Ascii
      Hex01 = ConvHexToByte(ValoriAsc.Substring(0, 2));
      Hex02 = ConvHexToByte(ValoriAsc.Substring(2, 2));
      Hex03 = ConvHexToByte(ValoriAsc.Substring(4, 2));
      Hex04 = ConvHexToByte(ValoriAsc.Substring(6, 2));
      Hex05 = ConvHexToByte(ValoriAsc.Substring(8, 2));
      crcRfid = ConvHexToByte(ValoreCrc.Substring(0, 2));

      //calcolo il crc mettendo in xor i valori hex
      crc = (byte)(Hex01 ^ Hex02 ^ Hex03 ^ Hex04 ^ Hex05);

      //printo il valore di crc
      Debug.Print(crcRfid.ToString());
      Debug.Print(crc.ToString());

      if (crcRfid == crc)
      {
        //eseguo un ciclo che mi printa tutti i singoli
        //byte del buffer
        Int32 strNumber;
        Int32 strIndex = 0;
        Boolean Acc = false;

        for (strNumber = 0; strNumber < Codice.Length; strNumber++)
        {
          strIndex = Codice[strNumber].IndexOf(ValoriAsc);
          if (strIndex >= 0)
          {
            Porta.Write(true);
            Thread.Sleep(100);
            Porta.Write(false);

            LedAut.Write(true);
            Thread.Sleep(200);
            LedAut.Write(false);

            Acc = true;

            break;

          }
        }

        if (Acc == false)
        {
          LedNoAut.Write(true);
          Thread.Sleep(200);
          LedNoAut.Write(false);
        }

      }
      Debug.Print(ValoriAsc);

      Thread.Sleep(150);
      led.Write(false);
    }
  }
}

Il codice per far funzionare il sistema è molto semplice. Con poco hardware è con una spesa inferiore ai 100€ possiamo costruire veramente prodotti basati su tecnologia rfid. Sostituendo il Netduino con il fratello maggiore (Netduino Plus) potremmo dotare il sistema di una memoria SD per il log degli accessi ed un webserver per leggere i file di log.