I have this simple light sensor project using LDR. The PIC reads an analog signal 0-5V from LDR and will turn on the relay ON when it's bright on and off when it's dark. I want to add a simple LED indicator that will turn ON when the LDR is broken or something, but I don't know how to do it.

My circuit


3 Answers 3


I want to add a simple LED indicator that will turn ON when the LDR is broken or something

Actually driving the LED indicator is the easy part, of course. Depending on the expected light output from the "LDR fault detected" LED, then a drive transistor might not be needed.

For detecting that the LDR is "broken or something", you need to decide exactly what means "broken or something", especially the "something". I have only seen LDRs fail open-circuit (due to fractured elements), but there might be other failure modes.

Here are 2 quick approaches, which you can investigate and modify to fit your overall design constraints:

  1. Use an LDR whose dark resistance can still be easily detected as different from an "open-circuit". That way, you would still expect to get an ADC output below the maximum value, when used in that potential divider with R1.

    For example, using an LDR with a 20MΩ dark resistance makes this much more difficult, especially using the 10-bit ADC in your PIC16F877A. Whereas an LDR with a 100kΩ dark resistance is much easier to distinguish from being an open-circuit, as you would not expect the ADC value to get close to its maximum value even when the LDR is in the dark.

  2. Or, more complex, but more flexible, you can test the LDR yourself, at your chosen interval.

    • Don't react to changes in your LDR-controlled ADC output immediately. Introduce a delay, so that your code does not report "light" during the test below.
    • Add a small green LED, under MCU control, which can shine on your LDR (green is a colour to which LDRs are typically most sensitive, around 550nm).
    • When you want to test the LDR, read the LDR's ADC value, power-on the small green LED and read the LDR's ADC value again. I expect that you will detect an LDR response within tens of milliseconds (depending on your LDR). Does the LDR's measured ADC value drop (indicating that it detects light and its resistance drops)? Yes - then the LDR is working. Then immediately switch off the green LED.
    • There will be a short delay before the LDR has gone back into its "dark state", after it has been tested by that green LED.

In that second approach, there are several variables you need to consider and adjust in your code, but that will allow you to fulfil an objective to test that the LDR responds to light.


I'm going to suggest an entirely different thought to consider which addresses itself to both the measurement for the purposes of on/off thresholds, as well as detecting both shorted and open cases for the LDR (broken or someone has a screwdriver shorting the contacts for some reason.) The idea works almost entirely independently from the specific LDR behavior, too. But it means a modification on your measurement system.

I'd like to suggest the following:


simulate this circuit – Schematic created using CircuitLab

First off, both \$V_{\text{ADC}_1}\$ and \$V_{\text{ADC}_2}\$ will each be, always, within the measurement range of your ADC inputs. Second, their difference, \$V_{\text{ADC}_1} - V_{\text{ADC}_2}\$, will be a linearized measurement of the exponential resistance behavior of the LDR to light. (Put another way, the BJTs take the logarithm of the collector current and therefore of the resistance, because that is what the \$V_\text{BE}\$ of BJTs do for you.) So it may be "nicer" in terms of how you interpret things within your software for thresholds. (\$R_1\$ and \$R_2\$ have almost no effect on this behavior.)

If the LDR is broken-open (or disconnected from the circuit), then \$V_{\text{ADC}_1}=V_\text{CC}\$ and \$V_{\text{ADC}_0}=0\:\text{V}\$ and you will be able to easily detect this issue.

If the LDR is broken-closed (or someone sticks a screwdriver across the leads), then \$R_1\$ and \$R_2\$ will be shorted and they will current-limit the "damage" to about \$10\:\text{mA}\$ and present \$V_{\text{ADC}_1}=V_{\text{ADC}_2}=\frac12 V_\text{CC}\$. That's also very easy to detect with your software.

That's more the approach I'd probably take. (Unless I missed something serious, here.)

