Building a photobooth with Raspberry Pi and a toy microwave

A few weeks ago I found an old first-generation Raspberry Pi hiding in a closet. At the same time I started investigating WordPress REST API at work. I also wanted an excuse to buy a Dremel. Everything seemed to align when I was strolling by the local Goodwill where my wife found an old toy microwave. Perfect excuses assembled, I had to buy a Dremel to fit a Raspberry Pi, its camera and a screen in a toy microwave to build a photobooth machine.

Several nights after, the hardware is ready. I found a used Dremel on Craigslist: great machine to cut the plastic quickly. I carved an opening in the microwave’s front door and mounted the Landzo display on it. For holding the Pi in place, I used a very low tech hack of wood sticks and glue, plus a rubber band. Unfortunately the first-gen Pi doesn’t have mounting holes on its base and I didn’t want to spend more money on a case. Good enough.

The microwave came with buttons and a LED that I connected to the board’s GPIO: the Start button starts the photobooth app, and the LED blinks while taking pictures. There are 4 more buttons that I will probably connect too for something fun, like show a video of actual food being cooked in the microwave… something for version 2 though.

In the next post I’ll talk a little more about the Python code I modified to use WordPress REST API.

Configure Landzo 7″ Display for Raspberry Pi

I’ve started building a photobooth using one of the first generation Raspberry Pi I found in a drawer. More details are to come. Meanwhile, here are some notes to configure the Landzo 7″ touchscreen display.

The display is sold as compatible with Raspberry Pi and probably it is but it didn’t work out of the box. The box comes with a CD-ROM but I don’t have any way to read that old stuff anymore. The landzo.com website doesn’t seem to host the content of that CD-ROM either.

The Pi doesn’t use the correct video modes for the display out of the box so I had to read the documentation. The gist of it is that you need to add a new custom mode to /boot/config.txt as below:

# uncomment to force a specific HDMI mode (this will force VGA)
hdmi_group=2
hdmi_mode=1
hdmi_mode=87
hdmi_cvt=800 480 60 3 0 0 0

If you’re interested, here is how I got to those numbers. I rebooted the Pi in VGA mode (hdmi_group=1 & hdmi_mode=1) and then ran the tools to interrogate the display:

pi@raspberrypi:~ $ /opt/vc/bin/tvservice -d edid.dat
Written 128 bytes to edid.dat

Parsed the file with the edidparser:

pi@raspberrypi:~ $ /opt/vc/bin/edidparser edid.dat 
Enabling fuzzy format match...
Parsing edid.dat...
HDMI:EDID version 1.3, 0 extensions, screen size 15x10 cm
HDMI:EDID features - videodef 0x80 !standby !suspend !active off; colour encoding:RGB444|YCbCr422; sRGB is not default colourspace; preferred format is native; does not support GTF
HDMI:EDID ignored unknown descriptor tag 0x10
HDMI:EDID ignored unknown descriptor tag 0x10
HDMI:EDID ignored unknown descriptor tag 0x10
HDMI:EDID does not yet know monitor vertical range, setting to default 24 to 120Hz
HDMI:EDID failed to find a matching detail format for 800x480p hfp:40 hs:48 hbp:40 vfp:13 vs:3 vbp:29 pixel clock:32 MHz
HDMI:EDID calculated refresh rate is 66 Hz
HDMI:EDID guessing the format to be 800x480p @70 Hz
HDMI:EDID found unknown detail timing format: 800x480p hfp:40 hs:48 hbp:40 vfp:13 vs:3 vbp:29 pixel clock:32 MHz
HDMI:EDID established timing I/II bytes are 00 00 00
HDMI:EDID standard timings block x 8: 0x0101 0101 0101 0101 0101 0101 0101 0101 
HDMI:EDID adding mandatory support for DMT (4) 640x480p @ 60Hz
HDMI:EDID filtering formats with pixel clock > 162 MHz or h. blanking > 1023
HDMI:EDID no known preferred format has been set
HDMI:EDID filtering preferred group has been changed from Invalid to DMT
HDMI:EDID best score mode initialised to DMT (4) 640x480p @ 60 Hz with pixel clock 25 MHz (score 0)
HDMI:EDID best score mode is now DMT (4) 640x480p @ 60 Hz with pixel clock 25 MHz (score 36864)
HDMI:EDID preferred mode is updated to DMT (4) 640x480p @ 60 Hz with pixel clock 25200000 Hz
HDMI:EDID has only DVI support and no audio support
edid_parser exited with code 0

From there I saw this interesting line:

HDMI:EDID guessing the format to be 800x480p @70 Hz

I know the display’s resolution is 800×480 so that has to be my clue for the new mode. The docs gave me the rest.

hdmi_cvt=<width> <height> <framerate> <aspect> <margins> <interlace> <rb>

Value Default Description
width (required) width in pixels
height (required) height in pixels
framerate (required) framerate in Hz
aspect 3 aspect ratio 1=4:3, 2=14:9, 3=16:9, 4=5:4, 5=16:10, 6=15:9
margins 0 0=margins disabled, 1=margins enabled
interlace 0 0=progressive, 1=interlaced
rb 0 0=normal, 1=reduced blanking

The next challenge is to enable the touchscreen: the driver is probably in the CD-ROM and I haven’t found it online yet.

Streaming Audio from Raspberry Pi – part 2

