AD7780 load cell

Hi everyone.

I am trying to communicate with load cell, which has AD7780. I tried with WIRE SDA-SCL but with no success.

I am using Arduino UNO rev3.

is it possible to comunicate?

Here is the scheme:

It took me three seconds to discover that this AD7780 device appears to use SPI ( or "SPI compatible" ) communications, not I2C.

Is Google broken in your country ?

Read the fricken' datasheet.

Ok. Thank You.

At first I am newbie in all of this things, so i will appreciate for a littlebit undestanding. Thank You.
My question is not what protocol is that, but how to make communication between Arduino uno and AD7780.

In my Country Google works fine.
I red datasheet, but i need help to understand this.

There are plenty of examples of how to use SPI between devices and Arduino.

You need to look at those, try it, and come back here if you have problems.

You are not going to get useful advice about how to use I2C, because it is not an I2C device ! You are also unlikely to get people sitting at their computers typing thousands of words explaining what SPI is, just for you.

SPI is going to be a bit tricky to implement for this device. The communication is only one way. It has no chip select. It has a multipurpose data ready/signal line. It might be easier to implement the communication by turning the pins of the arduino on and off directly, rather than trying to get the conventional SPI functions to work for you.

This works for the 20-bit version of the chip - the AD7781. You'll have to change it for the 24-bit version.

#include <Wire.h>         // for i2c lcd
#include <LiquidTWI2.h>   // for i2c lcd
#include <SD.h>           // for SD card

// Connect via i2c, default address #0
LiquidTWI2 lcd(0);

// Set up SD card file
File myFile;              // for SD

const int pinTempF = A0;  // analog temperature input
const int pinSCK = A1;  // clock digital out
const int pinDAT = A2;  // ready/data digital input
const int pinPwrDn = 4; // power down/reset digital out

unsigned long count; // ADC result
const unsigned long waitMs = 600000; // delay btwn reads
unsigned long nowMs;
unsigned long prevMs=0;

// for converting ADC count to grams or tenths of grams
//const unsigned long tare = 523000; // ADC count with no weight
//const float scaleFactor = 30.977;  // about 31 to get tenths of grams

// for weight statistics
unsigned int countInt;
unsigned long wtSum=0;
unsigned int wtMax=0;
unsigned int wtMin=65535;
int numReads=0;

byte tF; // temperature in deg F

byte buttons;  // lcd buttons
boolean doNow = true;

void setup() { 
  Serial.begin(115200);
  Serial.println(F("ADC 20-bit test; zero diff 524288; stat B01000001")); 

  //*** ADC setup
  pinMode(pinDAT,INPUT_PULLUP); // pull high (when shut down, ADC tri-states pin)

  pinMode(pinPwrDn,OUTPUT);
  digitalWrite(pinPwrDn,LOW); // turn ADC off

  pinMode(pinSCK,OUTPUT);     
  digitalWrite(pinSCK,HIGH);  // start high (and end high); is active going low  

  //*** LCD setup
  lcd.setMCPType(LTI_TYPE_MCP23017); 
  lcd.begin(16, 2);          // LCD columns and rows
  lcd.setBacklight(HIGH);
  lcd.print("Hi!");

  //*** SD card setup
  pinMode(10, OUTPUT); // used by SD card "CS" pin
  if (!SD.begin(10)) {
    lcd.setCursor(0, 0);
    Serial.println("SD err");
    lcd.print("SD err");
    delay(10000);
    return;
  }

}

void loop() {
 
  nowMs = millis();
  chkButtons();     // check LCD buttons and change backlight or show free RAM

  if((nowMs - prevMs > waitMs) || doNow) {
    doNow=false;
    prevMs = nowMs;


    readADC();      // get ADC count
    doCalcs();      // do max, min, sum (for avg)
    getTemp();      // read "thermister" to get temp in deg F

    PrintSerial();  // show on computer, if connected
    PrintLCD();     // show on LCD
    WriteData();    // save to SD card
  }
}


void chkButtons() {
  buttons = lcd.readButtons();
  if (buttons) {
    if (buttons & BUTTON_UP) {
      lcd.setBacklight(HIGH);     // turn backlight on
    }
    if (buttons & BUTTON_DOWN) {
      lcd.setBacklight(LOW);      // turn backlight off
    }
    if (buttons & BUTTON_LEFT) {  // show free memory
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(freeRam());
    }
    if (buttons & BUTTON_RIGHT) {
      doNow=true;      // do ADC reading right now
    }
    delay(300); // to give user time to release button
  }
}


