Help needed with a 4 differential channels simultaneous ADC MAX11040k.

I am dealing with a 4 differential channels simultaneous ADC called MAX11040k.
Here is its datasheet:
http://datasheets.maximintegrated.com/en/ds/MAX11040K-MAX11060.pdf

Each channel has 8 bits input control register and 24 bits output data register. (Shutdown, RST, etc..)
In total, sampling instant control register will be 32 bits and data register will be 96 bits.

My questions are:
How to send 32 bits control register through SPI? As SPI.transfer can only transfer 8 bits, right? Should I do SPI.transfer four times?
What's a proper way to select the three bytes from total 12 bytes?
What I am having with my code is 2.4999 which is not the input value for my channel 0.

Below is how I am doing currently for this device: the relative part

void setup()
{
byte command1 = B00100000;
byte command2 = B10000000;
 digitalWrite(ADCCS, LOW);
  SPI.transfer(command1);
  SPI.transfer(command2);
  SPI.transfer(command2);
  SPI.transfer(command2); 
  digitalWrite(ADCCS, HIGH);
}

long int ltw = 0; 
byte b0;  

void loop()
{

   if (digitalRead(MISO) == LOW) {   
   ltw=0;
   b0 = SPI_read();             // read 3 bytes for channel 0,
   ltw |= b0;
   ltw <<= 8;
   b0 = SPI_read();
   ltw |= b0;
   ltw <<= 8;
   b0 = SPI_read();
   ltw |= b0;
   
   b0 = SPI_read();        //reads the rest three three bytes but not going to use it.
   b0 = SPI_read();
   b0 = SPI_read();

   b0 = SPI_read();
   b0 = SPI_read();
   b0 = SPI_read();

   b0 = SPI_read();
   b0 = SPI_read();
   b0 = SPI_read();


   delayMicroseconds(1);

   digitalWrite(ADCCS, HIGH);      // 
   delay(2);
   volt = ltw * v_ref / 16777216; // max scale
}
}

Cheers,
Danny

ydy023:
How to send 32 bits control register through SPI? As SPI.transfer can only transfer 8 bits, right? Should I do SPI.transfer four times?

Yes. See Figure 7 (Read) and Figure 8 (Write).

32-bit Read:
Set SS LOW.
spi.transfer(address);
byte1 = spi.transfer(0);
byte2 = spi.tarnsfer(0);
byte3 = spi.transfer(0);
byte4 = spi.transfer(0);
Set SS HIGH.

32-bit Write:
Set SS LOW.
spi.transfer(address);
spi.transfer(byte1);
spi.tarnsfer(byte2);
spi.transfer(byte3);
spi.transfer(byte4);
Set SS HIGH.

Below is my current code; the output are basically 1 for all the bits for the four channels: 16777215 as it is 24 bits. But once in ten, the channel 0 will output another output which is 196608.
Does anyone know what the problem is based on this?
Is it the code problem or pin connections?

  digitalWrite(ADCCS, LOW);
  SPI.transfer(1100000);                  //configuration Address
  SPI.transfer(B00110000);
  digitalWrite(ADCCS, HIGH);

  digitalWrite(ADCCS, LOW);
   SPI.transfer(1110000);                   //Read Data Register address
   b0=SPI.transfer(0);                        // Get the fourth channel's output as the device is LSB
   ltw3 |= b0;
   b0=SPI.transfer(0);
   b0<<=8;
   ltw3 |= b0;
   b0=SPI.transfer(0);
   b0<<=16;
   ltw3 |= b0;   

   b0=SPI.transfer(0);                        //Get the third channel's output
   ltw2 |= b0;
   b0=SPI.transfer(0);
   b0<<=8;
   ltw2 |= b0;
   b0=SPI.transfer(0);
   b0<<=16;
   ltw2 |= b0;   
   
   b0=SPI.transfer(0);                              //Get the second channel's output
   ltw1 |= b0;
   b0=SPI.transfer(0);
   b0<<=8;
   ltw1 |= b0;
   b0=SPI.transfer(0);
   b0<<=16;
   ltw1 |= b0; 
   
   b0=SPI.transfer(0);                                 //Get the first channel's output
   ltw0 |= b0;
   b0=SPI.transfer(0);
   b0<<=8;
   ltw0 |= b0;
   b0=SPI.transfer(0);
   b0<<=16;
   ltw0 |= b0;  
  digitalWrite(ADCCS, HIGH);
  SPI.transfer(1100000);

