Scacchiera con sensori hall AH1751 + shift register 74HC595

Buongiorno a tutti!
Questo è il mio primo post qui.
Di scacchiere con sensori Hall si è già parlato infinite volte, ma non ho trovato soluzione al mio problema.

Circuito
Ho realizzato il circuito come da schema allegato:

  • uno shift register 74HC595 alimenta una per una le righe di sensori
  • una volta alimentata ogni riga, "scansiono" colonna per colonna per vedere dove è presente un magnete

Codice
Sempre in allegato l'estratto del codice:

  1. tolgo l'alimentazione a tutte le righe e aspetto blank_time
  2. alimento la riga 0 e attendo activate_time
  3. scansiono le colonne da 0 a 7 (corrispondenti agli input da 5 a 12) attendendo read_time tra una e l'altra
  4. passo alla riga successiva

Test
Se io provo il circuito in condizioni statiche, senza utilizzare il 74HC595 (per esempio alimentando direttamente da Arduino la riga 0 e lasciando le altre righe spente) tutto funziona: avvicino un magnete e Arduino legge il segnale corretto.

Se invece utilizzo lo shift register, il sistema va in tilt e alcuni sensori (solo alcuni, circa una decina) restituiscono valori in cambiamento quasi casuale.

Ho provato anche diversi delay per l'attivazione delle righe, fino anche a 5000 ms (in pratica, equivalente a spostare i cavi a mano), per vedere se il problema stava nel transitorio.

Poi, vedendo che la singola uscita del 74HC595 aveva una tensione di 3 V invece che 5 V, ho ipotizzato avesse problemi ad alimentare 8 sensori Hall contemporaneamente. Ho quindi inserito 8 transistor NPN pilotati dalle 8 uscite del 74HC595.

Alla fine però il problema si ripropone uguale.

Possibili cause valutate
a. sensori Hall difettosi. Ma nel funzionamento statico funzionano correttamente
b. transitori troppo veloci, e quindi tensioni che non si aggiornavano in modo sufficientemente veloce. Ma anche inserendo dei delay il problema si ripresenta.
c. Assorbimento di 8 sensori troppo elevato. Ma neanche i transitor hanno risolto.

Quale potrebbe essere il problema? Cosa mi consigliate di provare per individuarlo e risolverlo?
Grazie!

Schema scacchiera.pdf (75.1 KB)

Codice scacchiera.pdf (22.9 KB)

Scacchi o dama ? ...

Se scacchi, come distingui i pezzi ? ... se dama, come distingui i colori ? ...

Nè l'uno, nè l'altro.
A me basta individuare la posizione di 8 magneti su una griglia 8x8.

ayeye80:
Buongiorno a tutti!
Questo è il mio primo post qui.

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento se non lo hai già fatto: Regolamento
Qui una serie di link utili, non inerenti al tuo problema:

secondo http://www.diodes.com/_files/datasheets/AH1751.pdf le uscite sono dei open collector e percui serve su ciascun uscita una resistenza pullup.

i Diodi per l' uscita open collector sono messi al rovescio, per il fatto che togli l' alimentazione ai sensori sono messi giusti. Per questo lo schema cosí non funziona.

Ciao Uwe

Grazie Uwe.

La resistenza di pullup c'è: è la resistenza di 1 kOhm che collega il pin 3 al pin 1.

Proverò invece a modificare i diodi.

Il fatto è che il tutto funziona perfettamente quando alimento "a mano" le righe, collegandole direttamente al pin 5V, ma smette di funzionare quando per fare questa operazione uso il 74HC595.

Non ho però previsto un condensatore sull'alimentazione del 74HC595: potrebbe essere questa la causa?

ayeye80:
Grazie Uwe.

La resistenza di pullup c'è: è la resistenza di 1 kOhm che collega il pin 3 al pin 1.

è troppo microscopica per vederla. :wink: :wink: :wink:

il Tuo sketch:

