Nov 282014
 

In questo articolo volevo mostrarvi come far lavorare insieme il modulo ethernet SPI visto nel precedente articolo, ed il modulo radio 2.4GHz nrf24, anch’esso visto in questo articolo e in questo progetto. Volevo riprendere quest’ultimo; in relatà non doveva esserci nulla di nuovo, si doveva trattare unicamente di sostituire la shield ethernet ufficiale con il modulo più economico così da mostrare come far lavorare insieme due periferiche SPI già testate separatemente. Come vedremo, però, ci sono state delle sorprese inattese che hanno trasformato il senso di questo articolo.

L’interfaccia SPI

Prima di procedere ripassiamo per l’ennesima volta la piedinatura dell’interfaccia SPI che come sappiamo è differente in tutte le schede Arduino a meno di utilizzare il connettore ICSP. Qui sotto vi riporto la solita tabellina, lo so che vi uscirà dalle orecchie, ma è comodo avere tutti i dati che ci servono nella stessa pagina.

Arduino Board MOSI MISO SCK SS (slave) SS (master)
Uno / Duemilanove / Pro / Nano / Fio 11 or ICSP-4 12 or ICSP-1 13 or ICSP-3 10
Mega1280 or Mega2560 51 or ICSP-4 50 or ICSP-1 52 or ICSP-3 53
Leonardo / Micro / YUN ICSP-4 ICSP-1 ICSP-3
Due ICSP-4 ICSP-1 ICSP-3 4, 10, 52
Mini 11 12 13

I due moduli

Vi propongo qui sotto uno schemino riassuntivo dei due moduli che andremo a collegare insieme per rendere più semplice e rapido il cablaggio. Lo schema in questo caso è orientato guardando i pin di fronte esattamente come nella foto.

moduliSPI pinout_moduli

Colleghiamo  tutto ad Arduino UNO

Guardando gli schemi qui sopra il collegamento con Arduino è quasi banale. Per facilitare le cose ho usato gli stessi colori di sopra così non dovete far altro che seguirli per fare i relativi collegamenti. Cose degne di nota sono la diversa alimentazione a 3.3 e 5V dei due moduli ed il fatto che i pin dell’interfaccia SPI sono ovviamente in comune. Si noti che il color violetto l’ho usato per entrambi i CSS per far comprendere che si tratta di quel tipo di pin ma ovviamente devono essere fisicamente separati motivo per cui nell’immagine ne vedete due. arduinoUNOcComunque ho mantenuto il pin 10 per il modulo ethernet come con la ethernet shield ufficiale, mentre ho usato il 7 per il modulo nrf24l01. I pin verde, giallo e azzurro sono quelli del bus SPI e non possono essere modificati, tutti gli altri sono modificabili via software a nostro piacimento. Ovviamente avrei potuto collegare i pin del bus SPI sul connettore ICSP, non sarebbe cambiano nulla.

Pronti .. via

Di fatto in questa puntata, rispetto al precedente articolo, non facciamo altro che sostituire la classica shield ethernet con il modulo più piccolo ed economico, peraltro entrambe con lo stesso chip w5100 per cui non dovrebbe esserci alcun problema…non dobbiamo far altro che i collegamenti e tutto dovrebbe funzionare. Ho cominciato cautamente, collegando dapprima il solo modulo radio che funzionava correttamente, poi il modulo ethernet da solo anch’esso  funzionante. Bene, non resta che mettere tutto insieme e….ooops: non funziona!

I cavi sono integri e lo so perchè i moduli separati funzionano, il software l’abbiamo testato la scorsa volta per cui non ha motivo di non funzionare, cosa c’è che non va? Non voglio tediarvi con le decine di ore perse a cercare di capire dov’era il problema e che in parte è la causa del prolungato silenzio su questo blog :-). Alla fine delle indagini vengo a scoprire che il w5100 ha un bug nella gestione dell’interfaccia SPI. Sinora abbiamo spiegato a grosse linee come funziona l’interfaccia SPI ma abbiamo trascurato alcuni dettagli sinora inutili, che aggiungevano complessità senza alcun beneficio pratico, ma facciamo una riflessione. Sappiamo che più slave possono essere collegati sullo stesso bus SPI. Mettiamo che uno non sia in quel momento selezionato per cui sulla linea MISO (quella che dal dispositivo va verso Arduino) mantenga un valore LOW mentre un secondo dispositivo in un certo momento mantiene un valore HIGH in quanto stà trasmettendo dei dati. Ci troviamo due segnali che si “scontrano” portando ad ottenere un valore finale che non è significativo ai fini della trasmissione dei dati. Per questo motivo oltre agli stati LOW e HIGH esiste un terzo stato (three state) detto “ad alta impedenza” in cui la linea MISO passa appunto ad un valore di alta impedenza che di fatto equivale ad escludere quel dispositivo dal bus, è quasi come se venisse fisicamente staccato dal resto dei dispositivi. E qui c’è proprio il problema del W5100, ossia quando la linea SS è HIGH che dovrebbe disattivare il dispositivo, la linea MISO non passa allo stato ad alta impedenza per cui di fatto blocca tutte le trasmissioni sul bus. Ma allora perchè l’ethernet shield funziona se ha lo stesso chip? La mia è una R3 (terza revisione), e fra tutti gli aggiornamenti fatti c’è anche la soluzione a questo problema, se invece avete una vecchia versione aspettatevi qualche problema anche con quella. Di fatto la shield ufficiale utilizza un altro pin del w5100, il SEN che permette di attivare / disattivare tutta l’interfaccia SPI. Di fatto il “work-aroud” fa si che se lo stato di SS è alto, ossia deve entrare nello stato ad alta impedenza, porta basso il pin SEN (SPI Enable) disabilitando l’interfaccia SPI ed ottenendo di fatto il risultato voluto. Ottimo per chi progetta queste schede, ma noi cosa possiamo fare?

