In my lab, we are working on developing an open-source online biomass sensor.

The basic idea is to shoot an IR light source to a colloidal solution and then measure the reflected light using a photodiode. The amount of reflected light is a non-linear function to the concentration of particles in the solution.

The objective is to build a sensor as low cost as it is practically possible, which is why we decided to use an Arduino Nano with an MCP3208 ADC to read the signal from the photodiode, and a TLC5947 LED driver to light the LEDs.

This sensor is to be used in lab-scale bioreactors, therefore it is impossible to isolate the photodiode from ambient light coming from halogen lamps and indirect sunlight. I'm planning to build a circuit to filter the signal from ambient light based on this article.

However, I come from a biology background and have training in electrical engineering equivalent to that of a hobbyist. I`ve managed to complete an initial design based on online resources. I would really appreciate if anyone could give me some feedback or recommendations on my design before I move to the test phase.

This is my circuit:


I'm going to use a VBPW34FAS photodiode and three IR LEDs with an irradiance of 2.5mW/sr. I'm expecting the current from the photodiode to be between 1uA and 100uA.

The first stage of the circuit is a transimpedance amplifier which is going to raise the signal up to 1V. I'm using the LMV321A op-amp for this stage.

The second stage is a low-pass filter (cut-off frequency 300Hz) and a voltage subtractor. The objective of this stage is to subtract the low-frequency signals (halogen lamps, sunlight) from signals corresponding to the actual reflected light. In this stage I am using a TLV9041 op-amp.

Finally, the last stage is a voltage amplifier (LMV321A) designed to increase the signal up to 4.9V to be read by the Arduino.

As I said before, any feedback, recommendations, suggestions, or ideas will be greatly appreciated.

  • 3
    \$\begingroup\$ Can you modulate your illumination so that you can directly filter it from the unmodulated background illumination? \$\endgroup\$ Commented Oct 5, 2021 at 5:55
  • 2
    \$\begingroup\$ Your biomass signal is down there in the low frequency stuff your filter is intended to remove. If your ambient light eliminator works as intended, it will remove your signal as well. The circuit you are looking at was designed for use with highspeed signals, where removing the slow stuff was OK. \$\endgroup\$
    – JRE
    Commented Oct 5, 2021 at 5:58
  • \$\begingroup\$ Are you planning to use all eight channels of the MCP3208? It looks almost like you want to have eight sensors driven by one Arduino. Three LED outputs and one ADC input per channel. \$\endgroup\$
    – JRE
    Commented Oct 5, 2021 at 6:05
  • \$\begingroup\$ @user1850479 I guess I could but I honestly don´t know what you are suggesting, could you elaborate a little more? \$\endgroup\$ Commented Oct 5, 2021 at 14:48
  • 1
    \$\begingroup\$ A bandpass would be ideal, but even simpler would be to acquire light, dark, light, dark... samples and compute your signal as (light-dark). One operation per sample and would completely remove any change in the background signal. Of course more sophisticated filters can give you even better SNR but that may not be needed unless your background signal is extremely strong. \$\endgroup\$ Commented Oct 5, 2021 at 16:23

3 Answers 3


You might find it easier to work with an integrated solution instead of building your own from discrete parts. For example, the ADPD4100 is a photometric front-end that handles the timing of your LED and PD specifically for Ambient light rejection. They have a reference design as well for liquid measurements.


The article you cited is not very useful. All this stuff has been solved almost a century ago.

The basic approach is always the same:

  1. Modulate the light source's optical power ("the carrier"). Aim for 100kHz minimum frequency, ideally over 1MHz. The carrier amplitude has to be controlled in a closed loop to eliminate temperature and LED aging effects on the optical output power.

  2. Demodulate the photodiode output synchronously with the clock signal fed to the light source.

The light source's output power doesn't have to be following a square wave, it can be a sine wave riding on a DC offset, to make the circuit less of an EMI nightmare.

The demodulator can either do proper multiplication with the carrier, or a simplified multiplication with a carrier-synchronous square wave. The former multiplies two continuous-valued voltages, the latter multiplies a continuous-valued voltage with a discrete coefficient of either +1 or -1, usually done with a switch.


There are a number of issues.

1 - It's possible that C1 is too small. This will depend on exactly which PD you have selected, and how far it is from the op amp. Since you're running with a very low transimpedance, you'll probably be alright, but you need to check for oscillation when you start.

2 - Whatever you do, you must not run the LED at the full current of the driver. At full current, there is NO PWM signal for your detector to detect. For that matter, I'd be leery of trying for a 100:1 dynamic range on your LED drive. One phase or the other (or maybe both) of the detected signal will be a pulse of rather narrow duration, and detecting it will be a problem.

3 - Assuming the LED driver is running solo, the clock rate is a max of 30 MHz. That will give you a nominal 8 KHz signal to detect (125 usec) with a nominal low end PWM pulse bandwidth of 800 KHz with the current set to 1% of a full-scale 100 uA detected level. That will require the third stage to respond to 1.25 usec pulses, and the op amp won't do that reliably, and the ADC is unlikely to keep up. It's actually worse than that, since the pulse width at the high end must be significantly less than 100%.

Frankly, I suspect you're better off using a fixed 50% PWM at a convenient frequency of something like 1 KHz and setting the current by means of a variable voltage source. This will cut way down on your ADC sampling rate, since you can sync your ADC to the drive waveform. Even so, you're going to need to maintain about a 16 KHz throughput for 8 channels.

You can also reduce both your ADC load and your processing by producing a simple phase sensitive detector (using your LED drive as a reference), also known as a lock-in amplifier. You can then sample the output only as often as you need the data (I'm guessing on the order of 1 to 10 Hz), rather than keeping track of on-off amplitudes at the modulation frequency. This will almost certainly require either a 50% of Vss virtual ground or a bipolar power supply, but it will greatly simplify your ADC load.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.