The number One Million One Hundred Thousand (1,100,000) is too large to fit in a byte.

Perhaps you meant to use a binary constant: B1100000 or 0b1100000.

Thank you so much for your reply. I didn't notice that, yes, I meant binary.
I have just changed both of the addresses into B1100000 and tested. Unfortunately, it's still not working.
It outputs 1 for 96 bits.

The first channel is outputting proper values now, but the rest channels can only provide proper data once after press reset button. For the rest of time, they are not output correct values.

ydy023:
The first channel is outputting proper values now, but the rest channels can only provide proper data once after press reset button. For the rest of time, they are not output correct values.

You must have changed something to get it to work that well. If you share your code maybe someone can figure out what is wrong with the other three channels.

Saying "they are not output correct values" doesn't help with determining the problem. If you say what incorrect values you get, what correct value you expected, and why you expect that value, it will help us figure out what is wrong. This is particularly important when you are using hardware that few other people have handy.

Thank you very much for your reply and advise how should I clarify my problem.
What I have changed with the code is SPI.transfer(B11110000), it's a 8 bits address and the MSB bit standing for read/write was missing. And I also add B in front. And that's all I changed, the rest stay the same.
So I having four channels measuring voltage output from four sensors, the initial reading of each sensor should be around 0.2V. As you can see from below, I have four reading outputs which stands for channel 0, 1, 2 and 3. Although channel 0's output isn't perfect, but it is proper. The rest three channels only provide relative readings for the first line. From the second line, channel 0 is still working, but the rest three's output are messy.
If I totally get the output format or pin connection wrong, I would expect channel 1,2 and 3 give messy output all the time.
That's where confused me.

Initializing SD card...card initialized.
0; 0.150870; 0.112785; 0.135081; 0.109197;
1; 0.151399; -288.442047; -107.202698; 116.404190;
2; 0.151986; -297.857605; 283.584625; -135.159851;
3; 0.152523; 245.624756; 42.793106; -235.942108;
4; 0.151704; -16.571070; 9.021153; -302.546112;
5; 0.152074; 78.421471; -149.559601; 177.917648;
6; 0.150389; 229.529785; 61.874062; -149.107178;
7; 0.150661; -96.734581; -61.590305; 272.610779;
8; 0.169180; 242.635742; 97.962494; 220.121002;
9; 0.159351; -63.314262; 229.994568; 250.467819;
10; 0.151051; -243.444580; 283.574310; -61.728172;
11; 0.153606; 176.865540; 6.555233; 22.642891;
12; 0.152401; 19.677975; 163.873444; -235.473099;
13; 0.151857; 15.765853; -229.575500; -284.734955;
14; 0.156914; 271.065186; 299.680511; 89.685249;
15; 0.157774; 47.026169; 182.025681; -147.346024;
16; 0.155855; 306.850189; 274.865997; -149.066422;

Thank you again!

Did you remember to clear ltw1, ltw2, and ltw3 before ORing in the received bytes?

There must be calculations somewhere to convert the 24-bit binary value you get from the ADC into the floating-point value you display.

Perhaps you should show all of your code.

Thank you? I cannot believe I forgot to clear ltw1,2,3 before new action. I didn't notice this!
They are all working now. Thank you so much for your help.

Danny

Is it possible to see your final code. I have been asked to write the code using Cypress Psoc 5.

Thanks

Philip

Here is my final code using now.
Although all four channels are working now, but they have 0.04 V variation which is around 152520 out of 16777216 variation going on.
Regardless of sensors, even placing both AIN- and AIN+ with ground, the noise still existing. I have use decoupling capacitors and also a 2.5 voltage regulator as signal reference.
I know this is more about the entire circuit and device problem, but if anyone have any idea about what might cause this would be appreciate.
Here is the datasheet for this device ADC max11040k.
http://datasheets.maximintegrated.com/en/ds/MAX11040K-MAX11060.pdf

/*
 Pressure sensor system
 
 This system shows how to log data from a analog sensor and log 
 data into an SD card using the SD library.Also use an external 
 24 bits ADC
 	 
 created  20 June 2013
 by Danny	 
 */

#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal.h>


const int SDCS = 4;
const int ADCCS = 10;
double pressureValue0 = 0;
double pressureValue1 = 0;
double pressureValue2 = 0;
double pressureValue3 = 0;
const int fs=3;
LiquidCrystal lcd(12, 11, 6, 5, 3, 2);
byte command1 = B00110100;
byte command2 = B10000000;

