IR distance sensor

I want the (still to be added) display only to be powered up when someone is within the range of the device to save some energy. For the implementation of this function I decided to start with an already assembled IR distance sensor from Sharp.

As this sensor is an analog sensor the analog voltage out will range from 3V when an object is only 10 cm away and 0.4V when the object is 80 cm away. Unfortunately the Pi does not have any analog inputs.

My rescue was the great post from Matt @ raspberry-spy.co.uk, where he explains how to measure different light levels on the Raspberry Pi.

So I started from re-building his circuit and run some test measurements, this is how it looked on my breadboard.
LDR with capacitor

For a detailed overview including the Fritzing views please check out Matt’s post. Once I had replicated this set-up successfully I added the IR distance sensor.IR distance sensor on breadboard

With the following code I am able to count how many loops it takes until the capacitor voltage has increased enough to be considered as a HIGH by the GPIO pin (approximately 2V). The number of loops is proportional to the distance of an object in front of the sensor.

#!/usr/bin/perl

use Device::BCM2835;
use strict;

# call set_debug(1) to do a non-destructive test on non-RPi hardware
# Device::BCM2835::set_debug(1);
Device::BCM2835::init()
|| die "Could not init library";

# Variables
my $ir_pin = 24;
my $measurement =0;

# logfile handling
sub logging {

  my $logfile = "/appco.de/log/appco.de.log";

  if ( ! open LOG, ">>", $logfile ) {
    die "Kann Logdatei nicht anlegen: $!";
  }

  my ($sekunden, $minuten, $stunde, $tag, $monat, $jahr) = localtime;
  my $echtes_jahr = $jahr + 1900;
  my $echter_monat = $monat + 1;
  printf LOG "%s.%02s.%02s %02s:%02s:%02s %s\n", $echtes_jahr, $echter_monat, $tag, $stunde, $minuten, $sekunden, $_[0];
  close LOG;

}

while (1){
  # Discharge capacitor
  # Set GPIO pin to OUTPUT
  Device::BCM2835::gpio_fsel($ir_pin, BCM2835_GPIO_FSEL_OUTP);
  # Set GPIO pin to LOW
  Device::BCM2835::gpio_write($ir_pin, LOW);
  sleep (0.1);

  # Set GPIO pin to INPUT
  Device::BCM2835::gpio_fsel($ir_pin, BCM2835_GPIO_FSEL_INPT);

  $measurement = 0;

  # Count loops until voltage across
  # capacitor reads high on GPIO
  while (Device::BCM2835::gpio_lev($ir_pin) == 0){
    $measurement ++;
    sleep (0.2);
    # stop measuring after 100.000 loops
    if ($measurement > 100000){
      &logging ("canceled");
      last;
    }
  }

  &logging ("$measurement");

}

At the moment the sensor is always powered on, which is probably wasting more energy than I am intending to save by the use of the sensor.

For the future the sensor should only be powered up when the PIR sensor detected a movement and I also want to replace the ootb sensor with a much cheaper solution made out of IR LEDs and an IR receiver.

One thought on “IR distance sensor

  1. Pingback: Raspberry Pi and sensors | appco.de

Leave a Reply

Your email address will not be published. Required fields are marked *