Author Topic: AD7705 16-Bit Analog to Digital (ADC) Converter Hanging After Seconds-To-Minutes  (Read 6783 times)

Cube

  • Administrator
  • Contributor
  • *****
  • Posts: 86
    • View Profile
    • The Venturii Adventure
Background / Preamble:

I'm working on a prototype PCB involving an AD7705 Analog to Digital converter, which I have been wrestling with over the past couple of hours. For my testing purposes, I've soldered together a little prototype PCB using socketed components and quite a few wires, housing the basic components. Some of the pieces, including the AD7705 are on external PCB's, as they come from Aliexpress that way. I've put together 6x header blocks on my PCB to connect to the various off-board modules in a star configuration using standard 4-pin connectors on each. This makes for some clean connections, and a fairly presentable package all things considered, as I will need to mount this thing in my house once I finish the hardware and software in the garage and begin collecting data and tuning all the working parameters before digesting all things learned and producing a PCB that has all these things onboard itself.

The prototype as it is uses an Arduino Pro Mini (one of the knockoffs I'm sure) and has a 2x16 LCD display on the I2C bus, the AD7705 on the SPI bus, a couple of LEDs for realtime feedback, and a TTL-to-USB adapter for updates and Serial Port monitoring. I have an Infrared sensor monitoring ambient IR levels using the Atmel 328's onboard ADC, and I'm feeding the whole assembly power off a regulated power supply with onboard digital voltage readout, dialed in at 5.1Vdc. When it starts up, the LCD initializes and displays the values from the AD7705 and the IR sensor (basically values from both ADC's oversampled 15x.) ... and nothing else.

Present Problem:

It works for several seconds to several minutes, and then the AD7705 reports a value of 512 and stops updating. I connected a wire to the Data Ready pin on the AD7705 board and mirror that pin on one of the status LED's. When things are working, that LED flashes rapidly. When it stops, the LED is extinguished, which means that the Data Ready pin is low. If I hit Reset on the MCU, it starts up and everything works again, but inevitably the AD7705 stops working after a number of seconds. During this time, the readouts from the onboard ADC continue on the display, so the MCU itself is not hung, I just do not know what is going on with the AD7705.

This is probably one of the many instances where an oscilloscope would be very useful, but I am left with print() and digitalWrite() statements in the meantime. Actually, one other thing I can test is that I have another AD7705 board, I will swap them and see if the other one does the same thing. I noticed that the Analog Voltage Reference IC on this one looks like it wasn't sitting properly when it got soldered and I think there are gaps between the pads and a few of the pins on it. Begin troubleshooting...

It's funny, these projects always get snagged in the wrong places. For example, I expected trouble getting it working with a different Chip Select pin, but once that was resolved and I started getting data from it, I thought I was out of the woods. Then I encountered seemingly high amounts of noise, so knocked a few bits of the ADC off (it is a 16-bit converter so fairly high precision, most of which is probably not necessary for my application.) Got the readings pretty stable and thought I was out of the woods again, ready to write [proper] firmware to begin interfacing this with the Venturii VDAC module - only to discover that the external ADC seems unstable. I don't want to move on from here until I have a proven platform I can fall back on in case the Venturii firmware is buggy, but now I am left troubleshooting something else I had not anticipated. So it goes...
Venturii - Integrate Everything

Cube

  • Administrator
  • Contributor
  • *****
  • Posts: 86
    • View Profile
    • The Venturii Adventure