const int blank_time = 500;
const int activate_time = 500;
const int read_time = 100;
// ARRAY DI BYTE DA INVIARE AL 74HC595 PER ALIMENTARE UNA RIGA ALLA VOLTA
const int dati[8] =
{B10000000,
B01000000,
B00100000,
B00010000,
B00001000,
B00000100,
B00000010,
B00000001};
// DEFINIZIONE DEI PIN DI INPUT PER LA LETTURA DELLE COLONNE
const int colonna[8] = {5, 6, 7, 8, 9, 10, 11, 12};
// ALIMENTO UNA RIGA ALLA VOLTA
for(i = 0; i < 8; i++)
{
// TOLGO ALIMENTAZIONE DA TUTTI I SENSORI
shiftOut(data_pin, clock_pin, LSBFIRST, B00000000);
latch();
delay(blank_time);
// ALIMENTO LA RIGA i
shiftOut(data_pin, clock_pin, LSBFIRST, dati[i]);
latch();
delay(activate_time);
// SCANSIONO COLONNA PER COLONNA
for(j = 0; j < 8; j++)
{
// SALVO LO STATO NELLA CASELLA (8*i + j)
stato[8 * i + j] = digitalRead(colonna[j]);
delay(read_time);
}
}
stato[8 * i + j]

dove i va da 0 a 7 e j va da 0 a 7

Dove hai definito la variabile stato? L' hai definito di 64 elementi?

Dacci lo sketch completo.

Ciao Uwe

Mi vengono in mente tre cose ...

