MCP3301: ADC esterno a 13 bit con interfaccia SPI

Devo collegare ed utilizzare l'ADC MCP3301.
L'ADC utilizza l'interfaccia SPI, che sembra semplice da utilizzare.

Però mi sfuggono alcune cose:
1.per quanto riguarda la configurazione
SPI.setClockDivider
SPI.setDataMode
SPI.setBitOrder()

quale sono i valori ottimali e/o esatti da utilizzare ?

Sto utilizzando il codice seguente per acquisire i valori, però non riesco a capire se funziona correttamente.

Come faccio a verificare ?

// inslude the SPI library:
#include <SPI.h>

define CS 10 // Pin Selezione

//# define MOSI 11 // MOSI

define MISO 12 // MISO

define SCLK 13 // CLOCK

#define FASTADC 1
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

long readvalue0;

void setup()
{
// Set pin modalità
pinMode (CS, OUTPUT);
//pinMode (MOSI, OUTPUT);
pinMode (MISO, INPUT);
pinMode (SCLK, OUTPUT);

// Disabilitare il dispositivo per iniziare
digitalWrite (CS, HIGH);
//digitalWrite (MOSI, LOW);
digitalWrite (SCLK, LOW);

Serial.begin (115200);

//SPI.setClockDivider (SPI_CLOCK_DIV2);
//SPI.setClockDivider (SPI_CLOCK_DIV4);
//SPI.setClockDivider (SPI_CLOCK_DIV8);
//SPI.setClockDivider (SPI_CLOCK_DIV16);
//SPI.setClockDivider (SPI_CLOCK_DIV32);
//SPI.setClockDivider (SPI_CLOCK_DIV64);
SPI.setClockDivider (SPI_CLOCK_DIV128);

SPI.setDataMode (SPI_MODE0);
//SPI.setDataMode (SPI_MODE1);

//SPI.setBitOrder (MSBFIRST);
//SPI.setBitOrder (LSBFIRST);
}

void loop ()
{
long t0=micros();
for(int k=0; k<500; k++)
{
readvalue0 = read_adcSlow ();
Serial.println (readvalue0, DEC);
}
}

int read_adcSlow ()
{
long avg = 0; int value=0;
for (int k=0; k<16; k++)
{
//Select adc
digitalWrite (CS, LOW); //pull CS low to enable

//cycle clock twice, ignore two null bits

digitalWrite (SCLK, HIGH);
digitalWrite (SCLK, LOW);
digitalWrite (SCLK, HIGH);
digitalWrite (SCLK, LOW);

// Legge i bit di adc
for (int i=11; i>=0; i--)
{
//value += digitalRead (MISO) << i;
value += (bitRead(PINB, 4) << i);
//cycle clock
digitalWrite (SCLK, HIGH);
digitalWrite (SCLK, LOW);
}
avg=avg+value;
digitalWrite (CS, HIGH);
//delayMicroseconds (10);
}
avg=avg/4;
return avg;
}

Praticamente

for (int i=11; i>=0; i--)

:roll_eyes: ma non era a 13 bit l'adc?

si infatti è un 13 bit, o meglio un 12 bit più segno.
quindi ?
Nel datasheet c'è: null,null,sb,b11,b10,b9.....b0

ma con 'sb' si stabilisce il segno ?

comunque il metodo di lettura è corretto ?

Sempre sull'MCP3301. Sul datasheet è riportato:

For the MCP330X devices, the recommended minimum clockspeed during the conversion cycle (tCONV) is 85 kHz.
Failure to meet this criteria may introduce linearity errors into the conversion outside the rated specifications.
It should be noted that, during the entire conversion cycle, the A/D converter does not have requirements for clock speed or duty cycle as long as
all timing specifications are met.

Considerando che per ogni acquisizione sono necessari 16 clock. Gli 85 KHz sono facilmente raggiungibili. Basta fare un oversampling di 16 ed acquisire almeno a 332 Hz. Mentre se gli 85 K sono campioni, significa che l'ADC non è utilizzabile, con l'ARDUINO ???.

Vorrei utilizzare la funzione
SPI.transfer(0) in questo modo:

digitalWrite(10, LOW);
highByte = SPI.transfer(0x00); //XXXSVVVV -> XXX bit nulli, S segno, V bit significativi.
lowByte = SPI.transfer(0x00); //VVVVVVVV
digitalWrite(10, HIGH);

per leggere i valori dell'ADC. Però i primi tre bit da sinistra di highByte sono nulli o non significativi.

Come faccio a comporre il valore, escludendo i tre bit nulli e considerando che il 4° bit da sinistra fornisce il segno.

grazie.