void setup()
{
  pinMode(ADCCS, OUTPUT);
  pinMode(SDCS, OUTPUT);
  digitalWrite(ADCCS, HIGH);
  digitalWrite(SDCS, HIGH);
  SPI.begin();
  lcd.begin(16, 2);
  SPI.setBitOrder(MSBFIRST);

  digitalWrite(ADCCS, LOW);
  SPI.transfer(B01100000);     //address
  SPI.transfer(command1);
  digitalWrite(ADCCS, HIGH);

  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  Serial.print("Initializing SD card...");
  if (!SD.begin(SDCS)) {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("card initialized.");
}

float volt0;
float volt1;
float volt2;
float volt3;
float v_ref=2.48;          // Reference Voltage, 5.0 Volt for LT1021 or 3.0 for LP2950-3
long int ltw0 = 0;         // ADC Data ling int
long int ltw1 = 0;
long int ltw2 = 0;
long int ltw3 = 0;  
int cnt;                  // counter
byte b0;                  //
char st1[20];             // float voltage text

void loop()
{
  lcd.print("0:");
  lcd.setCursor(9, 0);
  lcd.print("1:");
  lcd.setCursor(0, 1);
  lcd.print("2:");
  lcd.setCursor(9, 1);
  lcd.print("3:");
    

  digitalWrite(ADCCS, LOW);
  if (digitalRead(MISO) == LOW) {   // ADC Converter ready ?
    ltw0=0;
    ltw1=0;
    ltw2=0;
    ltw3=0;
    SPI.transfer(B11110000);
    b0=SPI.transfer(0);
    ltw0 |= b0;
    ltw0 <<= 8;
    b0=SPI.transfer(0);
    ltw0 |= b0;
    ltw0 <<= 8;
    b0=SPI.transfer(0);
    ltw0 |= b0;   

    b0=SPI.transfer(0);
    ltw1 |= b0;
    ltw1 <<= 8;
    b0=SPI.transfer(0);
    ltw1 |= b0;
    ltw1 <<= 8;
    b0=SPI.transfer(0);
    ltw1 |= b0;   

    b0=SPI.transfer(0);
    ltw2 |= b0;
    ltw2 <<= 8;
    b0=SPI.transfer(0);
    ltw2 |= b0;
    ltw2 <<= 8;
    b0=SPI.transfer(0);
    ltw2 |= b0;   

    b0=SPI.transfer(0);
    ltw3 |= b0;
    ltw3 <<= 8;
    b0=SPI.transfer(0);
    ltw3 |= b0;
    ltw3 <<= 8;
    b0=SPI.transfer(0);
    ltw3 |= b0;   
    delayMicroseconds(1);

    digitalWrite(ADCCS, HIGH);      
    delayMicroseconds(1);

    volt0 = ltw0 * v_ref *0.88*2/ 16777216; 
    volt1 = ltw1 * v_ref*0.88*2 / 16777216; 
    volt2 = ltw2 * v_ref*0.88*2 / 16777216; 
    volt3 = ltw3 * v_ref*0.88*2/ 16777216; 
    pressureValue0=(volt0-0.205)/0.01845;
    pressureValue1=(volt1-0.205)/0.01845;
    pressureValue2=(volt2-0.205)/0.01845;
    pressureValue3=(volt3-0.205)/0.01845;
  }

  digitalWrite(ADCCS, HIGH);    
  digitalWrite(SDCS, LOW);

  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(pressureValue0);
    lcd.setCursor(2, 0);
    lcd.print(pressureValue0);
    lcd.setCursor(11, 0);
    lcd.print(pressureValue1);
    lcd.setCursor(2, 1);
    lcd.print(pressureValue2);
    lcd.setCursor(11, 1);
    lcd.print(pressureValue3);
    
    // print to the serial port too:
    Serial.print(cnt++);
    Serial.print(";  ");
    Serial.print(volt0,6);           // print voltage as floating number
    Serial.print("; ");
    Serial.print(volt1,6);
    Serial.print("; ");
    Serial.print(volt2,6);
    Serial.print("; ");
    Serial.print(volt3,6);
    Serial.print("; ");
  //  Serial.print(ltw0);
  //  Serial.print("; ");
    //Serial.print(pressureValue);  
    Serial.println("  ");    

    dataFile.close();
    delay(1000/fs);
    lcd.clear();
  }  
  else {
    Serial.println("error opening datalog.txt");
  } 
  digitalWrite(SDCS, HIGH);
}

byte SPI_read()
{
  return SPI.transfer(0x00);
}