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() { Serial.begin(9600); ad7706.reset(); ad7706.init(AD770X::CHN_AIN1); ad7706.init(AD770X::CHN_AIN2); } void loop() { v = ad7706.readADResult(AD770X::CHN_AIN1); Serial.print(v); v = ad7706.readADResult(AD770X::CHN_AIN2); Serial.print(" : "); Serial.println(v); }
Download: AD770X1.1.tar.gz (compatible with Arduino 1.0 IDE)