analogRead results are influenced by delay-length?

Hi all,

Im experiencing a "phenomenon" where the readout from an LDR varies depending upon how often I do the readout.

Since there are several seconds (could be minutes) between each readout I would not expect the wait-time to have any influence.
The code is really simple and short. It's basically:

  • Wait a predefined number of miliseconds
  • Turn on LED
  • Wait 5 seconds
  • Get the measurement
  • Turn off LED
  • Print result
  • Start over

I don't understand how 1. can influence 4. seeing as there are so much time between the two. But as the table at the end of the post shows, there is a connection?

Please share your thoughts as I would like the readouts/results to be independent from the amount of time between readouts. And I would really like to know what is actually going on :o

Hardware setup is a cheap LDR in series with 100k resistor and then the Uno measure the voltage on A0. A blue LED shines down on a surface and the LDR, being in the same plane as the LED, picks up on the reflected light. This is done in a dark and sealed box letting no outside light in, and so it should be repeatable (I know the LDR will fluctuate a bit, but take a look at the averages of my example and you'll see why I'm confused when it comes to the delay between readouts).
I've tried four different LDRs and I can replicate this on input A0, A1, A2 and A3 on the UNO.

Please see my code below and below the code I've given some examples of the values I get (10 repetitions) when changing the "SAMPLEPERIOD". The average clearly indicates decreasing values as SAMPLEPERIOD increases.

Uno R3 using Arduino 1.6.12

// define pins
#define exciLed 13
#define k1APin A0

// Why does SAMPLEPERIOD have an impact on the readouts?
#define SAMPLEPERIOD 20000

int k1A = 0;
int count = 1;

void loop()
{
  // Changing this gives different readouts - and confuses me. What's going on?
  delay(SAMPLEPERIOD);

  k1A = 0;

  // Turn on blue LED
  digitalWrite(exciLed, HIGH);
  delay(5000);

  k1A = analogRead(k1APin);
  
  // Turn off blue LED
  digitalWrite(exciLed, LOW);

  Serial.print(count);
  Serial.print("\t");
  Serial.print(k1A);
  Serial.println();
  count++;
}

void setup()
{
  // setup pins
  pinMode(exciLed, OUTPUT);
  pinMode(k1APin, INPUT);

  analogReference(INTERNAL);

  // Initiate serial
  Serial.begin(9600);
}

How/why is the SAMPLEPERIOD influencing the result from analogRead(k1APin) ?

SAM.PER. = 5000
1 364
2 421
3 433
4 422
5 414
6 431
7 410
8 434
9 416
10 411
Average 415.6
SAM.PER. = 10000
1 324
2 394
3 403
4 402
5 417
6 423
7 417
8 413
9 423
10 404
Average 402.0
SAM.PER. = 20000
1 312
2 335
3 370
4 352
5 331
6 339
7 356
8 333
9 351
10 360
Average 343.9
SAM.PER. = 40000
1 268
2 296
3 312
4 290
5 297
6 295
7 303
8 312
9 312
10 284
Average 296.9

Have you got the time response curve for the LDR from its datasheet?
CdS is sloooooooow

AWOL:
Have you got the time response curve for the LDR from its datasheet?
CdS is sloooooooow

There doesnt appear to be any time response curve or figures in the datasheet, but I guessed that 5 seconds would be sufficient. However, since these 5 seconds are constant and I'm only varying the "period of darkness" I cant see how this (the time response) would have an effect on what I'm seeing? But to be honest I also cant see why the amount of "darkness-time" between measurements influences the result.

Sorry, brain-fart - I was reading your delays as microseconds

Add a temperature sensor next to the LDR and see if the temperature changes relate to the LDR changes.

Paul

When you say 'in series with a 100k resistor' you mean it's setup as a voltage divider with LDR between +5 and A0 and a 100K between A0 and GND? I'd try replacing the LDR with another 100K resistor (so the voltage will stay the same) then try that. If the readings are then all the same and about 512 the ADC is working and it's got to be the response of the LDR.

analogReference(INTERNAL);

Can't do that if you power the LDR/resistor from the default 5volt supply.
That stuffs up the ratiometric behaviour of the LDR, resulting in unstable readings.

I think LDRs are most sensitive to green, so why a blue LED.
Leo..

Paul_KD7HB:
Add a temperature sensor next to the LDR and see if the temperature changes relate to the LDR changes.

Paul

Great advice. The LED I’m using might be warming/cooling in the on and off periods and maybe a slight drift in the light spectrum occurs, also it is close to the LDR, maybe temperature is influencing the LDR as well. It’s not easy jamming a temp-sensor in to the current setup but I will see if I can make it fit without adding furter holes to the box.

Andym535:
When you say ‘in series with a 100k resistor’ you mean it’s setup as a voltage divider with LDR between +5 and A0 and a 100K between A0 and GND? I’d try replacing the LDR with another 100K resistor (so the voltage will stay the same) then try that. If the readings are then all the same and about 512 the ADC is working and it’s got to be the response of the LDR.

Yes, exactly as you described. +5V → LDR >-A0-< 100k → GND
I’ve done the tests from my example as you suggested with a 100k instead of the LDR. It showed rock solid and predictable results. So nothing wrong with Uno or the software as I see it. Good test, thank you :slight_smile:

Wawa:
analogReference(INTERNAL);

Can’t do that if you power the LDR/resistor from the default 5volt supply.
That stuffs up the ratiometric behaviour of the LDR, resulting in unstable readings.

I think LDRs are most sensitive to green, so why a blue LED.
Leo…

I’m not sure I quite follow? Maybe I’m misunderstanding but the voltages I’m measuring are well below 1V since the light source is quite weak. However, I’ve commented the “analogReference(INTERNAL);” line out now and tried the experiment again. It still gives me results that seems to be influenced by the “on/off” time described in the OP.

The reason for using a blue LED is because the reflective surface of which I’m trying to measure the lightintensity is flourescent and the “blue” LED is actually a UV-LED (but also emits blue wavelengths). A green LED would not excite the material on the reflective surface sufficiently to make measurements.

With an LDR you normally use a pull up resistor with about the same value as the resistance of the LDR at the light level of interrest. That could well be higher than 100k in your case.
You should then get A/D values of about 512, and the most variation with light changes.

With those high values, a (10-100n) buffer/sample cap from analogue-in to ground is required, and maybe also two consecutive readings without delay in between (and use the second reading).

Not sure what you're trying to do. Measure the (bad) response/recovery time of an LDR in low light?
Leo..

Unkle:
I'm not sure I quite follow? Maybe I'm misunderstanding but the voltages I'm measuring are well below 1V since the light source is quite weak. However, I've commented the "analogReference(INTERNAL);" line out now and tried the experiment again. It still gives me results that seems to be influenced by the "on/off" time described in the OP.

The reason for using a blue LED is because the reflective surface of which I'm trying to measure the lightintensity is flourescent and the "blue" LED is actually a UV-LED (but also emits blue wavelengths). A green LED would not excite the material on the reflective surface sufficiently to make measurements.

Perhaps this will help. The LED you have is a blue LED. It has a phosphorescent coating that emits UV when pumped by the wave length of the blue light.

A "white" LED works the same way, except it has two blue LEDs, each a different wave length. They excite various combinations of phosphors that together produce what we see as "white" light.

A blue LED takes more voltage and current than the common red LED and probably needs a heat sink to remove the internally generated heat. White LEDs require heat sinks to handle the heat.

Paul