electronut Programming & Embedded Systems - by Mahesh Venkitachalam

Designing an Op-Amp Circuit to Detect LDR Pulses

The Problem

I wanted to design a circuit to generate a nice digital pulse (for input to a microcontroller or the Raspberry Pi) every time an LDR is quickly obscured from ambient light - like for instance, when you pass your hand over it. I didn't want to use the popular solution of reading the analog values, and processing it on the microcontroller (averaging, finding peaks, etc.), because this will take up valuable processing time, and I want to avoid lag as much as possible, by offloading this work to hardware.

So here are 3 attempts that I made, and the results.

Attempt #1: Use a Differentiator

When you pass your hand over an LDR (connected in the form of a resistor divider circuit), you get a signal with a little dip in it. To convert this signal to a peak, you can use the derivative. So my first attempt was to use an op-amp differentiator from Scherz's book [1].

Here is what the output signals look like on an oscilloscope:

So it works, we have a peak, but it's a low voltage signal, and in any case, it's not the clean digital signal I am looking for. Hence...

Attempt #2: Use a Differentiator + Comparator

If I feed the output of the circuit #1 to a comparator, it will swing to high when the differentiator outputs a peak.To avoid small noise triggering it, I am using a 1:100 resistor divider on the V- pin.

So here's the modified circuit:

Now here's what the signals look like on a scope:

Now that's much better. This actually works very well - I am able to get this into the Raspberry Pi GPIO pins as a "rising" signal. (If you use it with the Pi, make sure you use a 3.3V supply and not a 5V supply to the op-amp - else you might damage your Pi.)

But apparently there is a better way of doing this...

Attempt #3: A "Data Slicer"

As expected, posting this on StackExchange [2] resulted in a more elegant solution which uses lesser number of components - a single op-amp, in fact. The idea is to use a "Data Slicer" op-amp circuit [3], in which the op-amp inputs are the signal (-) and the same signal with a low-pass filter (+), with a cut off around 1.6 Hz. The op-amp is wired as a comparator, which goes high whenever there is a difference in the inputs, which will happen when there is a dip in the LDR signal. The 1M pot is used to bias the default output to low when there is some noise.

Here is the circuit:

And here is the output:

Fantastic! I guess you (can) learn something new every day. ;-)


  1. Practical Electronics for Inventors, 4th Ed by Paul Scherz & Simon Monk.
  2. My post on this topic at StackExchange/Electronics.
  3. "Data Slicer" section in Microchip document titled "PIC® MCU Comparator Tips ‘n Tricks".

If you liked this article, please consider supporting my efforts by purchasing my book.

Python Playground, published by No Starch Press, USA, is a collection of imaginative programming projects that will inspire you to use Python to make art and music, build simulations of real-world phenomena, and interact with hardware like the Arduino and Raspberry Pi. Do check it out!