Si dice che durante la notte di Halloween gli spiriti comunichino con il mondo dei vivi… Perché allora non costruire una sorta di Tavola Ouija con la quale stupire ed inquietare i vostri ospiti?? Saranno sufficienti pochi LED e una scheda Arduino UNO e sarete pronti a ricevere messaggi… dall’aldilà!

Cosa occorre

Note per la realizzazione del progetto

Per utilizzare il minor numero possibile di pin di I/O, è stato ideato una schema elettrico 5×5 per il funzionamento dei LED relativi alle lettere dalla A alla Y, mentre la lettera Z avrà il proprio pin. Come mostra lo schema sotto riportato, ogni LED è identificato da un pin di riga ed un pin di colonna; per accendere quindi uno specifico LED, bisogna impostare come HIGH il pin di riga e come LOW il pin di colonna. Ad esempio, per accendere la lettera A, il pin 2 dovrà essere settato su HIGH ed il pin 8 su LOW; questa operazione accenderà quindi solo la lettera A.
Tavola_help-me_schema-elettrico
Ogni combinazione con una riga impostata su HIGH e le altre righe su LOW ed una colonna impostata su LOW e le altre colonne impostate su HIGH accenderà un solo LED alla volta. In questo modo si utilizzeranno 11 pin di I/O per accendere o spegnere tutte le 26 lettere dell’alfabeto, occupando di fatto molti meno pin rispetto al caso in cui si utilizzi un pin di I/O per ogni LED.
Il prossimo passo è determinare il valore delle 6 resistenze (R1-R6) da inserire in ogni colonna. I LED che si utilizzeranno avranno in generale caratteristiche differenti in termini di colore e caduta di tensione. Proponiamo quindi di identificare un valore di resistenza che permetta di rimanere nei limiti di un corretto funzionamento, indipendentemente dai LED utilizzati.
In linea di principio, la caduta di tensione di un LED generico appartiene al range 1.5V~3.5V; possiamo quindi utilizzare resistenze da 250Ohms, in modo tale che l’assorbimento di corrente non superi il limite massimo di 20mA che una scheda Arduino UNO R3 può fornire.
Con questo valore di resistenza si avrà un assorbimento di corrente nel range 14mA~6mA dato dai seguenti calcoli: (5V-1.5V)/250Ohms=14mA e (5V-3.5V/250Ohms=6mA.
In questo modo, la luce emessa dai LED risulterà per alcuni più luminosa e per altri più soffusa, ma questo contribuirà all’atmosfera spettrale necessaria per questo progetto!

Passo 1

Una volta ideato il circuito, è necessario scrivere sulla tavola di compensato tutte le lettere dell’alfabeto utilizzando un pennarello indelebile nero. Fate una prova preliminare su un pezzo di carta di uguali dimensioni per essere sicuri di distribuire in maniera corretta tutte le lettere.
Tavola_help-me_1

Passo 2

Con un trapano praticate sulla tavola i buchi che ospiteranno i LED, uno sotto ogni lettera che avete precedentemente scritto. Fate attenzione alla giusta misura dei buchi: i LED dovranno entrare senza difficoltà.
Tavola_help-me_2

Passo 3

Una volta praticati i buchi, inserite i LED; posizionateli scegliendo a caso la disposizione dei colori ma collocandoli nella stessa direzione di polarità. In questo specifico progetto, i LED sono stati posizionati con il piedino più lungo sulla sinistra; questo per facilitare il collegamento secondo lo schema elettrico precedentemente ideato.
Tavola_help-me_3

Passo 4

E’ ora il momento della saldatura; rovesciate la tavola di compensato facendo attenzione a non far cadere i LED e a non danneggiarli, aiutandovi ad esempio con un’altra tavola da appoggiare alla prima nel momento in cui viene rivoltata.
Tavola_help-me_4Tavola_help-me_5

Passo 5

Aggiungete adesso la vostra scheda Arduino UNO R3 alimentata da una batteria da 9V e collegate il pattern di LED ai corretti pin Arduino. Utilizzate anche del nastro isolante per fissare il progetto ed evitare cortocircuiti, come nell’esempio riportato nell’immagine.
Tavola_help-me_6Tavola_help-me_7

Passo 6

Cominciate a scrivere il codice; è possibile testare il circuito e il collegamento tramite la funzione digitalWire() ed impostando con valore LOW tutte le righe tranne una e poi impostare tutte le colonne tranne una con valore HIGH; vi assicurerete così che a seconda della combinazione impostata si accenderà il corrispondente LED.
Per facilitare la programmazione, invece della fuzione digitalWrite(), si potrà utilizzare direttamente la micro libreria Atmega per accendere e spegnere i LED andando a settare tutti i pin della PORTD e PORTB.
La PORTD controlla i pin digitali di I/O da 0 a 7, mentre la PORTB controlla i pin da 8 a 13; ad esempio, se si vuole accendere il pin 7 e spegnere tutti gli altri pin sarà necessario impostare PORTD a 10000000. Per cominciare, verrà creata una struttura per definire ogni configurazione PORT per ogni lettera. La struttura si chiamerà letter_data_t:

#include
typedef struct // Create a structure to convert Binary of the PORTs for the corresponding Letter
{
  byte portd;
  byte portb;
}letter_data_t;

Dopo verrà creata la disposizione della tavola definendo ogni lettera come una porta, basandosi sullo schema elettrico 5×5 creato. Questo sarà il letter[]array.

const letter_data_t letter[] =
{
  {B00000100,B11111110}, //A
  {B00000100,B11111101}, //B
  {B00000100,B11111011}, //C
  {B00000100,B11110111}, //D
  {B00000100,B11101111}, //E
  {B00001000,B11111110}, //F
  {B00001000,B11111101}, //G
  {B00001000,B11111011}, //H
  {B00001000,B11110111}, //I
  {B00001000,B11101111}, //J
  {B00010000,B11111110}, //K
  {B00010000,B11111101}, //L
  {B00010000,B11111011}, //M
  {B00010000,B11110111}, //N
  {B00010000,B11101111}, //O
  {B00100000,B11111110}, //P
  {B00100000,B11111101}, //Q
  {B00100000,B11111011}, //R
  {B00100000,B11110111}, //S
  {B00100000,B11101111}, //T
  {B01000000,B11111110}, //U
  {B01000000,B11111101}, //V
  {B01000000,B11111011}, //W
  {B01000000,B11110111}, //X
  {B01000000,B11101111}, //Y
  {B10000000,B11111111}, //Z
  {B00000000,B00000000}  //26 = 0ff
};

Ora la tavola è stata definita riferendosi al pin di output per ogni lettera, utilizzando la struttura precedentemente creata.
Dopodichè, si passa alla sezione setup del codice; ogni pin necessita di essere impostato come un’uscita:

void setup() {
  // Setup each pin used as an output 
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(12,OUTPUT);
}

Ora che la funzione Setup è stata scritta e la struttura della tavola creata, verrano impostate alcune funzioni. La funzione principale di questo programma è la runHelpme(); questa funzione permetterà di accendere i LED sulla tavola in sequenza fino a formare le parole H-E-L-P M-E… che altro non è che il nostro obiettivo: dimostrare ai nostri ospiti che qualcuno dall’aldilà sta cercando di comunicare con noi…

void runHelpme()
{
  PORTD = letter['h'-'a'].portd;
  PORTB = letter['h'-'a'].portb;
  delay(1000);
  PORTD = letter['e'-'a'].portd;
  PORTB = letter['e'-'a'].portb;
  delay(1000);
  PORTD = letter['l'-'a'].portd;
  PORTB = letter['l'-'a'].portb;
  delay(1000);
  PORTD = letter['p'-'a'].portd;
  PORTB = letter['p'-'a'].portb;
  delay(1000);
  PORTD = letter[26].portd;
  PORTB = letter[26].portb;
  delay(1000);
  PORTD = letter['m'-'a'].portd;
  PORTB = letter['m'-'a'].portb;
  delay(1000);
  PORTD = letter['e'-'a'].portd;
  PORTB = letter['e'-'a'].portb;
  delay(1000);
  PORTD = letter[26].portd; //Turn off the LEDs
  PORTB = letter[26].portb; //Turn off the LEDs
  delay(1000);
  }

Il codice sopra riportato permetterà di utilizzare le lettere che vogliamo, tranne la “A”, prima lettera dell’alfabeto, impostando il numero corrispondente alla lettera scelta, secondo lo schema della tavola. Dopo questa impostazione, è necessario impostare un delay prima di far accendere la lettera successiva.
Il prossimo passaggio imposterà alcune funzioni “flair” per rendere la tavola Ouija un po’ più misteriosa. La prima funzione flair sarà runRandom() che farà accendere 15 lettere a caso: per 16 volte si sceglie un valore X a caso fra 0 e 25 che identificherà una delle 26 lettere della tavola, si accenderà quindi il relativo LED e poi si attenderà per 3 volte un ritardo con valore random compreso tra 40mS e 200 mS.

void runRandom()
{
  for(int i = 0; <=15; i++)
  {
    int x = random(0,25);
    PORTD = letter[x].portd;
    PORTB = letter[x].portb;
    delay(random(40,200));
    delay(random(40,200));
    delay(random(40,200));
  }
}

La prossima funzione è la flickerRandom() che farà tremolare per 6 volte un LED a caso con intervalli di accensione e spegnimento variabili in un range compreso tra 40mS e 500mS: questo darà un tocco ancora più strano alla vostra tavola Ouija!

void flickerRandom()
{
  int x = random(0,25);
  for(int i = 0; <=5; i++)
  {
    PORTD = letter[x].portd;
    PORTB = letter[x].portb;
    delay(random(40,500));
    PORTD = letter[26].portd;
    PORTB = letter[26].portb;
    delay(random(40,500));
  }
}

Ora che tutte le funzioni sono state scritte, è tempo di assemblare il codice: per prima partirà la funzione Flicker, seguirà un delay di 2 secondi, poi verrà visualizzata la frase “Help me”, ancora un’attesa di 2 secondi, di nuovo partirà la funzione Flicker per 2 volte, infine si avvierà la funzione Random:

void loop() {
  flickerRandom();
  delay(2000);
  runHelpme();
  delay(2000);
  flickerRandom();
  flickerRandom();
  runRandom();
}

Documentazione