Lug 012013
 

Del bus 1-wire abbiamo parlato in modo esteso in precedenti articoli, abbiamo visto in modo molto dettagliato come funzionano i segnali che transitano sul bus e abbiamo visto come usare i sensori DS18B20 sia con Arduino che via RS232 da PC. Se non conoscete i prodotti iButton della Maxim, diciamo subito che sono una famiglia di prodotti funzionanti con il bus 1-Wire e che hanno vagamente la forma esteriore simile a quello delle classiche “batterie a bottone”. C’è un’intera schiera di prodotti, si và da sensori di temperatura ed umidità a memorie, orologi, eprom, switch e quant’altro. Quelle che andiamo a studiare oggi sono le chiavi iButton. Potremmo definirle come delle chiavi elettroniche che quando sono appoggiate all’apposito lettore permettono di scambiare con esso il loro numero di serie a 64bit. Alcune hanno anche una memoria aggiuntiva o altre funzioni, ma ci limiteremo alla funzionalità più basilare che è appunto quella del riconoscimento della chiave.

Nella foto qui sopra potete vedere il mio set di 10 chiavi con due lettori (in inglese le trovate come “probe” – sonda). Esistono anche lettori con led integrati per la visione notturna, anche con la possibilità di cambiare colore attraverso il nostro circuito di controllo. Il collegamento elettrico del lettore rispecchia quello degli altri dispositivi 1-Wire, ci sono solamente due cavetti, uno rosso ed uno nero, ed è sufficiente una sola resistenza da 4.7K per collegarla al nostro Arduino nello stesso modo visto nel caso di alimentazione passiva del DS18B20.

Una volta preparato il circuito di prova possiamo passare alla componente software che in gran parte ricalca quanto già visto nei precedenti articoli. In particolare se ci soffermiamo alla parte di software che ricerca i dispositivi 1-wire sul bus, abbiamo di fatto già finito il lavoro. Ma attenzione. Se collegate il lettore ad Arduino e ricercate dispositivi 1-wire sul bus non avrete nessuna risposta. La risposta, la ottenete solamente se vi collegate la rispettiva chiave, infatti il codice identificativo a 64bit và ad identificare la chiave e NON la sonda di lettura. In questo modo basta eseguire un loop continuo che ricerca dispositivi 1wire sul bus e, non appena viene poggiata la chiave sul lettore, avremmo in risposta il codice della chiave letta. L’unica avvertenza è che l’indirizzo di queste chiavi comincia con un 0x01 (identificativo della famiglia di dispositivi) a differenza dello 0x28 dei sensori di temperatura precedentemente studiati.

#include <OneWire.h>

unsigned char G_addr[10][8]; //qui memorizzo fino a 10 indirizzi da 8 bytes (64bit)
byte G_Devices; // variabile usata per tenere traccia del numero di sensori riconosciuti nel bus
OneWire ow(8); // inizializza il bus onewire sulla porta n°8 (se avete collegato i sensori su un'altro pin dovete modificare qui)

void PrintAddress(byte *);
void lookUpSensors();
int CheckSensor(byte *);

void setup(void)
{
 Serial.begin(9600);// inizializza la porta seriale a 9600 bsaud
 G_Devices=0;      // imposta a 0 il numero di sensori attualmente riconosciuti
 lookUpKeys();     // avvia la ricerca delle sonde di lettura
 pinMode(13, OUTPUT);  // imposta il pin 13 come output (per usare il led interno come segnalatore)
}

void lookUpKeys()
{
byte address[8]; // questo array conterrà l'indirizzo locale delle chiavi

while (ow.search(address)) // loop finchè trova nuovi dispositivi
{
 if (address[0] == 0x01) // identificata chiave 1-wire
 {
  if(CheckSensor(address)==1) //se il crc ok la lettura è corretta
  {
   bool old=false;
   for (int i=0;i<G_Devices;i++) if(CheckAddress(G_addr[i],address)) {old=true;break;} // se trovo l'indirizzo imposto old a true ed esco dal for
   if(!old) // se la chiave non è ancora stata usata....
   {
    for(int aa=0;aa<8;aa++) G_addr[G_Devices][aa]=address[aa]; // copia l'indirizzo
    G_Devices++; // incrementa il numero di devices memorizzati
    Serial.println(""); // torno a capo sul terminale.
    PrintAddress(address); // stampo l'indirizzo della chiave
   }
  digitalWrite(13, HIGH);   // accende il led sulla porta 13
  delay(10);               // aspetta un po'...
  digitalWrite(13, LOW);    //..e spegne di nuovo il led sulla porta 13

  }
}

}//end while (ricerca nuovi dispositivi)

}

bool CheckAddress(unsigned char *a,unsigned char *b) // controlla se un indirizzo è già memorizzato
{
 bool ck=true;
 for(int i=0;i<8;i++) if(*(a+i)!=*(b+i)) return(false);
 return(true);
}

void loop(void) // corpo principale del programma
{
  lookUpKeys(); // loop principale...ricercachiavi continuamente
  delay(5); 
}

void PrintAddress(byte * address)  // stampa l'indirizzo esadecimale della sonda
{
 int i;
 for (i=0;i<8;i++)
 {
  if (address[i] < 9) Serial.print("0");
  Serial.print(address[i],HEX);
  if (i<7) Serial.print("-");
 }
}

int CheckSensor(byte * address) // verifica se la chiave è stata letta correttamente
{
 if (OneWire::crc8(address, 7) != *(address+7)) return(-1);// faccio il controllo del CRC8, se fallito ritorno -1
 else return(1); // cr8 OK, ritorno 1
}

Anzichè creare un listato minimale come faccio di solito, ho aggiunto qualche funzione in più che potrebbe essere utile nell’utilizzo pratico delle chiavi. Il software memorizza fino a 10 indirizzi di chiavi diverse. Se è la prima volta che utilizzate una certa chiave il software scriverà a terminale il corrispondente indirizzo esadecimale a 64bit (utile per debug), se invece non è il primo utilizzo si limita a far lampeggiare per un istante il LED sulla porta 13. Il listato è stato ampiamente commentato per cui non dovrebbero esserci problemi nella sua comprensione.

Chiaramente un sistema simile impiegato per far lampeggiare un LED non serve a nulla. Che applicazioni possiamo sviluppare con questo tipo di circuito? In realtà tantissime, in tutti i casi in cui vogliamo sostituire una chiave tradizionale o ci interessa un sistema di attivazione / disattivazione sicuro. Ad esempio potremmo usare delle serrature elettriche nelle porte di casa ed usare una chiave unica per aprirle tutte o fornire alcuni accessi ad una chiave, altri ad altre. Potremmo usare le chiavi per attivare e disattivare un sistema d’allarme o il sistema di condizionamento, di riscaldamente, per aprire il portone del garage, abbassare le tende solari o quel che vi viene in mente. Ad esempio tutti i casi in cui abbiamo un tastierino numerico per inserire un codice, possiamo facilmente sostituire o aggiungere questo tipo di dispositivo. Possiamo anche pensare a cosa più stravaganti come ad esempio il login di un PC o l’avvio di funzioni software quali l’avvio di un backup, tanto per dirne una o fare in modo che un datalogger invii i suoi dati via internet al riconoscimento di una specifica chiave. Come vedete le applicazioni sono molteplici.