AD7797
Production
The AD7796/AD7797 are complete, analog front ends for high
precision, bridge sensor applications such as weigh scales. The
AD7796/AD7797 contain a S-?...
Datasheet
AD7797 on Analog.com
Hi everyone,
I am working on AD7797, created a custom PCB with atmega328p chip(arduino uno) and also written firmware for this. I am able to communicate with AD7797 but while reading ADC value it false data. Same data repeats. Please help me i am attaching PCB schematic and arduino code. Kindly share some library or code for AD7797.
Regards
Suman
#include <SPI.h> // include the SPI library: #define cs 10 void setup() { Serial.begin(9600); // initialize serial port pinMode(SCK, OUTPUT); pinMode(MOSI, OUTPUT); pinMode(MISO, INPUT); pinMode(cs, OUTPUT); digitalWrite(cs, HIGH); SPI.begin(); // wake up the SPI SPI.setDataMode(SPI_MODE3); // datasheet p6-7 SPI.setBitOrder(MSBFIRST); SPI.setClockDivider(SPI_CLOCK_DIV32); // datasheet p6 Serial.println("AD7797 Test"); initAD7797(); } void initAD7797() { beginAD7797(); resetAD7797(); //reset device delay(2); if (!(getID() % 2)) { Serial.println("ID : AD7796"); } else { Serial.println("ID : AD7797"); } Serial.print("Configuration : "); Serial.println(readCFG(), BIN); } void beginAD7797() //must be mode3 { //SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0); //mode3, 1MHz SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL) | (1 << CPHA); //mode3, 4MHz } void resetAD7797() //p14 { digitalWrite(cs, LOW); //reset IC by sending out 32b of 1s transferAD7797(0xFF); transferAD7797(0xFF); transferAD7797(0xFF); transferAD7797(0xFF); digitalWrite(cs, HIGH); } uint8_t getID() //WORKS! { uint8_t output = 0; digitalWrite(cs, LOW); transferAD7797(0x60); //01100000 0x60 output = transferAD7797(0x00); digitalWrite(cs, HIGH); return output; } //read value from ADC, long readAD7797() { long value = 0; //uint16_t byte1, byte2, byte3; //selectCH(ch); selectMode(); while (readST() > 127); //wait until !RDY digitalWrite(cs, LOW); transferAD7797(0x58); //select DATA register (01011000)(0x58) //one read try (01011100)(0x5C) for CREAD value = (transferAD7797(0x00) << 16) & 0xFF0000; value += (transferAD7797(0x00) << 8) & 0xFF00; //grab top byte value += transferAD7797(0x00) & 0xFF; //grab bottom byte digitalWrite(cs, HIGH); //pull CS high to disengage return value; //return( ((byte1<<8) | byte2) & 0xFFFF); } uint16_t readCFG() //works! { long output = 0; digitalWrite(cs, LOW); transferAD7797(0x50); //select CONFIGURATION register (01010000)(0x50) output = (transferAD7797(0x00) << 8) & 0xFF00; //grab top byte output += transferAD7797(0x00) & 0xFF; //grab bottom byte digitalWrite(cs, HIGH); return output; } uint8_t readST() //works! { long output = 0; digitalWrite(cs, LOW); transferAD7797(0x40); //select STATUS register (01000000)(0x40) output = transferAD7797(0x00); //grab byte digitalWrite(cs, HIGH); return output; } //select adc channel void selectCH(uint8_t ch) { if (ch > 2) ch = 2; ch |= 0x90; digitalWrite(cs, LOW); //pull CS low to engage transferAD7797(0x10); //select configuration register 00010000 (0x10) transferAD7797(0x10); //Write 16 bits to CONFIGURATION register: //bias voltage: disabled 0 0 //burnout current: disabled 0 //bipolar operation: 0 or 1? //boost: disabled 1 //gain: disabled 0 0 0 //top 8b: 00011000 (0x18), disable boost yields 00010000 (0x10) transferAD7797(ch); //internal reference 1 //0 0 //buffer 1 //0 //000 (CH1) 001(CH2) 010(CH3) //channel select = AIN1(+) - AIN1(-) //bottom 8b: 10010000 (0x90) 10010001 (0x91) read CH2 10010010 (0x92) read CH3 digitalWrite(cs, HIGH); //pull CS high to disengage } void selectMode() { digitalWrite(cs, LOW); //pull CS low to engage transferAD7797(0x08); //select MODE register (00001000)(0x08) //Write 16 bits to MODE register on page 16 Table 15 transferAD7797(0x20); //0x00 for continuous //0x20 for single conversion preferred //0x40 for idle //0x60 for power down //0x80 internal zero scale calibration //0xA0 internal full scale calibration //0xC0 system zero scale calibration //0xE0 system full scale calibration //update rate on page 16/17 transferAD7797(0x0C); //0x00 X X //0x01 470Hz 4mS //0x02 242Hz 8mS //0x03 123Hz 16mS //0x04 62Hz 32mS //0x05 50Hz 40mS //0x06 39Hz 48mS //0x07 33.2Hz 60mS //0x08 19.6Hz 101mS -90dB for 60Hz //0x09 16.7Hz 120mS -80dB for 50Hz //0x0A 16.7Hz 120mS -65dB for 50/60Hz //0x0B 12.5Hz 160mS -66dB for 50/60Hz //0x0C 10Hz 200mS -69dB for 50/60Hz //0x0D 8.33Hz 240mS -70dB for 50/60Hz //0x0E 6.25Hz 320mS -72dB for 50/60Hz //0x0F 4.17Hz 480mS -74dB for 50/60Hz digitalWrite(cs, HIGH); } uint8_t transferAD7797(uint8_t data) { beginAD7797(); //set correct SPI settings for devices SPDR = data; while (!(SPSR & (1 << SPIF))); //wait until transfer is done return SPDR; //return received byte } void loop() { delay(100); Serial.println(String("ADC Read : ") + readAD7797()); }
Kindly help anyone
Hi,
Do you have a scope shot of your digital interface upon reading the data register? Are you also monitoring the RDY bit or RDY pin upon reading the data register? May I know also what is your input range and so what data output are you getting from these input values?
We have a software driver for the AD779x family. This can be also applicable for the AD7797. So you can use this as your reference code. Hope this will help. Kindly refer to the link. AD7793 IIO Low Power Sigma-Delta ADC Linux Driver [Analog Devices Wiki]
Thanks,
Jellenie
Waiting for the reply
Please reply anyone i am waiting. Is this the support you give, partial.
Hi,
Yes, for system full scale calibration, you have to apply your full scale or maximum input voltage across AIN+ and AIN- (in your case in a load cell application it's the Max load that your sensor can measure, and in system zero scale you have to apply the smallest input voltage across AIN+ and AIN-, (that is no load at all).
Thanks,
Jellenie
Hi,
I had done good progress things are going good now.
One major issue i am facing now, that while reading channel AIN+ and AIN- my ADC output does not go more than 16777215 even if the differential voltage is increasing. It starts from 0 and goes max to 16777215 and after that no change exact same ADC value it gives.
Is it because of calibration, or what i should do. Please reply soon.
Regards Suman
Sorry i understood, 16777215 is the 24 bit max value. But this max value i am getting at 39mV only according to datasheet (P20) its correct for 5V +Vref. I want to understand how i can sense differential voltage of range 1V to 1.8V. In my application voltage across AIN+ and AIN- is in range of (1.5V to 1.85V)
Please help me how to solve this
Regards Suman
Hi,
AD7797 has a fixed gain=128, thus your differential inputs is limited to +/-Vref/128 = +/-39 mV. May I know what is the specifications of your load cell (i.e. sensitivity, max. load, etc.). If you want to measure a differential voltage of 1.5V to 1.85V then you have to add an analog front end that will attenuate your input signal to meet the AD7797 input specification. Another option is to use other parts that can accept your required inputs without the need of external circuitry such as AD719x or AD7124 which has lower noise and lower current consumption than the AD7797 with some advanced features. AD7124 operates from a 3.6V max supply but is worth considering 3V supply is acceptable in your design.
Thanks,
Jellenie
Load cell is nothing but custom designed strain guage wheatstone bridge. And i don't have much detail about it. Just i measured at 5V excitation voltage it takes 10 mA current, and it generates differential voltage 1.65V which i want to measure with to measure.
At this point i can't go to any other chip. Already more than a month gone in getting pcb, components and all.
Kindly help me this chip only.
What circuity is required to make it work
Hi,
Since your input is outside the required specifications of AD7797, you have to attenuate your signal either using a voltage divider or an amplifier with gain= -8 that could lower your 1.65V to 20mV.
Thanks,
Jellenie
Thanks for your support i made it working.
Hi Suman,
I have just started working with AD7797. Any chance you can share the final arduino script of yours. Will save me a lot of time and trouble.
Many thanks
Hi Suman,
I have just started working with AD7797. Any chance you can share the final arduino script of yours. Will save me a lot of time and trouble.
Many thanks