AD7705/AD7706 Library Revisited

About a year ago, I wrote a simple library for interfacing AD7705/AD7706 with Arduino. The library works, but it requires some decent knowledge of the underlying chip, which had made it somewhat difficult to use. Most issues users reported can be resolved by adjusting the timing in user code, but I admit that it is somewhat difficult for users who are not familiar with the chip. For a library, I should have made it easier to use to begin with. So, I decided to add a few long-awaited features and hopefully these tweaks will make the library easier to use.

One of the changes to the original code is the addition of the dataReady function. This function queries the DRY bit in the communication register and returns true when the data ready bit is cleared.

bool AD770X::dataReady(byte channel) {
    setNextOperation(REG_CMM, channel, 1);

    digitalWrite(pinCS, LOW);
    byte b1 = spiTransfer(0x0);
    digitalWrite(pinCS, HIGH);

    return (b1 & 0x80) == 0x0;

Using this function, we can wait till the converted data is ready before reading out the conversion result (rather then using delay statements):

double AD770X::readADResult(byte channel, float refOffset) {
    while (!dataReady(channel)) {
    setNextOperation(REG_DATA, channel, 1);

    return readADResult() * 1.0 / 65536.0 * VRef - refOffset;

In readADResult, I added an optional parameter refOffset. If your Vref- is not tied to the ground then you can use this variable to set the offset voltage to be subtracted from the conversion result. The default operating mode is set to be bipolar. For AD7705 and AD7706, the difference between unipolar and bipolar operation is simply how the the input signal is referenced so by setting the input mode to bipolar, you can still measure unipolar voltages. All that is needed is to tie the Vref- to the ground and leave the refOffset with the default value (i.e. 0).

I have also added a reset function. By calling this function first in your setup code, you are guaranteed that the chip is brought to a known state. Some of the difficulties users faced using the original library is that, depending on how the system is powered up, the AD770x may not be in a consistent mode and thus the A/D results seemed to be random. The chip reset can be achieved by either using the RESET pin or code. In my opinion, implementing in code is the desired method unless you need highest performance possible. Another benefit is that this implementation requires one less MCU pin.

Finally, I added a few parameters to the alternative constructor. In case you want to fine-tune your setup (e.g. setup different gain/speed), you can use the alternative constructor instead.

The following example shows how to use this library to read ADC results from multiple channels:

#include <AD770X.h>

AD770X ad7706(2.5);
double v;

void setup()


void loop()
  v = ad7706.readADResult(AD770X::CHN_AIN1);

  v = ad7706.readADResult(AD770X::CHN_AIN2);
  Serial.print(" : ");

Download: AD770X1.1.tar.gz (compatible with Arduino 1.0 IDE)

Be Sociable, Share!


  1. Vasiliy says:

    Hallo Kerry D.Wong!
    It’s from Russia again :)
    Thank you for the new library! Now it is compiled into the first version of the Arduino! But I have a question, is it possible to increase the polling rate channels? Or you can tell which part of the code of your library, can I change the time delay? So I can experiment with delay …
    Thank you again! With the new library, all channels are working fine!

    • kwong says:

      Yes, there is another constructor that takes the update rate as a parameter:

      init(byte channel, byte clkDivider, byte polarity, byte gain, byte updRate)

      and you can use the constants defined in the header to set your rates.
      static const byte UPDATE_RATE_20 = 0x0; // 20 Hz
      static const byte UPDATE_RATE_25 = 0x1; // 25 Hz
      static const byte UPDATE_RATE_100 = 0x2; // 100 Hz
      static const byte UPDATE_RATE_200 = 0x3; // 200 Hz
      static const byte UPDATE_RATE_50 = 0x4; // 50 Hz
      static const byte UPDATE_RATE_60 = 0x5; // 60 Hz
      static const byte UPDATE_RATE_250 = 0x6; // 250 Hz
      static const byte UPDATE_RATE_500 = 0x7; // 500 Hz

      The clock divider can be set accordingly based on your oscillator frequency.

  2. Alex says:

    Hello Kerry,

    Thanks for the library…very useful. I was wondering if it would be possible to use the library with an AD7715 which is pin compatible with the AD7706 but is only a single channel device. Which parts would need to be changed in order to make it work. I think the byte codes for accessing the different registers are the same??

    Thanks again


    • kwong says:

      Thanks Alex. As you observered, AD7705 and AD7706 are almost identical. You can use the exact same code for either AD7705 and AD7706. The only change would be the interpretation of the input pin s used.

      For instance, if the channel setting is CH1=0 and CH0=0, for AD7705 AIN1+ and AIN- are used whereas for AD7706 AIN1 and COMMON are used.

      • Alex says:


        I was actually looking at using the AD7715 which is not quite the same as an AD7706 – it is very similar though but this device only has one channel not two like the AD7706. There are other differences too though, there is no clock register in the AD7715. How difficult would it be to modify the AD7706 library to work with the AD7715? Please note that my coding skill is almost zero!!



  3. Alex says:


    My sincerest apologies, I have it working and it’s excellent!! I did not actually just try the library! Someday I will have to learn how to code properly and understand how libraries are written! Thank you so much for your library and your response…



    • Damien says:

      First thanks for this library kwong!

      Alex, have you realy had success with this library and the AD7715? Because I didn’t…
      I suppose you modify it because of the difference between AD770X and the AD7715 like clock register, and channel…
      Would you offer us your modified code?
      (French man writing…)


      • Alex says:


        My code used Kerry’s library without being modified. I’m not a very good programmer so I can’t be certain how it worked with the AD7715. The critical part was adding a 100ms delay to Kerry’s example code. Once I did that the device started to work. I tested it on a breadboard with minimal components as specified in the datasheet with a variable resistor to provide analogue data! It worked first time…best of Luck

        Here is my code:

        * AD770X Library
        * sample code (AD7706)
        * Kerry D. Wong
        * 3/2011


        AD770X ad7706(2.5f);
        unsigned int v;

        void setup()

        // ad7706.init(AD770X::CHN_AIN2);
        Serial.println(“Here we go…”);

        void loop()
        v = ad7706.readADResult(AD770X::CHN_AIN1);
        delay(100); //100ms delay for AD7715

        • Damien says:

          Thanks Alex for replying!

          I can’t believe how it worked for you with the AD7715…
          I’ve tried you sketch, but it didn’t work for me…
          This library doesn’t work for me, but I wrote one for our AD7715.
          I didn’t spend a lot of time on, and even it seem’s to work quite
          well (thanks to kwong) there are a lots of difference between AD770X
          and AD770X…

  4. Bodhi says:

    Hi Kerry,
    i’m using your library for AD7705. I still don’t understand how to get data. To take data from AIN1, this is the code i use:

    #define LOOP_DELAY 120


    temp1 = ad7705.readADResult(AD770X::CHN_AIN1);
    temp2 = ad7705.readADResult(AD770X::CHN_AIN3);

    I’m working with UPDATE_RATE_60. Is there other way to get data?? If i only read AIN3 or AIN1, sometimes it doesn’t get data. Depending on the delay time (loop_delay), accuracy is higher or lower. When i read AIN1, i only have ground and i supposed that AIN1 and AIN3 should be for AIN1+/-. Why do i have to read AIN1 and AIN3 for AIN1+/-??.
    I’m working with a duemilanove ATM328.
    Thanks in advance

    • kwong says:

      Hi Bodhi,

      You can configure the AD7705 in either differential (bipolar) or single-ended (unipolar) operation. The simple constructor you used defaults to unipolar. If you need to take differential measurement, you can use the overloaded constructor: AD770X::init(byte channel, byte clkDivider, byte polarity, byte gain, byte updRate) , you can take a look at the cpp file to see how it can be used.

      I am not sure why you need to include delay in your code though.

      • Bodhi says:

        Hi kwong,
        If i don’t use the delay, sometimes it doesn’t measure anything and accuracy is lower. I have to measure thermocouples and accuracy is very important.
        I tried to use bipolar but values were wrong and the only way i could work was the one i wrote in the past post.
        Thanks for your response.

        • Bodhi says:

          Hi again kwong,
          i tried to test your test program and i also need a delay. if i change the update_rate to other value different to 25 it doesn’t work, only measure 0.0000. With the gain, happens the same, measure something but out of the reality.
          I’m using a crystal of 4.000M, can this be the reason?.
          Thanks in advance

  5. Bodhi says:

    Hi again Kwong,
    how can i poll the dataready? only checking the pin 12 of the ad7705?

  6. Linas says:

    Hello ,

    Can you check you library for issuse :
    ad7706.init(AD770X::CHN_AIN1,AD770X::CLK_DIV_1, AD770X::BIPOLAR, AD770X::GAIN_4, AD770X::UPDATE_RATE_25);

    Init must setup CHN_AIN1 , but it sets CHN_AIN2 … The same with AIN2. This settings must be swaped.

  7. Linas says:

    Nice librarry , great job !!

  8. Bogdan says:

    I will try to connect AD7705 to the arduino Leonardo. The question is, in the datasheet used DRDY. It is also connected to the arduino or leave free? Also the datasheet CS goes to the ground, and you have it connected to the arduino.
    Sorry for the horrible English. I’m from Ukraine.

    • kwong says:

      Hi Bogdan,

      DRDY can either be read from the register or from the pin. The method I used was reading from the register and thus the pin is left unused. The CS pin is used in the SPI protocol and is controlled within the SPI library.

  9. Bogdan says:

    Hello! This again I am! Another question: what is the face value of capacitors that connect to ground quartz? I understand that stupid question, but thanks for the answer!)

    • kwong says:

      I used a 2MHz ceramic oscillator so the caps were not used. But can also use a crystal with 2 load capacitors. The value varies based on the crystal you choose, but anything between 18pF and 33pF will work.

      • Bogdan says:

        Hi! One more question on the library. I’m using the Arduino Leonardo. It SPI pins are different from UNO. For normal operation of A can change them in the file library?Thanks for the fast reply!

  10. drewman2000 says:

    I have a quick question, I’m using the AD7705 with the arduino mega 2560 chip. I modified the header file to use the correct pins for the mega 2560: MISO(pin 50), MOSI(pin 51), and SCK(pin 52). I also set pinCS to pin 24 (since that is what the AD7705 CS pin is connected to) and I setup pin 10 to be a 2 MHz clock (using timers) to go into MCLK IN since I don’t have a crystal. My current issue is that I will only get values equal to 0 or whatever I pass in as the reference voltage. If I pass 2.5 as my reference voltage then my output randomly alternates between 0 and 2.5, if I pass in 5, then it flips between 0 and 5. So could this be an issue with the chip or is this an issue because I’m using the mega 2560?

    • kwong says:

      Hard to tell… the first thing I’d do is short the input (or provide a steady voltage) of the ADC and see how the output behave. AD7705/06 does have a minimum recommended clock frequency of 4MHz so not sure if it would work with a 2MHz clock.

      • drewman2000 says:

        Right now I have the AD7705 connected to a simple voltage divider across a 10k pot, if I plug the input into ground or if I pull the input high the data coming in is still 0.00. I setup a 4 MHz clock and my serial output to my screen stopped altogether, any ideas?

        • kwong says:

          Sorry, my bad. AD7705’s minimum operating freq is 400kHz not 4MHz so 2MHz should be fine (and that’s the clock frequency I was using). Could you try a reset() immediately before reading the ADC value? Also, could you add a small delay (e.g. delay(10)) before reading the ADC to see if you observe any difference?

          • drewman2000 says:

            Currently I have a 500ms delay in my loop between readings, I tried the reset just before reading the ADC value and still nothing. At this point I’m inclined to think that I may have a bad chip

          • Rob Marks says:


            Firstly I’d like to thank you for putting together this library, I was wondering if you could help me with a problem I’ve got.

            I am in the exact same boat as drewman2000; I’m on a Mega2560, have altered the header file for the Mega pins (50-52), using pin 10 as a 2MHz clock with the AIN connected to a 50k pot and all I get out is 0.00 with about a ~100ms delay between readings. I’ve tried adding the small delay and also the reset but neither work, do you have any ideas?

            Is it also normal that it should take about 2-3 mins to complete the setup routine and start giving readings back?

            Separately, is it possible to read the analog input as a decimal number rather than as a voltage?


          • kwong says:

            Assuming you are using the revisited library querying the DRY bit instead of using delays. Since I don’t have an Arduino mega board I can’t test for sure, but something is definitely not right.

            It shouldn’t take that long to get the initial reading, and the only way it could take that long is the dataReady function keeps returning “false”. In this case the readADResult function would be in a wait loop.

            Could you try using a crystal oscillator instead of clock generated via Mega? Although it really shouldn’t matter.

  11. abdel mageed says:

    Hi kwong,
    i tried to operate your code program and i read H1= 0.0 H2=0.0 H1=0.0 H2=0.0 i can not reading Anything !!!!!!!!!!!!!!!


    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
    //set reference voltage to 2.5 V
    AD770X ad7705(2.5);
    float v1;
    float v2;
    float H1;
    float H2;
    void setup()
    //initializes channel 1
    //initializes channel 2
    lcd.begin(16, 2);
    void loop()
    //read the converted results (in volts)
    v1 = ad7705.readADResult(AD770X::CHN_AIN1);
    //read the converted results (in volts)
    v2 = ad7705.readADResult(AD770X::CHN_AIN2);
    H1 =(v1*1);
    H2 =(v2*1);

    lcd.print( H1);
    unsigned int data=0;

    • kwong says:

      Could you try reading just one channel and see what values you get?

    • Sejny says:

      You must place before AD7705 initialisation this: void AD770X::reset() Input shift register of AD7705 must be in known state before initialisation and communicating.

      2Keryy: reset routine simplified:

      void AD770X::reset() {
      digitalWrite(pinCS, LOW);
      digitalWrite(pinCS, HIGH);

      I use cheap TM7705 modules from ebay. After corrrect interface reset this fake chips work fine.

  12. Ashkar says:

    Hello Brother,
    Your library is the only thing that I got to get my work done,Actually I am Building a Data Logger so I need to port this code to ATMEGA 32 Mcu But I am could not do this,Is there any way that this library can be ported to a Off the market Atmega32 Mcu.
    Thanks a lot for your work

  13. MechE says:

    Thank you very much for the AD770X library!
    Is it possible to use pins other than 11, 12, 13 for MOSI/MISO/SCK?
    I am asking because two of my devices do not seem to be compatible with each other (they work well independently with the Arduino), and I have extra digital lines available. I did not see a reference to SPI.h in your library and example, so I am hoping this is possible. Thanks again.

  14. francesco says:

    Hi to to all,

    I’m using the AD7705 and i found this lib very helpful, thanks a lot!

    i just have quite a problem on the measuring:
    i have connected to the GND the ai1(-)
    i’m giving to the ai2(+) a known voltage from the arduino (voltage that i also measure with the multimeter)
    The configuration is exactly the one shown in the scheme by kerry wong.

    when i run the program, i get from the ad7705 a value lower than the one i expect, for example:

    if i set 1 V from the arduino, i measure 1.00V with the multimeter, but i get 0.95V on the AD7705.
    if i set 2 V from the arduino, i measure 2.00V with the multimeter, but i get 1.92V on the AD7705.

    it seems like i have a gain problem (i set a gain og 1 btw), because the ratio voltge_expected/volytage_measured=1.045 ish, which is averagely constat.

    Can it be a calibration problem? or am i making some stupid mistake? or is the IC broken?

    hope someone can help me,

  15. francesco says:


    my mistake i was talking about the ai1(+) not the ai2(+)


  16. Mahmoud Tantawi says:

    Dear Kwong,
    Thanks a lot for your library it works fine when i connect a potentiometer to the channel where the middle pin is connected to the +ve In and -ve In is connected to ground , now when i try to enter a sine wave as an input i get very unreasonable values , I’ve tried both making an offset so that the value of the input is between 0 and 1V for example or without offsite such that the input would vary between -50 and +50 mV (because it is said in the data sheet that there won’t be correct readings below -100 mV) do u have any ideas where the problem could be ?!

    Best regards,

  17. Jeff Newbill says:

    A question for anyone using the cheap boards off eBay that use the TM7705 chip (supposedly AD7705 compatible).

    I’m using both inputs, and when I do, the data from AIN1 data comes out when I request data from AIN2 and the data from AIN2 come out when I request data from AIN1.

    However when I use just AIN1 by itself, reading data from AIN1 works as expected, but when using only AIN2, the data can only be read by reading AIN1.

    Does the real AD7705 exhibit this behavior or this is probably just a problem because the chip is (probably) a Chinese knock off?


    • John Liu says:

      Hi, Jeff.

      I am using TM7705 module with Arduino MEGA 2560 board, the input is unipolar, both AIN1(-) and AIN2(-) connect to GND. But I ran into a similar situation as you mentioned above. I do not have any infomation about the usage of TM7705 module. Have you made any progress on sovling the problem?

      Based on MEGA 2560 schematic the pin connections are:
      MISO(50), MOSI(51), SCK(50) and CS(53)


    • John Liu says:

      Sorry for typo, SCK(50) should be sck(52)


    • Kory says:

      Wondering how you got data from the tm7705 chip. perhaps you could send me a picture or schematic of your wiring and the code you used. I cannot figure out how to get data using the example code. my email is Thanks!

  18. Amir-aka says:

    Hello Kwong!
    I have a module with AD 7705.
    It has AD 7705 and reference voltage of 2.5 V. I connect it to the Arduino Uno with your library. I connect outputs in accordance with the protocol library SPI. I use a simple sketch of an example for testing. On the input AIN 1, I tried to connect the various signal sources (electret microphone, temperature sensor, battery 1.5 V). All values displayed in the serial monitor – zero. Help me to understand, Why it’s not working?

  19. Jose says:

    Thank you Wong. Your library is very useful.
    I am also having problems with the module described by Amir (AD7705 Dual 16 bit ADC Data Acquisition Module Input Gain Programmable SPI Interface TM7705 ). I have changed the the bit CLK to account for the crystal of 4 MHz but still doesn’t work. It seems the module has some sort of hardware problem.
    Does anyone had success using the module 7705?

  20. Jorge says:


    I am having compilation errors when using the program with the DUE. It has to do with the library. Has anybody made it work with a DUE? what modifications to the library are necessary? thank you

  21. Jorge says:

    Since it was not working for the DUE I have tryed first with the UNO. It compiles correctly but all my readings are 0 (except for some which seem like noise). Has anyone had a similar problem? Any help? ty

    • kwong says:

      Hi Jorge,

      A lot of people seemed to have similar issues like what you were having. I am not entire sure whether there was some slight change in the chip or what. The ones I developed my code with are all working fine… So unless I can get a sample of the ones that people are having trouble with, I am not quite sure what’s going on.

  22. Mark says:

    It works on my TM7705, but I have only two digits after dot. How increase this to 4 digits?

  23. UriSh says:

    Hi Kerry,
    I’m building an Arduino musical instrument, and I’m using your library and the AD7705.
    Will it be OK to publish the code, including your library, as a blog post or as an instructable?
    I’m asking because I couldn’t find a license reference in the code.

    • kwong says:

      Absolutely! Everything here is open sourced in the hope that it would be useful for other people.

      • UriSh says:

        Thanks for your reply!

        I sure hope it will work out. I’ve been using the AD7705 to get a precise reading of a 10-turn potentiometer, and it worked perfectly fine, until I added a LCD+keypad shield (DFRobot). For some reason, when I connect both the LCD and the ADC, the ADC hangs. I’ve checked to see if I fried the hardware or something like that, checked if the pinout matches, and most everything else that came to my mind. Nothing works so far, which is very frustrating. If you have some insight on how to get this to work, I would sure like to know.

        Thank you very much,

  24. alisdair says:

    For anyone using the TM7705 red boards of ebay.

    I had a lot of issues getting mine going until I attached 5v to the reset pin. I’m not great at reading wiring diagrams but I thought that it was already connected, but it wasn’t.

    I get readings from a pot using the default code above on Arduino uno with the tm7705 above and the Pot connected to 5v, ain+, ain-.

    it reads up until 2.5v.

    if you touch a wire to ain- and the REFIN+ (The fourth pin from the dot(ground) on the ad7705 chip), you get readings from 0-5v.

  25. alisdair says:

    I have a question for Kerry D Wong. (Thanks so much for this library, its so great that you did all the work and than shared it!)

    I am trying to get a reading from an RTD sensor on the board. While I would love your help with that too my actual question is:

    To get a bipolar reading, do I need to read ain+ and ain- (by putting ad7705.readADResult(AD770X::CHN_COMM)). Or is that a question that would not even make sense if I knew more aobut electronics?

    (I ask because when I read Ain+ with the REF as the agitation for the RTD, I only get the agitation value (2.5) as a reading)

    Thanks for all your help in both writing this library and then reviewing it to make it easier :)!

    • kwong says:

      Hi, to use bipolar mode with AD7705, you need to call the overloaded initialization function (definition below):

      void AD770X::init(byte channel, byte clkDivider, byte polarity, byte gain, byte updRate)

      and passing in AD770x::BIPOLAR into the polarity variable.

      Also, in bipolar mode, the measurable range between ain+ and ain- is between -2.5V to 2.5V if the reference is 2.5V.

  26. ernesto says:

    Thanks for the great library, but im not able to get correct values on the ouptut, it is always the same even if i change the input voltage, my module is the red from ebay i also tried connecting reset pin to 5v but nothing changes.

  27. martin says:

    Hi Kerry,
    i´m quite desperate to bring AD7706 alive. Im using uno board with AT328, all wires are connected correctly and still i cant get nothing but 0.00 in serial monitor. Would you be so kind and give me an advice how to fix it. It looks like AD7006 doesnt comunicate with uC.

    Thanks for reply

  28. Belese says:

    Hello, if you are interested, i’ve ported this library in python to use it with spidev (for raspi for ex). Here is the link :

  29. Belese says:

    Ps. I also use the red one from eBay connected on an pi and it work, even without connected the reset has a vref = 2.5v.

Leave a Reply