E' possibile acquisire dati da in SPI in modo sincrono da diversi SLAVE?

Ciao a tutti,
proseguo con lo studio del protocollo SPI e mi è sorta una domanda:

Nel momento in cui tengo in comune MISO ed SCK, ed assegno un CS ad ogni slave,
posso leggere in modo sincrono i dati da tutti gli slave simultaneamente?

Teoricamente mi sembra di si ma qualcuno di voi lo ha già / mai fatto?

Ad ora leggo i dati tramite un ciclo for che seleziona il chip da leggere e restituisce il dato letto,
prima di passare a quello successivo.

In questo modo però ottengo un output "multiplexato" mentre mi piacerebbe avere la sincronia tra tutti i canali...

NO, il bus SPI può essere usato SOLO da uno slave per volta (quello a cui dai il consenso mettendo LOW il CS).

Dovresti avere N bus SPI, ma, anche così, comunque ne leggeresti uno alla volta (la MCU è una sola e se legge da uno, non legge da un altro).

Del resto, come potresti ricevere sullo stesso filo (MISO) i dati provenienti simultaneamente da più devices ? ? ? :o

Guglielmo

Quindi per avere la sincronia tra tutti i canali come bisogna procedere?

Qual’è diciamo la “strada giusta”?

Semplicemente NON la puoi avere ...
... o devi usare N schede Arduino, sincronizzate tra loro, in cui ciascuna, assieme a tutte le altre, legge il suo canale SPI.

Una MCU, processi sequenziali, più MCU, processi paralleli.

Ma ti rendi conto che il bus SPI viaggia nell ordine di Mbps? Parliamo tra una lettua e la successiva di microsecondi di differenza ... ha veramente questa necessità ? ::slight_smile:

Guglielmo

Adesso mi prendo delle bastonate...

Ma ti rendi conto che il bus SPI viaggia nell ordine di Mbps

Se così è non è un problema, la domanda sorgeva dal fatto che via monitor seriale, leggevo un massimo di 10 sequenze di valori ( a Serial Speed 115200 ).

Come faccio a calcolare la reale mole di dati che viene acquisita per secondo?
Per avere una sorta di frequenza di acquisizione di tutti i canali...

Hai studiato il reference della libreria SPI ? ? ? :o

Hai visto che c'è un oggetto che si chiama SPISettings ? ... prova a studiarlo ... ::slight_smile:

Guglielmo

Yes e proprio da qui che arriva il dubbio.
Se ho 10 dispositivi da cui leggo 32 bit da ciascuno, dopo quanto tempo ho acquisito tutti i dati?

Ripeto ... hai visto la SPISetting ? Li decidi a quanti Mbit/sec viaggia il bus ... ovviamnete con un clock a 16MHz NON puoi superare tale velocità ... ma non ti consiglio neanche di usarla ...

Mettiamo che fissi a 4 MHz (che credo di ricordare sia il valore di default e che già sono tanti ... considera che più veloce vai più corti debbono essere i collegamenti per non avere problemi), ogni bit impiega 250 nSec che moltiplicato per 32 bit da 8 µSec ... questo è il tempo per trasferire i dati di un dispositivo ... poi dipende dal tempo che perdi tra un trasferimento e l'altro ... se lo fai immediatamete saranno ancora poche altre decine di µSec quindi ... ::slight_smile:

Guglielmo

Queste sono le caratteristiche del modulo, il timing per la conversione di un valore di temperatura medio è di 70ms.

Quindi avrò su 10 dispositivi, 700 ms tra una lettura e la successiva?

NO, quello è il tempo che il modulo impiega a fare una conversione, uno, dieci, cento o mille, sempre 70 mSec. impiegherà a fare la conversione e tu NON li puoi interriogare più di una volta ogni X con X > 70 mSec.

Quindi, aspetti diciamo 100 mSec, in qualche centinaio di µSec. li leggi tutti e poi stai di nuovo fermo ad aspettare lo scadere dei 100 mSec per poter rieffettuare la lettura.

Guglielmo

Quindi praticamente ho una frequenza di campionamento di 100mSec. Corretto?

Creo un ciclo for per leggere i valori e lo chiudo.
Dopo di che ci piazzo un delay(100); e sono a posto corretto?

Ma che misuri a fare temperature così velocemente? Normalmente la variazione di temperatura è un processo lento ...

Guglielmo

gpb01:
Quindi, aspetti diciamo 100 mSec, in qualche centinaio di µSec. li leggi tutti e poi stai di nuovo fermo ad aspettare lo scadere dei 100 mSec per poter rieffettuare la lettura.

Guglielmo

oppure se ne hai tanti, ma veramente tanti....

il tempo che finisci di leggere l'ultimo il primo ha finito la conversione successiva, e ricominci le letture

ma così non avanzi tempo per:
"capire, trattare ed usare le letture, e poi fare quello che devi fare sapendo le temperature"

anzi temo che tutto questo ti porti via abbastanza tempo da non preoccuparti dei tempi di lettura

Grazie mille ad entrambi!

Una domanda veloce veloce, esiste qualche funzione, ad esempio della libreria math.h per fare la conversione di un numero decimale, anche negativo in esadecimale?

La domanda suppone che ci sia una differenza matematica tra numeri decimali, binari, esadecimali e ottali, ma questa differenza non c'è perché si tratta di rappresentare un numero attraverso una sequenza di caratteri che noi interpretiamo come esadecimali. All'interno di una memoria o cpu tutto è composto da collezioni di bit 10001101. Il computer e l'editor (incluso il compilatore) ci permette di specificare un numero nei formati prima elencati, ma questi sono sempre convertiti in binario.

Quindi pare ovvio che vuoi una rappresentazione esadecimale anziché decimale per poi mostrarla su un display. sul monitor seriale o in un file. Se è così devi guardare a Serial.print(10, HEX), vedi il reference.

Ciao.

Grazie @maurotec, ma per i numeri negativi come si procede?

Non esistono numeri negativi in binario, esadecimale e ottale. Esiste invece una codifica binaria in complemento a 2 per convertire un numero decimale in binario e viceversa. Vedi qui

Per i numeri in virgola mobile, es. float vedi qui

Se non è questo che ti interessa, spiega meglio qual'è il tuo obbiettivo/necessità.

Ciao.

In realtà è un mix di tutte queste cose.
Devo acquisire il valore di una termocoppia ( da - 270 a 1370 con una risoluzione di 0.25), come posso codificarlo in esadecimale?

da - 270 a 1370 con una risoluzione di 0.25

Si tratta quindi di un float perché c'è la virgola e allora IEEE754, ma non mi è ancora chiaro cosa vuoi fare.
Una volta trasformato in esa avrai una stringa di 8 caratteri nel caso di float, cosa ci devi fare con questa stringa.

Oppure puoi usare una union composta da float e uint32_t e visualizzi un bye per volta in esa.

Bo non so è una richiesta mai capitata prima.

Ciao.

Cerco di spiegarmi meglio e di dare più info possibile.

Sto cercando di prendere il valore restituito da un MAX31855, convertirlo in HEX su due byte, ed "incasellarlo" in un array, che diventerà un messaggio CAN spedito con un modulo MCP2515.

Il MAX31855 tira fuori i valori in MSB, con risoluzione di 0.25°C.
Vedi allegato "MAX31855".

Spero di essere stato chiaro, altrimenti sono a disposizione per ogni info che sia necessaria / dimenticata!

MAX31855.PNG