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:

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.