2013-03-17

Those old coin-op photobooths are awesome. Sit down, close the drape, put some money in the coin slot, and in a few minutes you will have some memories in your pocket. Why can't I have one of those? Oh yea, because they take up a lot of room, use stinky chemicals, and I have no idea how to build one. Fortunately, I have some computer skills.

The Mission

if

Yea, that's a big if. If I had it my way, I'd make an art installation piece that was a digital photobooth with a built in webserver, so that after pictures were taken, one would connect to the photobooth over the internet and download pictures. Unfortunately, I don't have the room or the tools to make a photobooth, but I can get cracking on a much smaller, yet curiously similar project that focuses on the computer and software aspect of a digital photobooth.

The Computer

The computer for this project is a Rev 2 Raspberry Pi. See that little wood block that the computer is screwed to? Good. The Rev 1 Raspberry Pi didn't have any mounting holes and it made putting the device into a custom enclosure a real pain in the ass. The Rev 2 only has two mounting holes and a small block of wood was used for both holes.

I'm still waiting for a apology for the lack of mounting holes fiasco. Oh yea, this computer's name is 'shitbird' because I couldn't come up with another name

The Case

A few years back, my buddy gave me two almost fancy Wild Turkey boxes. One box was used for my media machine, the other was used for this project.

A bit of hot glue affixed the wood blocks to the inside of the case.

Notches were cut in the sides of the box to handle cabling.

This case is far too big for this project, but I really wanted to make it and this is what I had kicking around .... so tough!

Big Red Switch

This switch is identical to the emergency 'play Black Sabbath' button, and it is mounted on my wall near the heater and some sweet rotary phones. For input, the switch is connected to the Raspberry Pi on GPIO pins 5 and 6.

The Camera

In a few days time, a 5 megapixel camera will be arriving at my home, but for now I'm using this less than ideal 640x480 logitec webcam that has been placed on a shelf next to some sweet rotary phones.

To be honest, everything in my home is "near" a sweet rotary phone (or two).

Nesting in the corner

Oh hey, is that a Raspberry Pi on your wall? Yes, yes it is.

If my home were a Federation Star Ship, that corner would be the Engineering Department. beep boop.

Aside from a bunch of sweet rotary phones, there is lantern that can be controlled over the network, and there is a toaster with a postcard on it. RAD!

Code

So it is built and all in place. What does it do?

The computer is running Arch Linux and the software for this project is written in the Ruby programming language without any third party libraries. However, in order to take a picture, the code makes a system call to fswebcam which is easily installable from the Arch Linux software repositories.

Pressing the big red button takes a pictures and saves the picture in a local directory. The code also contains a basic webserver that makes accessing the saved images a snap. Included in the webserver is a simple way to make the computer take a picture. This can be accomplished by directing a web browser to http://NAME_OF_COMPUTER:8080/capture

Enter the Ruby

#!/usr/bin/env ruby

require 'webrick'
require 'thread'
require 'observer'

#we might be testing
@@TESTING ARGV[0].nil? false true

##define some variables
this_dir File.dirname(__FILE__)
@@public_dir File::join(this_dir,"public")
@@captures_dir File::join(@@public_dir"captures")

class Switch
  include Observable  #instances will be watched!
  def initialize()
    #init the switch GPIO
    @io #this is pin 7 on a Rev 2 Raspberry Pi
    @value_file "/sys/class/gpio/gpio#{@io}/value"
    @value
    #clean up first
    unless @@TESTING
      clean_up()
      File.open("/sys/class/gpio/export","w"do |f|
        f.puts(@io)
      end
      #set direction to in
      File.open("/sys/class/gpio/gpio#{@io}/direction""w"do |f|
        f.puts("in")
      end   
      #record the initial value
      @value get_value()
    end
  end
  
  def get_value()
    unless @@TESTING
      value File.read("/sys/class/gpio/gpio#{@io}/value").chomp()
    end
  end
  
  def run()
    puts "running switch"
    running true
    thread Thread.new() do
      while running
        #poll the value
        value get_value()
        if value != @value
          @value value
          #emit the value
          changed
          notify_observers(self@value)
        end
        sleep 0.1
      end
    end
  end
  
  def clean_up()
    unless @@TESTING
      File.open("/sys/class/gpio/unexport","w"do |f
        f.puts(@io)
      end
    end
  end
end

class PictureTaker
  def initialize()
    'creating picture taker'
  end
  
  def switch_changed(switchvalue)
    if value == "1"
      puts "value: #{value}"
      take_picture
    end
  end
  
  def server_wants_capture(servervalue)
    if value
      take_picture
    end
  end
  
  def take_picture    
    now Time.now.strftime("%Y%m%d%H%M%S")
    puts now
    new_file File::join(@@captures_dirnow+".png")
    cmd "fswebcam -r 640x480 -S 3 -F 2 --no-banner --png 7 --save "+new_file
    #run the command
    start Time.now
    IO.popen(cmddo |f|
      output f.gets
    end
    return (Time.now start).to_s
  end 
  
end

if __FILE__ == $0
  pt PictureTaker.new
  sw Switch.new
  sw.run
  #watch for a switch press
  sw.add_observer(pt:switch_changed)
  #make a webrick server
  server WEBrick::HTTPServer.new({:Port=>8080,:DocumentRoot=>@@public_dir})
  #what server actions do we have?
  server.mount_proc('/capture'do |reqresp
    resp['Content-Type'] = 'text/plain'
    resp.body pt.take_picture
  end

  running true
  trap "SIGINT" do 
    server.shutdown
  end
  
  server.start
  
  sw.clean_up()
  
end

For easier copy and paste, the code is available at http://hoof.jezra.net/snip/ob

What's next?

Aside from waiting for the 5MP camera...

There are still plenty of unused GPIO pins on the computer and there is a lot of unused space in the computer case. It should be possible to find something else to do with the computer.

  1. upload captured images to somewhere on the internet
  2. have the motion detecting toaster tell the picture taker to take (and upload) pictures when motion is detected.
  3. Always skip step 3
  4. enjoy a bit of home security

Now quit reading, and go take a picture.

Comments
2013-06-06 Karl:
Hi mate, I absolutely love this idea, and am thinking of making something similar myself, would it A, be ok to use your stuff and B, should I be able to get it all working using the bits you have listed on here?

great work!

Karl
2013-06-06 jezra:
Hi Karl.
A: Yes
B: Yes

let me know what you create.
2013-12-03 chris:
I really love this example of fun things to do with a raspberry pi. I am fairly new to this stuff and want to reproduce what you have done. What type of button are you using and did you wire it directly from the button connectors to the GPIO pins?
2013-12-03 jezra:
Hi Chris,
I use a fairly generic big red button switch, and just about any button/switch would work for this. There are 2 or 3 pins on the RPi that can have a switch directly connected, and in this case, it is pin 7.
2014-06-27 Jones:
Can you explain me, how I insert the code in the raspberry, please?
I need a programm?
Sorry, i'm noob in this stuff....
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
3 minus 0
Answer:
required
subscribe
 
2014
2013
2012
2011
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008