void readADC() {
  byte i;
  byte statusBits = 0; // ADC status bits 
  byte numTry = 0;     // number of attempts to read ADC
  count = 0;  
  numReads += 1;       // number of calls to read ADC (used to calc averages)

  digitalWrite(pinPwrDn,HIGH); // turn ADC on

  while(statusBits ^ B01000001) { 
    // if statusBits doesn't match that pattern
    // then the ADC has reported an error in conversion or in the read
    // and XOR will return non-zero (i.e., true), and loop will continue.
    // If statusBits matches that pattern, 
    // then XOR will return zero (false) and loop will end.

    while(digitalRead(pinDAT));  // goes low when data is ready

    // then get 20 bits, MSB first
    for(i=0;i<20;i++)
    { 
      count=count<<1; 	          // shift in a zero; 1st time thru just shifts all zeros
      digitalWrite(pinSCK, LOW);  // Clock was initialized high; is active going low (here)
      if(digitalRead(pinDAT))     // read a bit and add one to count if bit is high
        count++;
      digitalWrite(pinSCK, HIGH); // inactive going high
    }

    // "Get" 4 bits (zeros).
    // For the 24-bit version of the ADC, 
    // this code would be deleted
    for(i=0;i<4;i++)
    { 
      digitalWrite(pinSCK, LOW);
      digitalWrite(pinSCK, HIGH);
    }       

    // get the 8 status bits
    for(i=0;i<8;i++)
    { 
      statusBits=statusBits<<1;
      digitalWrite(pinSCK, LOW);
      if(digitalRead(pinDAT))
        statusBits++;    
      digitalWrite(pinSCK, HIGH);
    }       

    numTry += 1;              // count number of attempts
    if (numTry >= 10) {       // if ten, then
      statusBits = B01000001; // force a return, with a number
      count = 500000;         // that the load cell will never generate
    }

  }
  digitalWrite(pinPwrDn,LOW); // turn ADC off

  // for most negative: returns 0
  // for zero: returns 2^19 = 524,288
  // for most positive: 20 "1"s = (2^20)-1 = 1,048,575
}

void doCalcs() {

  countInt = (unsigned int) (count - 500000); 
  // count <= 565,535, so save mem by subtracting 500000
  // (that way, max & min don't have to be longs)

  // find min and max
  if (countInt < wtMin) {
    wtMin=countInt;
  } 
  if (countInt > wtMax) {
    wtMax=countInt;
  }

  wtSum += countInt;  // sum for calculating average

}


void getTemp() {

  tF=0.39101*analogRead(pinTempF)-77.5; // exact would be -78, but added 0.5 to get proper rounding
}

void PrintSerial() {

  // print to computer, if connected
  Serial.println(F("**********"));
  Serial.print("i=");
  Serial.println(numReads);     
  Serial.print("count=");
  Serial.println(count);     
  Serial.print(F("avg Int="));
  Serial.println(wtSum / numReads); 
  Serial.print(F("max="));
  Serial.println(wtMax - wtSum / numReads); 
  Serial.print(F("min="));
  Serial.println(wtSum / numReads - wtMin);
  Serial.print(F("temp="));
  Serial.println(tF); //output deg F 
  Serial.print(F("freeRAM="));
  Serial.println(freeRam()); 

}


void PrintLCD() {
  // print to LCD
  lcd.clear();

  lcd.setCursor(0, 0);
  lcd.print("av");
  lcd.print(wtSum / numReads);
  lcd.print(" i");
  lcd.print(numReads);

  lcd.setCursor(0, 1);
  lcd.print("mn");
  lcd.print(wtSum / numReads - wtMin);
  lcd.print(" mx");
  lcd.print(wtMax - wtSum / numReads);
  lcd.print(" t");
  lcd.print(tF); //output deg F
}

void WriteData() {

  myFile = SD.open("AD7781.txt", FILE_WRITE);
  if (myFile) {

    myFile.print(numReads);
    myFile.print(',');
    myFile.print(count);     
    myFile.print(',');
    myFile.print(tF);

    // return and close     
    myFile.println();  
    myFile.close();

  } // end write to myfile if it opened
}

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

The problem I see with that code, is that if you get the problem where the status bits are not what you expect, and the while loop runs again, you need to have a low pulse on the PDRST signal in order to initiate a subsequent measurement from the device, don't you ?

michinyon and DaveEvans, thank You.

I will try all solutions.

massec - you're welcome.

michinyon:
The problem I see with that code, is that if you get the problem where the status bits are not what you expect, and the while loop runs again, you need to have a low pulse on the PDRST signal in order to initiate a subsequent measurement from the device, don't you ?

Hmmm... I don't see that requirement in the datasheet.