Photodiode Op-amp fluctuating

I am trying to make a simple ambient light meter for outdoor use. I connected fotodiode BPW21 to op-amp MCP6002 (rail-to-rail, its output values are always between 0-5 V in this case) according to the attached diagram. The op-amp’s resistor is 4k7 ohms, because the sensor should be able to detect high brightness values.

The problem is, that the values sampled by Arduino’s ADC are fluctuating. It’s now very bright outdoors, and the values are oscillating between 600 and 700 (even the sensor is in constant brightness). I sample at 1 Hz and values differ this much in less than 10 seconds.

I have read that the reason for this may be the op-amp. I tried to insert a 100 nF capacitor parallel to 4k7 resistor, but it didn’t help.
I don’t need bandwidth at all. It’s OK, if the sensor values rise slowly in 10 or 30 seconds to the “real” reading. The fluctuating is however annoying.

int analogPin = 5; 
int val = 0;  

void setup()
{
  Serial.begin(9600);            
}

void loop()
{
  val = analogRead(analogPin);
  Serial.println(val); 
  delay(1000);
}

The arrow of the diode seems to point in the wrong direction.
Are you sure you connected the photodiode anode to the + input (ground).

Did you use bypass caps on the opamp supply.
Have you go access to a scope, to see if the opamp is oscillating.
Post a real picture of the setup.
Leo..

Wawa:
The arrow of the diode seems to point in the wrong direction.
Are you sure you connected the photodiode anode to the + input (ground).

Did you use bypass caps on the opamp supply.
Have you go access to a scope, to see if the opamp is oscillating.
Post a real picture of the setup.
Leo..

Yes, anode is connected to the ground. I installed a 100 nF capacitor between +5V and ground pins in breadboard, which supplies both op-amp and Arduino.
Sadly I'm away now from my breadboard so I can't post a picture. I don't have access to a scope, either.

Does it help, if I insert a bigger, let's say 330 uF, capacitor parallel to the 4k7 resistor? Or what happens, if a big capacitor is attached parallel to the diode itself?

The sensor is outdoors, so it's connected to the breadboard with 5-6 m long RJ11 cable. Its self-capacitance is (I think) between 50-300 pF/m. As I said, low bandwidth is not a problem.

Here is a guide to photodiode amplifier design, that discusses the sort of problems you are having.

jremington:
Here is a guide to photodiode amplifier design, that discusses the sort of problems you are having.

BPW21's (photovoltaic, which I use) capacitance is 1.2 nanofarads. Cables make a few hundered picofarads of extra. The GBWP of MPC6002 is 1 MHz.
According to the formula #10 of this link Stabilize Transimpedance Amplifier Circuit Design | Maxim In, I need to install a capacitor circa 6.7 nanofarads.

It's still unclear, what should happen, if I insert a bigger capacitor? Should it be more stable? I repeat myself, but 100 nanofarad capacitor didn't help at all.
I get stable readings with a multimeter from op-amp's output, but not with Arduino ADC. Of course the multimeter is integrating or averaging is input, so they are totally different.

If the opamp can't drive that capacitive load (wire), then use a resistor in series with the output of the opamp.
This is a DC application, so 1k in series seems ok.
Leo..

Its not the same as driving a capacitive load, as the capacitor is in the feedback path.

MarkT:
Its not the same as driving a capacitive load, as the capacitor is in the feedback path.

Was talking about the ?500-1500pf? output to ground capacitance (the wire).
Leo..

MarkT:
Its not the same as driving a capacitive load, as the capacitor is in the feedback path.

Wawa:
Was talking about the ?500-1500pf? output to ground capacitance (the wire).
Leo..

The wire from the photodiode is 5-6 meters long, and it's attached to op-amp's negative input pin. This capacitance plus diode's capacitance = input capacitance?

Load capacitance is very small, the op-amp's output pin is connected direclty to the ADC pin #5 of Arduino.

Are these definitions correct? If they are, I think the 1k resistor in series doesn't help.