Episode two of my experiment with the Raspberry Pi I have received at Pycon 2013. On the way back from Santa Clara I stopped by Fry’s and bought the only USB sound card they had in store, a weird looking Creative and a powered USB hub.  I ordered also a case from Adafruit industries (not convinced of the case though).

Raspberry Pi and USB sound card
The output of lsusb:

Bus 001 Device 006: ID 147a:e03d Formosa Industrial Computing, Inc.

Hooked them all together, installed avahi-daemon on the Pi so I can ssh into it easily from any lan (ssh raspberrypi.local, although I should change its name to something more unique). Tested arecord locally first. It took me a while to figure out how to use arecord, it’s old stuff that I’m not very used to. You need to specify the hardware device. If you get this sort of error:

arecord: main:682: audio open error: No such file or directory

probably you haven’t specified that you want to record from the card that actually has an input device

pi@raspberrypi ~ $ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: Audio [2 Channel USB Audio], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0

I hooked my phone’s audio player to the mic input of the USB card so that there would be constantly audio coming in the Pi, then started recording

pi@raspberrypi ~ $ arecord -D hw:1,0 -f s16_le -c 2 > test.wav

I have specified the hardware device I want to use, the format and the number of channels. Playing back that file worked.

pi@raspberrypi ~ $ aplay -D hw:1,0 test.wav

Next step was to capture live audio from the line input of the USB card, transcode that to OGG Vorbis and ship the bits to the remote Icecast server I setup last week. I quickly gave up on ezstream and started using ices2, the Icecast client: it seems easier to manage as it takes care of the encoding. This is the input module I used for the Pi:

<input>
<module>alsa</module>
<param name=”rate”>16000</param>
<param name=”channels”>2</param>
<param name=”device”>hw:1,0</param>
<!– Read metadata (from stdin by default, or –>
<!– filename defined below (if the latter, only on SIGUSR1) –>
<param name=”metadata”>1</param>
<param name=”metadatafilename”>liveaudio</param>
</input>

The USB soundcard I’m using sends 16000hz samples. I chose not to resample that, only to downmix stereo to mono to save bandwidth.

<–  stereo->mono downmixing, enabled by setting this to 1 –>
<downmix>1</downmix>

And all seems to work: the Pi sends a clear signal up to the streaming server and it’s been doing that for a while. Big success so far. Next step for me will be to write a script that grabs data from the OpenStack Summit schedule for one room and adds that information as metadata for the streaming: this way the listeners will have an idea of who is speaking or what the session is about.

Update: the stream was having a wide latency, around 20 seconds so I decided to play a little bit with the sampling rates. The latency went down to around 1 second using  <param name=”rate”>48000</param> in the input module and  <samplerate>48000</samplerate> in the encode module, with no resampling. Unfortunately the USB card dies every now and then when not connected through a powered USB hub. Too bad, because the USB hub looks ugly.

Simple live audio streaming from OpenStack Summit using RaspberryPi

I have always wanted to have a simple way to stream audio from the OpenStack Design Summits, much like Ubuntu used to do for its Ubuntu Design Summit. Since every participant to Pycon 2013 was kindly given a Raspberry Pi and having a couple of hours to kill, I have started playing with a simple idea: configure a Raspberry Pi to capture audio and stream it to a public icecast server.

First thing: spin up a virtual machine on a public cloud that will be serving as public icecast server. I have used my UniCloud account, created a small server, 512Mb ram, Ubuntu LTS 32bit. I updated the default security groups to allow traffic on port 22 (SSH) and 8000 (icecast), and I also needed to assign a public floating IP.  Once the machine is up, simple apt-get install icecast2 took care of starting the audio streaming server. That’s it, streaming server part is done.

Back to the RasPi, in order to test the streaming server, I installed ezstream, copied the config files from /usr/share/doc/ezstream/examples. I copied ezstream_vorbis.xml to pi home dir:

<ezstream>
<url>http://INSTANCE_NAME:8000/armin</url>
<sourcepassword>TheSecret</sourcepassword>
<format>VORBIS</format>
<filename>playlist.m3u</filename>
<!– looping the stream forever, for testing purposes –>
<stream_once>0</stream_once>
<svrinfoname>OpenStack Test Streaming Rradio</svrinfoname>
<svrinfourl>http://radio.openstack.org</svrinfourl>
<svrinfogenre>OpenStack Test Streaming</svrinfogenre>
<svrinfodescription></svrinfodescription>
<svrinfobitrate>320</svrinfobitrate>
<svrinfochannels>2</svrinfochannels>
<svrinfosamplerate>44100</svrinfosamplerate>
<!– advertising on public YP directory –>
<svrinfopublic>1</svrinfopublic>
</ezstream>

The playlist.m3u is a simple text file with one .ogg file in there, enough to test it. Start the stream to be sent to the icecast server with

ezstream -c ezstream_vorbis.

And go play the audio in your favorite icecast player, the URL is something like http://YOUR_INSTANCE_NAME:8000/vorbis.ogg.m3u

Simple, rudimentary but I like because it seems to be easy. The next step for me is to buy a USB microphone to stream live audio captured in a room. The optimal configuration though is to use this system to stream audio easily from the OpenStack Summit rooms. I need a way to connect the USB input to a regular audio mixer: any idea on how to do that?