Data ADC 16bit Unreliable Where Is Wrong?

ive already made my arduino uno to read data adc 16 bit from max1416
http://datasheets.maxim-ic.com/en/ds/MAX1415-MAX1416.pdf
pin configuration

my code

#include "SPI.h"
 
int ss=10;
unsigned int adcValue;
byte highByte;
byte lowByte;
 
void setup(){
  pinMode(ss, OUTPUT);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  Serial.begin(9600);
}
void loop()
{
  //series of commandbit    
  digitalWrite(ss,LOW);
  SPI.transfer(0x20);//command for comm reg to select ch1 and write to clock register 
  SPI.transfer(0xA5);//command for clock reg to set 2,4576Mhz                                  
  SPI.transfer(0x10);//command for comm reg to write setup register                          
  SPI.transfer(0x44);//command for setup reg to self calibration,unipolar,unbuffered,    
  
  
 
  while(1)
  {
      char DataNotReady = 0x80;
      while(DataNotReady) // wait for end of conversion 
      {
          SPI.transfer(0x08);//command for comm reg to read  (dec   8)
          DataNotReady =SPI.transfer(0x00); // Read comm register
		  DataNotReady &= 0x80;
      }
      
      
      SPI.transfer(0x38);//command for the comm to read data register for channel 1 
      
	  //read 16bit of data ADC
      highByte = SPI.transfer(0x00);
      lowByte = SPI.transfer(0x00);
      
      adcValue = highByte << 8;
      adcValue = adcValue | lowByte;
      
      digitalWrite(ss,HIGH);
      Serial.print("analog value =");
      Serial.println(adcValue, DEC);
      Serial.print('\n');
      delay(1000);
  }
}

my problems is the reading of adc seems random and giving the floating number,
here is the reading when i connect ain+ to 5volt with reference 5volt,and i use 5volt pin in arduino

analog value =0

analog value =32896

analog value =0

analog value =32896

analog value =128

analog value =32896

analog value =0

analog value =32896

and these is the result when i connect the ain+ to GND

analog value =0

analog value =65471

analog value =16383

analog value =1926

analog value =7

analog value =34811

analog value =48591

analog value =4095

according to datasheet we have to read data when data is ready,it is acknowledged by pin 12,or MSB bit in communication register,so value 1 for data not ready,and 0 for data ready
but when i try to debug there,the data are never ready,it keep giving 1

i aware that the adc 16 bit have to be design well with separate analog and digital ground and etc to get precise value.but my point is i just want to developing at first level,like get values 65536 when measuring 5 volt (vref=5volt) and get zero when measuring 0 volt

where is exactly my problem?anyone?

Can you post a schematic of how you have wired it up.

here is my schematic,

i think the problems is in this code,

