2

I have a Raspberry PI Zero W and Light Sensor like on the photo: enter image description here

I connected it to Raspberry Pi as follow: GND to GND VCC to 5V SIG to GPIO-3

Using the following code below I am able to detect if its dark or bright outside (by covering the sensor with my hand):

    import RPi.GPIO as GPIO
    from time import sleep
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(3, GPIO.IN)

    for i in range(0,5):
        print ( GPIO.input(3))
        sleep(1)

This gives me an output of either 1 or 0. It depends on the light condition. I would like to be able to get more detailed data than just 1 and 0, e.g power of light lux or something so I can track how much sun my plant is getting at the current time.

Is there something I can upgrade within my code or the issue is that the sensor is analog and Pi is digital?

1
  • 1
    your last few words hit the target .... you need a sensor that produces a digital data signal or you need to use an ADC (analog to digital converter)
    – jsotola
    Commented Mar 19, 2020 at 0:22

1 Answer 1

2

The module you have includes a resistive sensor and a comparator which produces a 1-bit value (0 or 1). There's nothing you can do to get a more detailed signal from that module.

There are two main approaches which allow to read analog values from resistive sensors with devices which don't have analog pins, such as raspberries.

  1. External ADC:

schematic

simulate this circuit – Schematic created using CircuitLab

Conceptually, this is a voltage divider which converts the variable resistance of the LDR into a variable voltage, and then the voltage is sampled by the ADC (PCF8591, ADS1x15, MCP3002 just to name a few) and transmitted to the Raspberry in the form of a digital signal (I2C, SPI, etc.) This is the proper way that achieves good precision and fast conversion time.

Here's a tutorial for ADC1015, explaining how to connect it to the Raspberry and read the analog values.

  1. Poor man's ADC (based on a step response):

schematic

simulate this circuit

This is also a voltage divider, but since a capacitor is used for the lower leg, the voltage rises with time, so that the sensor resistance becomes inversely proportional to the pulse length. The measurement cycle consists in driving the GPIO pin LOW to discharge the capacitor, then switch it to input and measure the time it takes for the pin to go from LOW to HIGH:

def discharge():
  GPIO.setup(ldr_pin, GPIO.OUT)
  GPIO.output(ldr_pin, False)
  time.sleep(0.01)

def pulse_length():
  count = 0
  GPIO.setup(ldr_pin, GPIO.IN)
  while not GPIO.input(ldr_pin):
    count = count + 1
    time.sleep(0.001)
  return count

def analog_read():
  discharge()
  return pulse_length()

Obviously, this is much slower and less precise than using a real ADC, but it requires a minimum of external components. Here is a detailed description of this approach including some code samples.

2
  • thank you for your clarification. It must be enough for me for now. I will use it to trigger remote camera to stop taking photos at night, and meantime will order ADC from china. Just wonder how many modules I can stack on my raspberry Pi as I already got wittyPi 2 sitting on it :)
    – novak100
    Commented Mar 19, 2020 at 8:29
  • @novak100 Every connector is an extra point of failure, so at some point you should solder stuff together. Also note what the first sentence says: you cannot use this module to get analog light values. You need a bare LDR. Commented Mar 19, 2020 at 8:33

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.