At a recent meeting, some ideas for an office event were being discussed, and people were considering hiring a photo-booth for the evening. I had a huge lightbulb moment: we’ve had a photo booth in the office and at some staff events already — why do we keep paying other people to do this? Surely we can create our own for a fraction of the cost?
How hard can it be?
This is the question I set out to answer in our most recent Hack Day.
I decided to tackle the problem with the following goals in mind:
- don’t be expensive
- be as portable as possible
- be maintainable by my peers
- be fun!
I’ve had some experience with the Raspberry Pi over the last few months. I purchased one last October, planning to run it as a media-centre in my home. This is one of the few projects I’ve had that made it past the planning stage.
I still consider my main technical skill to be my perl programming ability. I didn’t have the time or inclination to learn python — one of the suggested languages for writing applications for the Pi.
Many of my peers are also fluent in perl, making future maintenance much easier.
Once I’d assembled the Pi, I installed Raspbian, then used perlbrew to install my own non-system, up-to-date perl to work with. At this point I made an image of the SD card, giving me a good recovery strategy should anything untoward happen.
Next, following some research, I decided to install SDL as my basis for the application interface; quite a leap from the command-line and HTML world I’m used to developing for.
Because the Pi isn’t meant to behave like a supercomputer, I performed these steps over a week before the hack day was due to start. There’s nothing more frustrating than spending your shiny hack-time preparing your environment and having no time to do anything fun.
This was a very good decision; I had to leave perl building overnight, then SDL and its dependencies were also left installing overnight. One test script in the process reached 800,000 tests with no end in sight. I elected to take the “risky” route and complete the installation using cpanm with the “
Time for another image of the SD card!
Ready To Hack!
Well, almost. Before I committed to this idea I wanted to be sure that I could make something basic appear on the screen and at least have a clunky method for capturing images from the camera module.
Once I’d done this I forced myself to step away from the device. I had an environment that was ready for me to work on the idea — anything more in advance of the hack day would be “cheating”.
Hacking – Day One
The first thing I did in the morning was try to sketch out the layout of the interface, and make some of the calculations for the placement of the various areas of interest. Although “
xwininfo -root” was reporting a specific resolution I was aiming to make the layout somewhat flexible — I couldn’t be certain that the application would always be running on the same resolution.
A lot of the working day was spent pair-programming with my co-worker Gianni.
Through the day we tackled a number of issues:
I don’t know if there were connection or DHCP issues but I struggled to maintain a connection with the USB WiFi device. I fell back to using an ethernet connection during the project.
Despite seeing the device detected, and despite
evtest reporting actions from the game pad, we were unable to get SDL to react to anything from the controller. During development
xdotool was used to send key-press events and the demo mode didn’t require any input at all.
Preview in wrong place
For some reason the preview from the camera was using the same location and dimension co-ordinates as the screen layout, but was displaying offset from where it should have been showing.
It seems that I’d managed to mix up X’s resolution with the framebuffer’s; the app was using one, and the camera preview the other. This was resolved by switching to a monitor that was supported out of the box and didn’t letterbox the X desktop.
While using the camera module, it was apparent that something wasn’t quite right. The preview mode before taking a shot appears to have some digital zoom applied to it. If you watch carefully, you’ll see this in the demo video at the end of this posting — the video is zoomed for the preview and flicks back to the actual capture for a fraction of a second as the image is captured.
raspistill, the recommended tool for controlling the camera, led to a
system() call from the application. This isn’t good practice in general, and is made worse because a 5-second preview means we’re blocked waiting for the >5-second
system() to complete.
Gianni suggested we investigate using v4l2 as a possible solution for the preview zoom and maybe as an alternative, non-blocking method for controlling the preview and image capture.
Using v4l2 confirmed the preview-zoom issue was at the kernel/firmware level.
It did allow us to enable and disable the preview overlay at will, without blocking on a
v4l2 preview location
Frustratingly, we were unable to relocate the preview overlay location and dimensions — despite the tools making it look like we ought to be able to.
Rather than spend hours going down rabbit-holes instead of making progress with the hack, I decided to redesign the screen layout to accommodate the stubborn overlay. You can see this if you compare the design sketch and the final demo video.
Day One End
I worked a bit late at the end of the day to rework the layout and have the project in a moderately good condition leading in to the second day.
To mark the end of the day, I recorded a short video which, through the medium of Auto-Awesome, Google+ turned into a cheesy montage for me to share.
After a sleepless night, thanks to a brain buzzing with ideas and improvements for the hack, I decided to tackle the following tasks on the morning of the second day:
- hide the annoying mouse cursor
- give the app a more professional appearance
- tidy up and refactor some of the clunky implementation details
- add a
--demomode to turn the booth into its own presentation
- boot straight into application
The afternoon was reserved for final tweaks for the presentation. The last thing I wanted was to break everything just before it was time to share my work.
I timed how long it took for the device to boot, the app to load and the demo to complete: a couple of seconds over the two-minute limit. I was happy with this if I had the opportunity to do a live demo.
Being the paranoid type, I wanted a backup plan in case a live demo wasn’t possible. I recorded myself running the boot-demo at my desk and uploaded it to YouTube.
The choice of connector prevented a live demo later in the day… so glad I had the backup plan!
I don’t know what, if any, future there is for this project. It’s “functional enough” and with a little more time could be a very fun product to roll out at events and parties. The size of the unit and camera mean it could be presented in any number of ways: a proper booth; a life-size cut-out with a camera in one eye; peering out of a shoe box.
I don’t want to do too much extra work until the preview bug is resolved. For me, this issue really detracts from the experience and makes the product look unfinished.
Lastly, the application code is a bit of a hack in places and should be reworked to use SDL events more and
sleep() a lot less.
Bill of Materials
If you’re interested in playing with any or all of the kit mentioned here, you can purchase everything through Amazon UK.