I popped the above circuit (less the short circuit protection resistors) into Spice using a simulated LDR (which in this case goes from \$5\:\text{k}\Omega\$ in full light to \$2\:\text{M}\Omega\$ in full dark. The \$x\$-axis is the natural logarithm of the LDR resistance. The \$y\$-axis is \$V_{\text{ADC}_1} - V_{\text{ADC}_2}\$. I'm using non-ideal BJTs (2N2222A and 2N3906) at \$27^\circ\text{C}\$.

enter image description here

The above shows the linearity that the BJTs can confer to your ADC measurements. It should be very simple to write code so that you can ask the user to "calibrate," by applying a bright light and then covering it up into darkness, so that your software can capture the operating range for better repeatability during operation.

That said, the voltage difference offset will vary with operating temperature as both the BJTs (and also the LDR) have temperature dependences. Ignoring the LDR for a moment, the BJT variations from freezing to about \$55^\circ\text{C}\$ look like this:

enter image description here

So you can see that you may experience sufficient offset shift over temperature enough that a periodic one-point calibration might help. (You'd simply cover up the LDR to block light and tell the software to take a measurement that would be used to fix the dark end of the two-point calibration curve.)

The BJTs may be the least of the problem, though. The LDR also has a substantial variation over temperature. They really aren't designed for precision light/dark applications. So you need to take that into account, as well, and to improve its operation over various temperatures you may require a temperature sensor (which you'd use with an improved interpolation algorithm.)

The main point I was trying to get across is that the exponential behavior of the LDR resistance, with respect to light, can be easily linearized before it is processed by the MCU. The nice thing about this is that there is, broadly speaking, a linear relationship between the logarithm of the LDR resistance and the logarithm of luminance. (Humans also have a kind of square-root function that arrives partly because of pupil dilation, and this will add yet another factor to consider.)

P.S. In the above plots, if you take \$e\$ raised to the \$x\$-axis value, you will get \$R\$ of the LDR.

  • \$\begingroup\$ I'm truly curious. How does this circuit linearize the LDR response? Q1 & Q2 function as simple diodes. Or: am I missing something? \$\endgroup\$ Nov 8, 2019 at 2:29
  • \$\begingroup\$ @DwayneReid You are missing something. Let me post a Spice run for you. \$\endgroup\$
    – jonk
    Nov 8, 2019 at 3:02
  • \$\begingroup\$ @DwayneReid It's been added. Hopefully, that helps somewhat. The basic idea is that in a BJT the \$V_\text{BE}\$ is proportional to the logarithm of the collector current. \$\endgroup\$
    – jonk
    Nov 8, 2019 at 3:11
  • \$\begingroup\$ Thank you very much. Your answer is very informative. But I want to ask why use the linearity between VBE and Ic, and why not use simple linearity between V,I,R in Ohm's law. Is it because the Resistance of the LDR vary a lot? \$\endgroup\$ Nov 8, 2019 at 6:19
  • \$\begingroup\$ @LinhTrầnQuang The LDR resistance can, in practical situations, vary by three orders of magnitude. If you use it as part of a voltage divider, this means that the range of useful resolution (with an ADC) represents only a tiny part of the sensor's capability. \$\endgroup\$
    – jonk
    Nov 8, 2019 at 6:45

If "broken" means the LDR is an open circuit, then the voltage at your input would be 5V. You would monitor for that situation on the analog input, and write some code to light an LED.

Note that you're using the LED to generate light, not as a sensor.

  • \$\begingroup\$ Ah I want to use 2 Led. This Led is the main Led for lighting, and a small red Led I want to add to detect broken aka open circuit. The problem is, normally if it's dark, the LDR behave like an open circuit because of its high R, I don't know what kind or design or code to make circuit distinguish it. \$\endgroup\$ Nov 7, 2019 at 17:03
  • 1
    \$\begingroup\$ Do you mean you want to use an LED to excite your LDR, and light up another LED if it isn't working?? You're not being particularly clear. Please edit to explain your situation to someone who isn't familiar with it. \$\endgroup\$ Nov 7, 2019 at 17:14
  • \$\begingroup\$ Ah I'm sorry for the confusion. The LED in this project is a LED for household lighting(Lamp Light) controlled by the PIC, which detect light intensity signal from LDR. I want to add a new,small red LED OR a Bell that will be turned ON when the LDR is broken. \$\endgroup\$ Nov 7, 2019 at 17:23
  • 1
    \$\begingroup\$ A warm welcome to the site, @LinhTrầnQuang. Please edit your question and add his new information plus much more explanation. Otherwise, you're asking people to piece together more of your question from lots of comments. Thanks. \$\endgroup\$
    – TonyM
    Nov 7, 2019 at 18:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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