two wire ADC, SPI read

I use Arduino UNO (Atmega328) and a 12bit ADC component (AD7893ANZ-10), datasheet available on https://www.analog.com/media/en/technical-documentation/data-sheets/AD7893.pdf

The problem:
I tried already few different codes but the read value is wrong always, even when the SDATA pin of ADC is not connected to MISO pin of Arduino, I get the same values (see figure in attachment). I simulated it in proteus(see figures.) and used the virtual serial monitor in proteus. The MOSI and SS pin of Arduino are not connected but I set SS pin in code to LOW and HIGH to fullfill libraries requirements. More information about the timing of ADC is added as comments into the code below. Or availabe in the datasheet. I would be thanksfull if you take a look on it due I cant figure out what I did wrong.

PS: The ADC has just to pins to communicate with SPI: 1.SDATA(slaveout) and 2.SCLK. The pin CONVST on ADC is to initiate a conversion.

Thanks and stay healthy :slight_smile:

#include <SPI.h>
   //source of code https://www.gammon.com.au/spi
void setup() {

  Serial.begin (115200);
  pinMode(7, OUTPUT);   // this pin is connected to convst on adc to initiate conversion


  // Put SCK, MOSI, SS pins into output mode (introductions from source)
  // also put SCK, MOSI into LOW state, and SS into HIGH state.
  // Then put SPI hardware into Master mode and turn SPI on
  pinMode(SCK, OUTPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(SS, OUTPUT);
  digitalWrite(SS, HIGH);
  digitalWrite(SCK, LOW);  
  digitalWrite(MOSI, LOW); 
  SPCR = (1<<MSTR);
  SPI.begin (); 
  SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE1)); // set the clk frequency; take the MSB first; 
                                                                    //mode1 for CPOL=0 and CPHA=1 according to datasheet p.9 "CPOL bit set to a logic zero and its CPHA bit set to a logic one."
}


int transferAndWait (const byte what)  //methode to read data
{  
  int a = SPI.transfer(what);    //send zero(MOSI not connected)and  read the first 8 bits and save 
  Serial.println (a);            // show the value, in serial monitor -1
  a =(a << 8);                   //shift the saved first 8 bits to left 
  Serial.println (a);            // show the value, in serial monitor 255
  a = a | SPI.transfer(what);     //read and save the last  8 bits 
  Serial.println (a);             // show the value, in serial monitor -256
  delayMicroseconds (10);
  return a;
} 


void loop() {
  int k;
  digitalWrite(7, HIGH);      //set pin high to initiate the conversion
  delayMicroseconds(9);       //the conversion time needed, actually 6 mikroseconds
  
  digitalWrite(SS, LOW);    // enable Slave Select  to get the library working
  k = transferAndWait (0);  //call the method
  delayMicroseconds(1);
  digitalWrite(7, LOW);      
  digitalWrite(SS, HIGH);   //disable chip select
  delay(2000);
  Serial.println (k);       // show the value, in serial monitor -1
}

NSFS.PNG

atmaa:
.....I simulated it in proteus(see figures.) and used the virtual serial monitor in proteus....

I'm always skeptical of simulation outputs in cases like these. did you ACTUALLY test your code on the REAL thing?

PS: your code, while a bit messy, seems to OK based on the Datasheet IMHO :wink:

Thanks a lot for checking, I didnt try it out on hardware yet due missing parts. I will do as soon as possible. I just was not sure if the code make sense at all :cold_sweat:

dear Sherzaad, thank u so much for checking and suggestingto try on hardware. I just did that and as u said the code is fine and works well.

thanks and stay healthy :slight_smile:

Glad I could help! :smiley: