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
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 = 3 #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()
p 'creating picture taker'
end
def switch_changed(switch, value)
if value == "1"
puts "value: #{value}"
take_picture
end
end
def server_wants_capture(server, value)
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_dir, now+".png")
cmd = "fswebcam -r 640x480 -S 3 -F 2 --no-banner --png 7 --save "+new_file
#run the command
start = Time.now
IO.popen(cmd) do |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 |req, resp|
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.
- upload captured images to somewhere on the internet
- have the motion detecting toaster tell the picture taker to take (and upload) pictures when motion is detected.
- Always skip step 3
- enjoy a bit of home security
Now quit reading, and go take a picture.
great work!
Karl
A: Yes
B: Yes
let me know what you create.
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.
I need a programm?
Sorry, i'm noob in this stuff....