while(1)
  {
      char DataNotReady = 0x80;
      while(DataNotReady) // wait for end of conversion 
      {
          SPI.transfer(0x08);//command for comm reg to read  (dec   8)
          DataNotReady =SPI.transfer(0x00); // Read comm register
		  DataNotReady &= 0x80;
      }
      
      
      SPI.transfer(0x38);//command for the comm to read data register for channel 1 
      
	  //read 16bit of data ADC
      highByte = SPI.transfer(0x00);
      lowByte = SPI.transfer(0x00);
      
      adcValue = highByte << 8;
      adcValue = adcValue | lowByte;
      
      digitalWrite(ss,HIGH);

am i doing the reading of register correctly?because from the data output we see 32896 which is in binary 1000000010000000.
we know that 10000000 is the state of data has not been ready to read in communication register.
my objective is to read the data in data register and id already set the communication register to read data register with command SPI.transfer(0x38);
but why the reading still in communication register?
sory i havent experience using the spi.h library before,

Well you are only powering it with 3.3V but you are giving it 5V signals and setting the reference to 5V. At best this does not do it any good, at worst has damaged it.
You should also have a 0.1uF capacitor from power to ground.
You have put the ~CE pin to pin 13 but you are not driving it with the software. This needs to be driven low just before you send it clock & data pulses and then high just after. Otherwise it will not work.

what do you mean ~CE?Chip Enable?if you mean that i connect it in pin 10 and id already driving it low and high then giving the data in the middle of it,
but if you are reffering to pin 13 its sclk pin,does it already handle with library spi.h?afaik in spi.h library in arduino uno already handle pin 11 = mosi ; 12= miso ; 13 =sclk;
And btw,what is exactly the purpose of putting capacitor there?

oke nice hints,ill try that tonight after work

what do you mean ~CE?Chip Enable?i

Using the ~ ( tilda ) in front of a pin name is another way of writing a bar on top of the pin name so ~CE means CE bar. The bar on a pin name is used to indicate that pin is active low. That is the pin does what it name says with a logic zero. Therefore the chip is enabled when a logic zero is placed on the pin.

if you mean that i connect it in pin 10 and id already driving it low and high then giving the data in the middle of it,

You must drive it low just before you send it data and you must put it back high just after. If you do not then the chip will not work correctly. This MUST be done before and after every transfer, you are not doing this. You asked where you are going wrong and I am telling you.

And btw,what is exactly the purpose of putting capacitor there?

http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

My guess is the output is actually signed, rather than unsigned. Thus, if you change the declaration of adcValue to "int" instead of "unsigned int," it may give you better readings.
Also, if the difference is almost entirely in the upper half rather than the lower half, it's totally possible that the data transfer is little-endian, when you're currently assuming it's big-endian. If that's the case, swap which byte you assign to the upper half of the value, and which you assign to the lower half.

thx you Grumpy_Mike & jwatte :slight_smile:

id already try the Grumpy_mike advice n its still giving no reading =(,,
and btw i think it doesnt need to drop cs low and high in every time we write and read the spi,
in link :
http://www.ccsinfo.com/forum/viewtopic.php?t=46768
http://www.ccsinfo.com/forum/viewtopic.php?t=47085
his code works fine without generating cs low and high every spi transfer,

and for jwatte
i use the unsigned for datatype because in this device i am setting it to unipolar mode,according to datasheet we get value up to 65536,so its unsigned

ive revised my code,
what ive improved here,

  1. wait for value drdy to 0 before drop the cs in reading state
  2. give cs high & low in every phase write & read
  3. give a reset state when initialization
  4. using hardware pooling in while loops
#include "SPI.h"
 
int ss=10;
int drdy=9;
int reset=8;
unsigned int adcValue;
byte highByte;
byte lowByte;
 
void setup(){
  pinMode(ss, OUTPUT);
  pinMode(drdy,INPUT);
  pinMode(reset, OUTPUT);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  Serial.begin(9600);
  digitalWrite(reset,LOW);
  digitalWrite(ss,LOW);
  delay(100);
  digitalWrite(reset,HIGH);
  digitalWrite(ss,HIGH);
}

void DataNotReady()
{
    int ready=digitalRead(drdy);
    while(ready)
    {
        delayMicroseconds(1);
        ready=digitalRead(drdy);
    } 
}

void SeriesCommandBit()
  {
  digitalWrite(ss,LOW);
  SPI.transfer(0x20);//command for comm reg to select ch1 and write to clock register ( dec     32)
  SPI.transfer(0xA5);//command for clock reg to set 2,4576Mhz                                  ( dec    165)
  SPI.transfer(0x10);//command for comm reg to write setup register                          (dec      16)
  SPI.transfer(0x44);//command for setup reg to self calibration,unipolar,unbuffered,     (dec      68)
  digitalWrite(ss,HIGH);
  }

void loop()
{
	SeriesCommandBit();   
	digitalWrite(ss,LOW);
	SPI.transfer(0x38);
	delayMicroseconds(1);
	digitalWrite(ss,HIGH);
	DataNotReady();
	digitalWrite(ss,LOW);	
	highByte = SPI.transfer(0x00);
	lowByte = SPI.transfer(0x00);
	adcValue = highByte << 8;
	adcValue = adcValue | lowByte;
	digitalWrite(ss,HIGH);
	Serial.print("analog value =");
	Serial.println(adcValue, DEC);
	Serial.print('\n');
	delay(1000);
}

ive already debuged it in drdy value,in it always giving 1,so it means the data never ready
please any advise for my situation :smiley: