SPI Manipulation using AD7730 (Load Cell ADC) and SD Card Shield

Good Day everyone. I'm a newbie in the forum. I made lots of Arduino projects though for the past three years. However, I decided to post and ask some advice from you [experts :slight_smile: ] since my current project gets really frustrating and my due date is about to end.

I made an AD7730 shield for arduino and already tested it to a load cell. Now, I am about to save the calculated data to a memory card, where I chose SD card shield. However, my problem is that both shield ara using SPI interface. My plan is to put AD7730 to sleep or standby mode when Arduino is about to use the SD card shield, conversely, deactivate the latter when AD7730 is activated. Is this possible? And if so do you have any suggestion on how to do this in a right way? I am afraid to do trial and errors since I only have one AD7730 that is working.

Thank you in advance everyone. Godspeed.

Every SPI module has a SS (slave select) line, that activates the module. Attach these lines to different digital pins, and activate the intended device by pulling that pin LOW (or HIGH?). The other lines (SCK, MISO, MOSI) are shared by all devices.

Thank you very much. Now I know that I am in the right path. :grin:

After long hours of manipulations and editing the code as well as some *.cpp files, I am still unlucky for the two shield. Below is my simplified code. Any comments will be greatly appreciated.

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

#define RESET 8
#define RDY 9

const int sdSS = 4;

byte firstByte;
byte secondByte;
byte thirdByte;
unsigned long Dout = 0;
char charbuff[10];

void setup() {

  Serial.begin(9600);

  /*---////////// Set up AD7730 ///////////---*/
  Serial.println("Initializing AD7730 Shield...");
  pinMode(RDY, INPUT);
  pinMode(MISO, INPUT);    // AD7730 DOUT - Pin 12 Arduino
  pinMode(MOSI, INPUT);    // AD7730 DIN  - Pin 11 Arduino
  pinMode(RESET, OUTPUT);

  SPI.begin();
  SPI.setDataMode(SPI_MODE3);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV16);

  // Reset AD7730
  digitalWrite(RESET, LOW);
  delay(200);
  digitalWrite(RESET, HIGH);
  delay(200);
  // Set next action to Write to Filter Register
  digitalWrite(SS, LOW);  // AD7730 CS' - Pin 10 - Arduino
  SPI.transfer(0x03);
  digitalWrite(SS, HIGH);
  // Write Values to Filter Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x80);
  SPI.transfer(0x00);
  SPI.transfer(0x10);
  digitalWrite(SS, HIGH);
  delay(30);
  // Set next action to Write to DAC Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x04);
  digitalWrite(SS, HIGH);
  // Write Values to DAC Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x00);
  digitalWrite(SS, HIGH);
  delay(30);
  // Set next action to Write to Mode Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x02);
  digitalWrite(SS, HIGH);
  // Internal Full Calibration
  digitalWrite(SS, LOW);
  SPI.transfer(0xB1);
  SPI.transfer(0x80);
  digitalWrite(SS, HIGH);
  while (digitalRead(RDY) != LOW) {
  } // Wait until AD7730 is ready.
  // Set next action to Write to Mode Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x02);
  digitalWrite(SS, HIGH);
  // Internal Zero Calibration
  digitalWrite(SS, LOW);
  SPI.transfer(0x91);
  SPI.transfer(0x80);
  digitalWrite(SS, HIGH);
  while (digitalRead(RDY) != LOW) {
  } // Wait until AD7730 is ready.
  // Set next action to Write to Mode Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x02);
  digitalWrite(SS, HIGH);
  // Write Continuous Mode
  digitalWrite(SS, LOW);
  SPI.transfer(0x31); // 0x21 for bipolar
  SPI.transfer(0x80);
  digitalWrite(SS, HIGH);
  while (digitalRead(RDY) != LOW) {
  } // Wait until AD7730 is ready.
  // Set next action is to read data continuosly from Data Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x21);
  digitalWrite(SS, HIGH);
  digitalWrite(MOSI, LOW);
  Serial.println("AD7730 initialization done.");

  if (SD.begin(sdSS)) {
    Serial.println("SD Initialization done.");
  }
  else {
    Serial.println("SD Initialization failed.");
  }

}

void loop() {
  while (digitalRead(RDY) != LOW) {
  }
  digitalWrite(SS, LOW);  // Select AD7730
  firstByte = SPI.transfer(0);
  secondByte = SPI.transfer(0);
  thirdByte = SPI.transfer(0);
  digitalWrite(SS, HIGH); // Deselect AD7730
  Dout = thirdByte + secondByte * 256L + firstByte * 256L * 256L;
  Serial.println(Dout);
  float fDout = Dout;
  dtostrf(fDout, 4, 0, charbuff);

  File myFile = SD.open("MERCON.txt", FILE_WRITE);
  if (myFile) {
    Serial.print("Saving to file...");
    myFile.println(charbuff);
    myFile.close();
    Serial.println("done.");
  }
  else {
    Serial.println("Failed to open file!");
  }
  delay(3000);
}

When written separately, both initialization went through and working. However, when I combined them AD7730 initialization does not continue. I know there is a solution to m problem since SPI interfacing was designed for multiple device, I just don't know yet the right algo for this to shields.

Where is SS defined?

I'm not sure, but check in setup():
Remove pinMode for MISO and MOSI (should be done by the SPI library, MOSI should become output)
Remove digitalWrite(MOSI, LOW)?
Add pinMode(sdSS, OUTPUT)? (could be done in SD.begin?)
Set all used SS pins to OUTPUT before any other SPI related code.

Eventually swap the SD card and AD7730 initialization. The sequence should not matter, but...

And check that the modules' SS are connected to their assigned pins, and only to these pins (remove hardware jumper to another pin from shield?). SS and sdSS should not be shorted somewhere.

Thanks for your reply. SS is the default pin for m arduino which is pin10.
Luckily, I already found solution to the problem. I founfd Bill Greiman's updated SDFat library, which allows SD card shield to work with other SPI devices. Below is the simplified working code for AD7730 and SD card interfacing with Arduino SPI.

#include <SPI.h>
#include <SdFat.h>
SdFat sd;

SdFile myFile;

#define RESET 8
#define RDY 9
const int sdchipSelect = 4;

byte firstByte;
byte secondByte;
byte thirdByte;
unsigned long Dout = 0;
char charbuff[10];

void setup() {

  Serial.begin(9600);
  /*---////////// Initialize SD Card ///////////---*/
  if (!sd.begin(sdchipSelect, SPI_HALF_SPEED)) {
    Serial.println("SD Initialization failed.");
  }
  else {
    Serial.println("SD Initialization done.");
  }

  /*---////////// Set up AD7730 ///////////---*/
  Serial.println("Initializing AD7730 Shield...");
  pinMode(RDY, INPUT);
  pinMode(RESET, OUTPUT);

  SPI.begin();
  SPI.setDataMode(SPI_MODE3);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV16);

  // Reset AD7730
  digitalWrite(RESET, LOW);
  delay(200);
  digitalWrite(RESET, HIGH);
  delay(200);
  // Set next action to Write to Filter Register
  digitalWrite(SS, LOW);  // AD7730 CS' = SS = Pin 10 - Arduino
  SPI.transfer(0x03);
  digitalWrite(SS, HIGH);
  // Write Values to Filter Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x80);
  SPI.transfer(0x00);
  SPI.transfer(0x10);
  digitalWrite(SS, HIGH);
  delay(30);
  // Set next action to Write to DAC Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x04);
  digitalWrite(SS, HIGH);
  // Write Values to DAC Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x00);
  digitalWrite(SS, HIGH);
  delay(30);
  // Set next action to Write to Mode Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x02);
  digitalWrite(SS, HIGH);
  // Internal Full Calibration
  digitalWrite(SS, LOW);
  SPI.transfer(0xB1);
  SPI.transfer(0x80);
  digitalWrite(SS, HIGH);
  while (digitalRead(RDY) != LOW) {
  } // Wait until AD7730 is ready.
  // Set next action to Write to Mode Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x02);
  digitalWrite(SS, HIGH);
  // Internal Zero Calibration
  digitalWrite(SS, LOW);
  SPI.transfer(0x91);
  SPI.transfer(0x80);
  digitalWrite(SS, HIGH);
  while (digitalRead(RDY) != LOW) {
  } // Wait until AD7730 is ready.
  // Set next action to Write to Mode Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x02);
  digitalWrite(SS, HIGH);
  // Write Continuous Mode
  digitalWrite(SS, LOW);
  SPI.transfer(0x31); // 0x21 for bipolar
  SPI.transfer(0x80);
  digitalWrite(SS, HIGH);
  while (digitalRead(RDY) != LOW) {
  } // Wait until AD7730 is ready.
  // Set next action is to read data continuosly from Data Register
  digitalWrite(SS, LOW);
  SPI.transfer(0x21);
  digitalWrite(SS, HIGH);
  digitalWrite(MOSI, LOW);
  Serial.println("AD7730 initialization done.");
}

void loop() {
  while (digitalRead(RDY) != LOW) {
  }
  digitalWrite(SS, LOW);  // Select AD7730
  firstByte = SPI.transfer(0);
  secondByte = SPI.transfer(0);
  thirdByte = SPI.transfer(0);
  digitalWrite(SS, HIGH); // Deselect AD7730
  Dout = thirdByte + secondByte * 256L + firstByte * 256L * 256L;
  Serial.println(Dout);
  
  float fDout = Dout;
  dtostrf(fDout, 4, 0, charbuff);
  
  if (myFile.open("test.txt", O_RDWR | O_CREAT | O_AT_END)) {
    Serial.print("Writing to test.txt...");
    myFile.println(charbuff);
    myFile.close();
    Serial.println("done.");
  }
  delay(5000);
}

Good day! I encountered another problem in using AD7730. During my long testing and simulations using usb cable as supply line both AD7730 and SD card works flawlessly. However, when I am testing my set-up using external 9Vdc power supply with usb cable not connected and connecting a Serial LCD as monitor, the calibration of AD7730 hangs at

// Internal Full Calibration
  digitalWrite(SS, LOW);
  SPI.transfer(0xB1);
  SPI.transfer(0x80);
  digitalWrite(SS, HIGH);
  while (digitalRead(RDY) != LOW) {
  } // Wait until AD7730 is ready

The ready pin never goes LOW.