(Solved) Pull-down resistors for analog pins

Hello, I have an application that reads some analog sensors (LDRs) in a fairly harsh environment. I would like to write a function that periodically polls the readings and detects fault conditions. A short to ground is easy to detect, and a short to positive will shut down the board, but the most common fault is a broken wire, and since the pin is now floating around 500, which is also a valid reading if it were working properly, I cannot figure how to differentiate a fault. I tried 10K pull-downs, which distorted the readings too much. (Unsurprisingly).

Will 1M pulldowns work, perhaps? What are your thoughts? What about the internal pull-ups? My feeling was that 30 -50K may also be too strong, but I suppose it would be easier to try....

Also, a related question. When I was perusing some data sheets, I saw that all of the arduinos analog pins share one ADC unit and it's capacitor. I also saw that a call to analogRead takes about 200 microseconds. Is that enough time for the capacitor to drain between subsequent analogReads? Or should there be a delay between readings? My feeling is that an extra delay is not needed, and there certainly doesn't seem to be much mention of it, but I'm just curios. (I'm not sufficiently math-savvy to calculate the relevant values from the datasheet.)

Thanks!

1M should work. The analog input is spec'd at 100 megohms, but it's not actually a resistance to ground or Vcc.

and a short to positive will shut down the board

A short to Vcc will simply max-out the ADC.

Also, a related question. When I was perusing some data sheets, I saw that all of the arduinos analog pins share one ADC unit and it's capacitor. I also saw that a call to analogRead takes about 200 microseconds. Is that enough time for the capacitor to drain between subsequent analogReads?

It's fairly common to simply read twice (and ignore or overwrite the 1st reading).

DVDdoug: 1M should work. The analog input is spec'd at 100 megohms, but it's not actually a resistance to ground or Vcc.

Thanks. I'll give them a try.

DVDdoug: A short to Vcc will simply max-out the ADC.

Duh! Of course. It's been a long day....LOL

DVDdoug: It's fairly common to simply read twice (and ignore or overwrite the 1st reading).

That I did not know. That makes more sense than a delay.

Thank you for the quick reply!

@OP

1. It is a common practice to execute this code in setup() function for the detection of open-circuit at an input channel of ADC: pinMode(A1, INPUT_PULLUP):. At the open-circuit condition, the ananlogRead(A1); gives a value very close to 1023 (saturation) due to internal pull-up resistor (20k - 50k).

2. The int x = ananlogRead(A1); instruction is the compaction of the following steps:
(1) Select analog channel – A1. Automatic delay for the ‘hold cpacitor’ to be charged up to the pick value of the sampled signal.

(2) Conversion is started.

(3) The EOC (end-of-conversion) signal is being continuously monitored by the MCU. At the end of conversion, the MCU moves the ADC value to the variable x.; at the same time, the MCU clears the EOC status and discharges the ‘hold capacitor’. The ADC is ready for next measurement.

3. What I have understood that the very first reading (when the system starts) of the ADC is considered invalid as time is needed to initialize the analog circuitry.

@GolamMostafa,

If I understand you correctly, the setup() code for each analog pin would be:

pinMode(Ax,INPUT_PULLUP);
int x = analogRead(x);

//check for reading below about 1020 or so

pinMode(Ax,INPUT);

The system takes about 2 minutes on startup to home the motors, etc. before the first analog reading is taken, so I assume that is plenty of time for the ADC to initialize.

GolamMostafa: 3. What I have understood that the very first reading (when the system starts) of the ADC is considered invalid as time is needed to initialize the analog circuitry.

This is not true. The Datasheet says: "The first ADC conversion result after switching reference voltage source may be inaccurate, and the user is advised to discard this result." But it is true by default the first analogRead switches external reference to Vcc so according the Datasheet the first value read should be discarded. Another concern is the source of the analog voltage should have impedance less than 10kOhm. If the impedance is (much) higher the first (few) readings after channel switching will be inaccurate (between voltage of the old and new channel) until the S&H cap charges to the new voltage. This can be prevented by a small (nF range) cap on the channel.

JohnDeere630:
@GolamMostafa,
If I understand you correctly, the setup() code for each analog pin would be:

void setup()
{
   Serial.begin(9600);
   pinMode(A1, INPUT_PULLUP);
   int x = analogRead(A1); //discard this reading

   if(ananlogRead(A1) >=1000)
   {
      Serial.println("Something wrong at the input channel!")
      while(1);     //wait for ever
   }

}