I assumed the normal situation of the photodiode very close to the opamp,
and the long wire between opamp and Arduino.
A long wire between photodiode and opamp could explain the symptoms you're seeing.

This should have been tested on the bench, before connecting a long wire to it.
Leo..

Wawa:
I assumed the normal situation of the photodiode very close to the opamp,
and the long wire between opamp and Arduino.
A long wire between photodiode and opamp could explain the symptoms you're seeing.

This should have been tested on the bench, before connecting a long wire to it.
Leo..

I tested the diode without any cable and it did fluctuate, but not as much as now. The sensor's self-capacitance plus cable capacitance is high, but the ambient light photovoltaic currents are also rather high.

The wire from the photodiode is 5-6 meters long, and it's attached to op-amp's negative input pin.

That is a serious mistake.

Make a small module with the op amp connected directly to the photodiode, and use a shielded cable with power, ground and op amp output between the module and the Arduino.

I wonder, what is frequency spectrum of the fluctuation? Does active low pass filter help to reduce fluctuation or does it contain also low frequencies?

The fluctuation I have seen looks sometimes like sine wave as it goes up and down, if I sample exactly with 1 Hz, but is that the case really? At least it's hard to believe so.

Does active low pass filter help to reduce fluctuation

Usually, a good low pass filter is essential.

You MUST sample at 2x the frequency of any possible input signal frequency, otherwise you will have aliasing and the results will be uninterpretable.

jremington:
Usually, a good low pass filter is essential.

You MUST sample at 2x the frequency of any possible input signal frequency, otherwise you will have aliasing and the results will be uninterpretable.

Good point. Next I am trying to increase Cf and add a LPF to see, what happens. Wish I had an oscilloscope!

I will report once I test it.

I inserted a 100 nF capacitor to the transimpedance amplifier and feed its output to a first order active op amp low pass filter (R = 10 kohm, C = 10 uF). The output is now much cleaner. There's still some fluctuation, but I think that's Arduino's fault. When feed the output to two analog pins, their values can differ randomly within +-3 range! Why?
Otherwise I am happy with the stability.

But another problem has emerged. I measured the output voltage of the low pass filter with a DMM and it's about 20 percent less than Arduino measures. The supply voltage is almost sharp 5.0 V, and I use the default voltage reference.
When DMM shows 4.5V, the Arduino has already saturated to 5V. Is my Arduino's 5V reference faulty?

double voltage = reading * 5.0 / 1023.0;

Is my Arduino's 5V reference faulty?

The default ADC voltage reference is the Arduino power supply. If your DMM measures 5V there then that is not the problem.

A very minor point, but the correct divisor for scaling is 1024., not 1023.

jremington:
The default ADC voltage reference is the Arduino power supply. If your DMM measures 5V there then that is not the problem.

A very minor point, but the correct divisor for scaling is 1024., not 1023.

Ok, I changed the divisor, but it doesn't make the difference obviuosly.
This is very weird. DMM shows 3.25 V, but Arduino shows 3.82 V...

If I forget anything else and attach 5 volts into a unity gain rail-to-rail op-amp, I measure output of 4.98 volts with DMM, which is exactly what op amp should give at maximum. But Arduino just saturates straight into 1023 or 5.00 volts.

Any suggestions?

EDIT: The inaccuracy is a problem in every pin and it disturbs at low voltages as well. DMM: 53 mV, Arduino: about 30 mV.

I measure output of 4.98 volts with DMM, which is exactly what op amp should give at maximum. But Arduino just saturates straight into 1023 or 5.00 volts.

That is the expected result from the Arduino ADC.
The increments between ADC readings are about 5 mV for a 5V reference, so you cannot tell the difference between inputs of 4.95V, 4.98V, 5.00V or even slightly higher. All those inputs will produce 1023 at the output.

Oops! A forum member was kind enough to point out my power of ten (50 mV versus 5 mV) error. There is a problem if the ADC cannot distinguish between 4.98V and 5.00V.

You might want to connect a 10K potentiometer between ground and 5V, with the tap going to the ADC input, and check out the full range of output versus input.