The other AD7705 board does the same thing. :( Scratch that off the list.

Another piece of VERY odd behavior I've noticed is that when the AD7705 is locked up, the analog reading of the IR sensor affects the DataReady LED! I have NO idea how that happens, and if I disconnect the DataReady pin from the AD7705 it floats so the LED flickers, making me all but convinced that the signal is coming from the AD board. Every single time though, it does the same thing. It runs for a few seconds (30-90 it seems) and then the green LED goes out. Now if I place an object in front of the IR sensor and the value rises above 100 (seems to be exactly 100 that is the tripping point) (100 out of 1023, I might add.) - the green LED goes on. Dropping the value of the IR sensor below 100 extinguishes the LED, but all the while the AD7705 reports a value of 512. It is shifted two bits to the right, so I imagine this is probably 16385. Maybe I'll drop the bit shift off and see what the actual number is *just for something to try.* This is really bizarre. I can't wait until I'm reading this in retrospect with a smile on my face and thinking to myself, "If only I knew then what I knew now..."
Venturii - Integrate Everything

Cube

  • Administrator
  • Contributor
  • *****
  • Posts: 86
    • View Profile
    • The Venturii Adventure
Here is the code:

Code: [Select]
void setup() {
Serial.begin(9600);

// -- LEDs and IRBS Initialization -- //

pinMode(BigGreenLED, OUTPUT);
pinMode(YellowLED, OUTPUT);
pinMode(IRBS_LED, OUTPUT);
pinMode(A0, INPUT);
pinMode(AD_Ready, INPUT);

// -- DIP Switch Shift Register Initialization -- //

pinMode(ploadPin, OUTPUT);
pinMode(clockEnablePin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);

digitalWrite(clockPin, LOW);
digitalWrite(ploadPin, HIGH);

DIPs = read_dip_switches();
display_dip_switches();
DIPSwitchValues = DIPs;

// -- AD7705 Initialization -- //

ad7706.reset();
ad7706.init(AD770X::CHN_AIN1, AD770X::CLK_DIV_1, AD770X::BIPOLAR,
AD770X::GAIN_1, AD770X::UPDATE_RATE_500);
        // Not using the second channel:
//ad7706.init(AD770X::CHN_AIN2, AD770X::CLK_DIV_1, AD770X::BIPOLAR,
// AD770X::GAIN_1, AD770X::UPDATE_RATE_500);

lcd.init();
lcd.backlight();
lcd.print("bbs.venturii.net");
}

void loop() {

static uint8_t x = 0;
static unsigned long as = 0, bs = 0, il_sum = 0;
unsigned int t = 0;

// Set Green LED to the value of the Data Ready pin from the AD7705:

digitalWrite(BigGreenLED, digitalRead(AD_Ready));
as += ad7706.readRawResult(AD770X::CHN_AIN1);

// IRBS - Take sample with LED On:

digitalWrite(IRBS_LED, HIGH);
digitalWrite(YellowLED, HIGH);
il_sum += 1023 - analogRead(A0);

// IRBS - Take sample with LED Off:

digitalWrite(IRBS_LED, LOW);
digitalWrite(YellowLED, LOW);
bs += 1023 - analogRead(A0);

x++;

// Oversample:
if (x > 14) {

// Display rad value from AD7705:
t = as / x;
lcd.setCursor(0, 1);
lcd.print(t);
lcd.print("     ");

// Display differential value from IRBS:
t = bs / x;
t = il_sum / x;
lcd.setCursor(7, 1);
if (il_sum > bs) {
lcd.print("[");
lcd.print((il_sum - bs) / x);
lcd.print("]   ");
} else {
lcd.print((bs - il_sum) / x);
lcd.print("   ");
}

// Clear buffers and counter:

as = bs = x = il_sum = 0;
}

// Lather, rinse, repeat. Always repeat.
}
Venturii - Integrate Everything

Cube

  • Administrator
  • Contributor
  • *****
  • Posts: 86
    • View Profile
    • The Venturii Adventure
I tried a few more things:

  • First of all I removed the initialization code for the second channel of the AD7705. I'm not using it and there is nothing hooked up to it's input, so I shouldn't need to do anything on the second channel. Same Result.
  • I removed all LCD code from the program; basically it does nothing now since it has no way to output the data, but it still collects it and then clears the counters every 15th pass. Same Result. Interestingly, this time I could not get the green LED to change state by placing an object in front of the infrared beam sensor - it stayed off this time. I suspect there is some conflict between the LCD code or library and the AD7705 code / library. I also noticed that the pin 13 clock LED (onboard LED) was much more smoothly flashing this time - it seems like whenever the LCD display goes to update it pauses the SPI clock just enough to create a noticeable pulse in the clock LED. I don't know what the implications of this are for the rest of the problem, but certainly worth pointing out.
  • With the LCD code in place, I tried grounding the Data Ready pin and repeating the IRBS test - with the pin grounded there is no change of state in the LED. Therefore I believe that [somehow] the IRBS or LCD code is affecting the inner workings of the AD7705 board, to the point that we are able to cause it to toggle it's Data Ready pin.

It is getting late and I am going to let this sleep overnight. The more I troubleshoot it the more confused I'm getting. It doesn't seem like this should be possible, and yet - here we are. Hopefully a fresh start tomorrow or another day may help bring new insight to the problem because right now I am stumped!
Venturii - Integrate Everything

Cube

  • Administrator
  • Contributor
  • *****
  • Posts: 86
    • View Profile
    • The Venturii Adventure
Not one to give up easily, I tested another theory: This time I physically removed the Data Ready pin connection from the AD7705 and the MCU and even reinstated all the LCD and Serial Output code, and so far - it has not locked up once. I am now going to leave it running overnight and see what the result is in the morning. Fingers crossed! (Reason for optimism: It has not run this long without hanging, probably since I added that Data Ready pin. Very odd that doing so would cause so much trouble, especially since it is connected to a pin configured as an input, but there it is - so far, a smoking gun. Of course, I just realized that there is another possibility: Doing so necessitated the use of a different connector type - this time I used a strip of Dupont (?) connectors, and they are all still physically connected together in a ribbon cable. The four pin connectors previously used were not - each wire was free run. I wonder if I wasn't inducing some troubling interference that way, and the shorter, parallel wires in this cable isn't helping solve the problem? Sigh. Either way, it's still working. I need to find out what exactly the cause is before I can truly put this issue to rest, but progress is still progress. Goodnight.
Venturii - Integrate Everything

Cube

  • Administrator
  • Contributor
  • *****
  • Posts: 86
    • View Profile
    • The Venturii Adventure
And the morning's results: Success!

The prototype is still pushing data in real time to the LCD and to the Serial Port. (I actually forgot to hit "Post" on this yesterday, but two days in and it is still cranking out values to the LCD and serial port. I'd say that was it, either the Data Ready pin or the spread out wires, or both.)
Venturii - Integrate Everything

Cube

  • Administrator
  • Contributor
  • *****
  • Posts: 86
    • View Profile
    • The Venturii Adventure
I've been working on this project with renewed vigor of late, trying to get it to workable status in time for this year's outdoor watering season. I really want to monitor my water consumption patterns, particularly since we've also had a few leaky toilets that sometimes don't shut off the water inside the tank after a flush. Totally different problem, but one that can be easily resolved with some monitoring of the tank and/or the water consumption of the house.

Looking back over these posts dated quite a few months ago, I was shocked to realize how much I'd forgotten about the headaches I had with it since that time. Recently I've been experiencing much of the same problems, thinking they were new, and come to several pseudo-conclusions:
  • I'm still using the same laptop, which could be faulty.
  • Mark has pointed out that he's had similar "ghost-like" issues solved by re-flashing the bootloader.
  • Not many people on the Internet report having similar problems to the ones I've been reporting.
  • The environment and build of the prototype could be suspect.

The reason I suspect the laptop of ill is that often, even when just trying to flash the device, the process fails. This could be due to Virtualbox, since I am technically operating the serial port from inside a vbox virtual machine. On times where it failed to flash the first prototype, it only failed during the read (verification) stage - write always succeeded. However, I since tried using a different board and hot-wired the prototype over to it only to find that it would more readily fail on the write cycle, never even making it to the read stage. When it did succeed on a successive attempt, it worked flawlessly, making me think that much of the headaches and hassles I'd been experiencing were directly related to the physical layout and design of the first prototype. I've started working on a PCB design in KiCad, to produce a "proper" prototype of this product. In the mean time, I'm going to try connecting it to a standalone IP to Serial converter, physically separating it from the laptop, to see if that doesn't help as well.
Venturii - Integrate Everything