void loop()
{
    //Read and process analog signal
}

BTW: Internal pull-up does not interfere with the input signal of the concerned channel; so, there is no need to disconnect the pull-up.

GolamMostafa: BTW: Internal pull-up does not interfere with the input signal of the concerned channel; so, there is no need to disconnect the pull-up.

I doubt this. Why do you think so?

GolamMostafa: (3) The EOC (end-of-conversion) signal is being continuously monitored by the MCU. At the end of conversion, the MCU moves the ADC value to the variable x.; at the same time, the MCU clears the EOC status and discharges the 'hold capacitor'. The ADC is ready for next measurement.

The hold capacitor is not discharged, it stays connected to whatever analog pin was last selected. Thats the reason you get cross-talk beween channels if the source impedances are very high, the hold cap doesn't get to fully charge with a very high input impedance on switching channels.

If the source impedance is 10k or less you'll never have to worry about the hold cap, it will charge completely in time with the default Arduino ADC configuration.

GolamMostafa: BTW: Internal pull-up does not interfere with the input signal of the concerned channel; so, there is no need to disconnect the pull-up.

No, this certainly does interfere unless the input impedance is very low (20 ohms or less).

Smajdalf: I doubt this. Why do you think so?

My experiment with NANO does not show the interference! (A1 channel was directly shorted with 3.3V point.)

But direct shorting is way less than 20 ohms source impedance obviously - try using a 1k+1k voltage divider
instead, a much commoner scenario…

LOL....now I'm a bit confused :confused: My application has 4 LDRs in a typical voltage-divider arrangement with a 5K resistor, connected to pins A0 - A3. The analog reference voltage is the default 5 volts, and it does not change throughout the sketch. They are typically read sequentially, with no commands or pauses between the readings.

It appears to work fine. The pin values are mapped from 0-1023 to 0-100, and they are pretty steady. This all is connected to the MCU with an 8' shielded cable, so obviously, there is some increased capacitance, but it doesn't seem to bother, as near as I can tell. I'd like to connect a 1M pull-down resistor to each of the 4 analog pins so that if a wire is broken, the pin will be pulled close to 0 volts rather than floating.

Is the pull-down a good idea? Should I do something different in the sketch with the readings, such as take average multiple readings, or discard the first reading of each pin, on each iteration? In the sketch, the readings are taken, compared, and motors are switched on or off on each iteration of loop(), so I'd like to keep it reasonably fast, to avoid overshooting the target. There are also 8 flags and 4 timers that are checked in the loop.

1M pull downs will allow detection of breakage, but you will need to double-read each pin to be sure to see the effect, as 1M is way above 10k

It would be simpler just to mount the 5k resistors at the Arduino, and the LDRs remotely. This way if there's breakage the 5k resistors will pull the pin to the rail just fine. No need to double read as the source impedance must be at most 5k.

There's no problem having half the divider at one end of the wire and the other half at the other.

MarkT: 1M pull downs will allow detection of breakage, but you will need to double-read each pin to be sure to see the effect, as 1M is way above 10k

It would be simpler just to mount the 5k resistors at the Arduino, and the LDRs remotely. This way if there's breakage the 5k resistors will pull the pin to the rail just fine. No need to double read as the source impedance must be at most 5k.

There's no problem having half the divider at one end of the wire and the other half at the other.

Huh. I never thought of that. Thanks! I already have pads for SM resistors on the shield board I made for the Mega, and this way, I don't even have to change the sketch! Plus, there only needs to be 5 wires run to the sensor array....

This thread was very informative and helpful. Thank you everyone!

Why that 1M pull-down? Aren't those 5k resistors right at your Arduino or so? That'd safe you bringing the Vcc line all the way out! All you need is five wires: one for each LDR and a common ground.

Wire shorted to GND: reading 0. Wire cut: reading 1023 (thanks to the 5k pulling the pin to Vcc).

I think we just agreed that!

wvmarle: Aren't those 5k resistors right at your Arduino or so?

They were up in the sensor array on a small PCB I made. When I get done with the mod, they will be connected as pull-downs on the shield board, and there will be 5 wires to the array instead of 6; 1 to each LDR and a common Vcc

To be honest, I don't know why I didn't figure this out earlier. Just a case of not seeing the forest through the trees, I guess. LOL

I moved the 5k resistors to the shield, and printed a new sensor array. It works like a charm, and now the Mega can not only detect a bad cell/broken wire, but tell me which one.

Thank you, MarkT, for that suggestion!