Peter Stuifzand

Art and electronics project

A few weeks ago I created an art project together with my girlfriend involving video and electronics. I created the electronics part for her.

The technical part of the project was based on a simple idea. When someone walks by it should play a short piece of video.

The sensor

I made a sensor that notices changes in the light received. The idea is that when someone walks by the light falling on the LDR changes. The resistance of the LDR changes when the light changes. The change in resistance can be found out by measuring the voltage over the LDR.

Sensor schema

I used the K8055 to measure this voltage. It’s a Velleman Kit that can uses USB to communicate with a computer. One can read the voltage of the sensor with 8-bit precision using the analog port of the device.

The program

To control the K8055, I used perl and Device::Velleman::K8055 which is available on CPAN. It can only be used with Windows because it uses the Win32::API module. Also available from CPAN. There are libraries available for linux, but I didn’t use those.

The perl program loops and reads one value from the AnalogChannel using ReadAnalogChannel function each time it goes trough the loop. It takes the channelnumber as an argument. It saves the last few values. This ‘first’ value is used to check if the value has changed enough. If is has, the movie starts playing.

The movie is played using VLC player. This player has a HTTP server, so the movie it is playing can be started and stopped by send get requests to an URL. I used LWP::UserAgent for this.

The sourcecode

# Written by Peter Stuifzand
use strict;
use warnings;

use constant PAUSE_CHANNEL_WAIT_TIME => 0.4;
use constant WAIT_TIME               => 2;
use constant DIFF_NUM => 4;
use constant KEEP_VALS => 24;

use Device::Velleman::K8055 qw(:all);
use Time::HiRes qw/sleep gettimeofday tv_interval/;
use List::Util qw/sum/;
use LWP::UserAgent;

print "Test programma 4\n";
die "Can't open K8055 device" unless OpenDevice(0) == 0;

my $ua = LWP::UserAgent->new;

sub NextMovie {
    #$ua->post('http://localhost:13579/command.html', { wm_command => 921 });
    $ua->get('http://localhost:8080/requests/status.xml?command=pl_pause&id=4');
    return;
}

sub FlashDigital {
    ClearAllDigital();
    sleep(0.4);
    SetAllDigital();
    sleep(0.4);
    ClearAllDigital();
    sleep(0.4);
    SetAllDigital();
    sleep(0.4);
    ClearAllDigital();
}

# Start at the beginning of the movie. Sync.
$ua->get('http://localhost:8080/requests/status.xml?command=pl_seek&pos=0&id=4');

my $last_val = ReadAnalogChannel(1);
my @vals;

my $people_count = 0;

do {{
    my $val = ReadAnalogChannel(2);
    if (!@vals) {
        push @vals, $val;
    }
    # Other ways to calculate change
    #    my $avg = sum(@vals) / @vals;
    #    my $diff = abs($avg - $val);
    my $diff = abs($vals[0] - $val);
    printf "%3d %3d %3d\n", $val, $vals[0], $diff;

    push @vals, $val;
    if (@vals > KEEP_VALS) {
        shift @vals;
    }

    $last_val = $val;

    if ($diff >= DIFF_NUM) {
        $people_count++;

        my $start = [gettimeofday()];

        NextMovie();
        while ((my $diff = tv_interval($start) < 1.9)) {
        }
        NextMovie();
        my $diff = tv_interval($start);
        my $current_time = 2 * $people_count;
        my $current_time_s = $current_time % 60;
        my $current_time_m = ($current_time - $current_time_s) / 60;
        # Status information
        print "$people_count $diff s $current_time_m:$current_time_s\n";
        @vals = ();
    }
}} while (!ReadDigitalChannel(1));

CloseDevice();

Conclusion

I was inspired by the a few people to write this text. The first person is Bre Pettis who has an amazing video podcast about stuff that a person could make in the weekend. The other person was Danny O’Brien, because he talked about how we should publish more ideas, because it makes you look smart and organized.

© 2023 Peter Stuifzand