Soluzioni?

La prima soluzione praticabile consisterebbe nel copiare quella addottata nell’ethernet shield ufficiale o quella di alcuni cloni come quella della freetronics, il che consisterebbe nell’inserire un invertitore di segnale fra il pin SS ed il SEN, ma il lavoro risulterebbe sicuramente difficile visto che parliamo di saldature davvero molto piccole, inoltre non abbiamo uno spazio fisico dove posizionare il chip aggiuntivo, dovremmo provvedere con qualcosa di artigianale come ad esempio un alloggiamento in silicone. Qui sotto vi allego un’immagine con la soluzione dell’ethernet shield a sinistra, quella della shield freetronics in mezzo e per finire quella problematica del nostro modulo che di fatto sul pin SEN presenta solamente un resistore da 10K connesso alla linea 3.3V. Ho cerchiato in blu le parti interessate, la porta NOT a destra, il mosfet in mezzo ed il semplice resistore sul nostro modulo, fonte di tutti i miei problemi.

 schemi ethernetLa seconda soluzione sarebbe invece esterna alla scheda e prevederebbe di agire sulla linea MISO rendendola “ad alta impedenza” quando la linea SS è bassa andando di fatto ad eliminare il vero problema anzichè aggirarlo. Questa soluzione avrebbe un vantaggio, ossia il tipo di soluzione sarebbe in grado di funzionare anche con ulteriori eventuali schede con il medesimo difetto, senza dover effettuare nessuna modifica sulla scheda vera e propria.  Esistono chip appositi per questo lavoro, nel caso specifico un “single inverting buffer”, ma non ne ho mai usati per cui non ne ho in casa. A questo punto mi sono chiesto se le mie conoscenze di elettronica fossero sufficienti per una soluzione “fai da te” con i comuni componenti che ogni appassionato ha già in casa. Se leggete questo articolo significa che ci sono riuscito e vi assicuro che è stata una gran soddisfazione, se non altro perchè non ho trovato nulla di simile in rete. Forse si potrebbero utilizzare altre strade o semplificare ulteriormente quel che vi propongo, ma intanto vediamo cosa ho fatto. La mia idea prevede l’uso di due transistors BJT e di 5 resistori. Guardiamo insieme lo schema qui sotto:

 schema

Non spaventatevi, sembra tanto complesso ma sono solo due transistors NPN e 5 resistori. Partendo dalla sinistra troviamo due generatori di tensione. V1 serve a simulare un segnale MISO costantemente HIGH (5V) mentre V2 genera un’onda che varia da 0 a 5V per simulare il segnale SS. In realtà quest’ultimo è un segnale digitale per cui dovrebbe essere meglio rappresentato da un’onda quadra, ho invece  usato un’onda sinusoidale solamente perchè il grafico che segue più sotto era meglio leggibile. Di fatto questi due generatori corrispondono ai pin MISO ed SS del nostro modulo ethernet. Sempre a sinistra troviamo un primo transistor BJT NPN (Q1) ai cui tre capi sono collegati altrettanti resistori.