Primo, li stai usando nel senso giusto ? (funzionano correttamente solo con il polo sud dal lato della sigla, oppure il nord dall'altro, secondo il datasheet)

Secondo, cosa succede ai segnali ed ai livelli delle uscite quando non sono alimentati ? (cioe', le uscite dei vari sensori, sono effettivamente "NC" (ad alta impedenza) quando il loro positivo e' scollegato, oppure in qualche modo interferiscono con la riga alimentata falsando la lettura ?

Terzo, qual'e' l'assorbimento in corrente di ogni riga quando e' alimentata ? (puo darsi che mi sbagli, ma mi sembra di ricordare che gli HC595 possano dare 8 o 10 mA al massimo come source, e non esattamente alla tensione di alimentazione, cioe' se alimentati a 5V l'uscita arrivava sui 4.5V o simili, o qualcosa del genere, e se l'assorbimento e' piu alto la tensione dovrebbe calare abbastanza)

uwefed:
i Diodi per l' uscita open collector sono messi al rovescio, per il fatto che togli l' alimentazione ai sensori sono messi giusti. Per questo lo schema cosí non funziona.

Ho sperimentato durante il weekend e i diodi sono giusti. Così funziona il singolo sensore Hall:

Sensore non attivato, contatto chiuso (cioè senza magnete vicino):

Sensore attivato, contatto aperto (cioè con magnete vicino):

Per evitare che un sensore vada in cortocircuito con gli altri collegati allo stesso input, va il diodo in quella direzione.

uwefed:
Dove hai definito la variabile stato? L' hai definito di 64 elementi?

Dacci lo sketch completo.

Quello allegato era solo un estratto. Ecco qui quello completo.

Etemenanki:
Primo, li stai usando nel senso giusto ? (funzionano correttamente solo con il polo sud dal lato della sigla, oppure il nord dall'altro, secondo il datasheet)

Si, ho segnato il polo sud sui magneti per essere sicuro di utilizzarli nel modo corretto. Ad ogni modo, il problema dei "falsi positivi" me lo da anche quando sulla scacchiera non c'è neanche un magnete.

Etemenanki:
Secondo, cosa succede ai segnali ed ai livelli delle uscite quando non sono alimentati ? (cioe', le uscite dei vari sensori, sono effettivamente "NC" (ad alta impedenza) quando il loro positivo e' scollegato, oppure in qualche modo interferiscono con la riga alimentata falsando la lettura ?

Ho tenuto questo punto per ultimo: per riuscire a risolvere ho ridotto il tutto ad una griglia 3x3 e invece che utilizzare il l'HC595 ho utilizzato 3 pin di Arduino come output per alimentare le 3 righe di sensori, e ho utilizzato 3 pin come input per leggere 3 colonne di sensori.

Misurando con un multimetro ho trovato che PRIMA dei diodi la tensione letta è corretta (0 V se non c'è il magnete, 5 V se c'è il magnete).
DOPO il diodo invece...leggo una tensione di circa 1 V! Da dove arriva?! Ho 9 sensori con 0 V all'uscita. Questi sono collegati ad un input (che non dovrebbe avere tensione) e mi ritrovo 1 V.
Il problema è che questa tensione "oscilla", ha dei picchi, e questi picchi mi danno delle false letture.

Tutto questo, ripeto, quando non c'è nessun magnete sulla griglia. Quando cioè nessun sensore è attivato.
Detto in modo diverso: il problema non è che se metto un magnete, il sistema non lo vede. Il problema è che il sistema vede magneti che non ci sono (false letture).

Codice griglia.pdf (26 KB)

Ma la scritta stampata sul sensore è rivolta verso la scacchiera ?

No, la scritta (che è sul lato "svasato") è rivolto opposto alla scacchiera. La si dovrebbe vedere nella foto, anche se a causa della luce non si legge.
Ma poi, dipende da come uno mette la scacchiera: da come vedi il pannello in foto, io devo avvicinare il polo sud al sensore.
Ovviamente se capovolgo il pannello e i magneti li metto dal lato opposto ai sensori, dovrò avvicinare il polo nord.

E funzionano, eh. I singoli sensori funzionano senza problemi:

  • nessun magnete, uscita 0 V
  • con magnete, uscita 5 V

E' quando collego le uscite in parallelo che ho problemi. O meglio, come scrivevo prima, se leggo le tensioni prima del diodo, sono corrette anche con le uscite collegate in parallelo.
Se leggo dopo il diodo, trovo 1 V di tensione, pur con tutte le uscite uguali a 0 V.

Strano, perché il datasheet dice questo

While the magnetic flux density (B) is larger than threshold Bop, the OUT pin turns on (low). If B removed toward Brp, the OUT pin is latched “on” state prior to B < Brp. When B < Brp, the OUT pin go into “off ” state.

Si, infatti. Quello che scrivi si capisce molto meglio dal diagramma:

Dice che, essendo un sensore "latched" non basta allontanare il polo sud perchè ritorni da on a off, ma bisogna avvicinare il polo nord.
Funziona così:

  1. sensore off
  2. avvicinano polo sud -> sensore on
  3. allontano polo sud -> sensore (ancora) on
  4. avvicinao polo nord -> sensore off

(Poi considera che "multiplexando" le alimentazioni, io non ho mai veramente bisogno di avvicinare il polo nord, perchè ogni volta che tolgo alimentazione, il sensore si riporta su off.)

Infatti è quello che fa, se prendo un sensore singolo.
Se prendo un sensore e ci aggiungo un diodo, ancora funziona così.
Se però prendo più sensori e collego le uscite in parallelo, "magicamente" a valle del diodo mi trovo una certa tensione.

Ricapitolando:

  • il singolo sensore funziona correttamente.
  • non ci sono dubbi sulla polarità del magnete (avvicino il sud alla scritta, o avvicino il nord al lato opposto alla scritta, e si attiva).
  • non ci sono dubbi sulla direzione del diodo
    Ma...
  • appena collego le uscite in parallelo (nell'ultimo caso a gruppi di tre) in qualche modo interferiscono e sfalsano la lettura

Bene, per informazione, ho trovato la soluzione.
Come spiegavo, il problema era una lettura falsata DOPO i diodi, di circa 1 V contro gli 0 V attesi:

Allora mi sono detto "Perchè non inserire una resistenza di pull-down, così da stabilizzare l'input di Arduino a 0 V?!".
L'unica accortenza, visto che con due resistenze in serie (quella di pull-up del sensore Hall e quella di pull-down dell'input di Arduino) andavo a creare un partitore di tensione, è stato scegliere come pull-down una resistenza abbastanza grande. 1 MOhm contro 10 kOhm.
A sinistra tutti contatti chiusi (=sensori non attivati), a destra un contatto aperto (=un sensore attivato):

Ieri ho provato fino ad una griglia 4x4 e tutto funziona perfettamente!