Se il segnale SS è LOW, alla base di Q1 non arriva nessuna tensione per cui il transistor è interdetto e fra collettore (R3-Q1) ed emettitore (Q1-R4) non passa nulla. Se a questo punto misuriamo la tensione fra il resistore R3 ed il diodo Q1 troveremo i 5V del segnale MISO che, come detto, ho rappresentato con il generatore V1. Questo punto R3Q1 rappresenta perciò la nostra uscita dal primo transistor. Vi faccio notare una cosa, il segnale SS è LOW ed il segnale in uscita e HIGH per cui abbiamo già ottenuto l’inversione di segnale. Ora se alziamo il segnale SS il transistor Q1 entra in conduzione e la corrente fluisce fra collettore ed emettitore  per cui la tensione al nodo R3-Q1 si riduce a circa 0.35-0.45V, sufficientemente basso da risultare “LOW” (per essere considerato low il segnale deve stare sotto gli 0.5V). L’unico problema non del tutto risolto è che l’uscita non è completamente scollegata dall’ingresso MISO, c’è infatti solamente un resisistore da 10k (R3) che potrebbe anche funzionare ma non rappresenta una soluzione ottimale. Potremmo aggiungere all’uscita un secondo resistore (R1), soluzione a cui avevo inizialmente pensato, ma ho preferito aggiungere un secondo transistor che di fatto serve solo a generare l’alta impedenza che cercavamo di ottenere quando SS è HIGH. Per farlo usiamo il nodo R3Q1 per comandare un secondo BJT Q2 attraverso il resistore R1. Quest’ultimo l’avevo messo nell’ottica di non usare il secondo transistor, poi l’ho lasciato come protezione della base ma in realtà essendoci già R3 a monte potete anche toglierlo senza modificare in nessun modo il funzionamento del circuito. Il resistore R5 crea una resistenza che impedisce alla corrente di fluire rapidamente verso massa quando Q2 è in conduzione, permettendo di “leggere il segnale” all’uscita MISO_OUT. Credo sia chiaro, comunque meglio ripetere, che il punto MISO_ETH deve essere collegato al pin MISO del modulo ethernet, mentre MISO_OUT deve essere collegato ad Arduino e, nell’esempio di questo articolo, anche all’uscita MISO del modulo nrf24.

tracciati_bjt_not_gate

Nella simulazione qui sopra possiamo apprezzaere 3 diverse tracce colorate. La traccia verde rappresenta il segnale SS (generatore V2) e come dicevamo ho usato un’onda sinusoidale anzichè quadra solamente per rendere il grafico meglio leggibile. Vediamo che l’onda passa repentinamente fra i +5V e 0V simulando gli stati di HIGH e LOW. In grigio è rappresentata la tensione al nodo R3Q1, ossia l’uscita dal primo transistor. Ciò che si nota è che quando SS (verde) è a livello LOW, l’uscita del primo transistor è a livello HIGH e viceversa. Si nota però che il livello LOW non corrisponde allo zero assoluto ma vi è una leggera fluttuazione fra 0.35 e 0.45V. L’uscita dal secondo BJT (rosso – MISO_OUT) annulla questo problema anche se porta ad una riduzione del picco a circa 4.2V (anzichè 5), comunque abbondantemente sopra la soglia minima  (2.7V) per essere considerato un valore HIGH.

Qui sotto vi riporto una foto del sistema funzionante:

eth_nrf_misohack circuito_miso_threestate
schema_carta_miso_threestate

Nell’immagine in alto a sinistra vedete il progetto nel suo complesso con Arduino connesso al modulo ethernet e al nrf24. C’è inoltre una breadboard che potete vedere nel dettaglio della seconda foto, in cui c’è il circuito descritto in questi ultimi paragrafi, con i due transistors ed i 5 resistori. Come vedete c’è più confusione fra cavi e cavetti che reale complessità. Se fosse tutto montato su un circuito definitivo si traterebbe di pochi componenti in un angolino sperduto.  La terza foto è il progettino che avevo disegnato su carta prima di fare le simulazioni e procedere con il cablaggio. Ques’ultima foto mi da lo spunto per un’ultima considerazione che dovrebbe essere scontata ma meglio chiarire. Ovviamente la linea SS che arriva da Arduino oltre ad andare sul modulo nrf24, andà sia al circuito che abbiamo creato sia alla scheda ethernet come originariamente predisposto.

Ora non dovete far altro che programmare il software delle vostre creazioni, se volete potete prendere spunto o copiare integralmente il progetto della scorsa volta, in tal caso vi ricordo che è necessaria una seconda scheda con display, sensore di temperatura DS18B20 e secondo modulo nrf24. Io ho usato quel progetto ed attualmente da circa 24 ore il sistema sta raccogliendo i dati sulla temperatura che sono raggiungibili qui, si noti che per ora è solo un test per cui dopo le prove del caso rimuoverò il sistema e la pagina potrà non essere aggiornata. Ora testerò l’affidabilità del modulo ethernet in prova, se ricordate uno dei motivi che mi hanno spinto a provarlo, oltre al costo minore, è la scarsa affidabilità nel tempo della ethernet shield ufficiale che in maniera del tutto casuale dopo tempi variabili si blocca impedendo l’invio di nuovi dati. Su questo mudulo c’è anche un pin di reset per cui se il sistema si dimostrasse poco affidabile come l’ethernet shield ufficiale, provvederò a sfruttare questo pin per effettuare il reset della scheda quando questa smette di funzionare correttamente, in questo modo dovrei ottenere un sistema estremamente affidabile senza bisogno di continua assistenza “manuale”.

Spero che abbiate apprezzato questo articolo perchè dietro ci sono decine e decine di ore perse a scoprire dove si celava il problema e poi a trovare una soluzione per risolverl. Se non avete capito nulla ma avete lo stesso problema incontrato in questo articolo non dovete far altro che copiare, prendete lo schema e fare i collegamenti senza porvi troppe domande ed il tutto funzionerà quasi come un miracolo.