.
Who's a packrat? me, that's who. For about 8 years I've had a piece of antler stored under my bed because I figured that eventually I would find a use for it. Last week I received a Deschutes Brewery bottle opener from my buddy, and this morning I decided that "Today is the day"!
Oh Deer!
This piece of antler had previously been used to make a button for a rabbit sporran, but that is a tale for another time.
With my handy dandy generic rotary tool and a cutting wheel, the end of the antler was removed and I was ready to get on with the project.
De Shortened Dechutes Opener
De bottom of de opener was removed so it would fit a bit better in de antler handler. Thanks Dechutes!
I had forgotten how hot metal gets when being cut. Fortunately I have some crappy pliers that held de opener while I was cutting.
Speaking of forgetting...
Ready for the opener
After about 20 minutes of grinding, carving, and shaping the antler, I was ready to add the opener.
If you have never used a grinding wheel to cut antler, I highly suggest trying it because the stink is something everyone should experience. For the most part, the stench is reminiscent of concentrated burning hair. Yum! How did I forget that smell?
Epoxy
A bit of epoxy was applied to the opener, which was then placed in the antler. A few pieces of masking tape were used to keep the epoxy from running out and getting all over the place.
Success!
A quick jaunt to the store... and I was the proud owner of a sixer of Anchor Steam and a lotto ticket.
Yea, that's my dinner: Ramen with broccoli, carrot, and tapatío; and an Anchor Steam.
Let me tell you about antler dust. That stinky crap gets everywhere, and if you happen to have a significant amount of facial hair, expect to collect a lot of stink on your face. blech!
As a wonderful sidenote: I can use this as a sgian-dubh when traveling by airplane. Double win!
Solitude is my muse, and taking things apart keeps me from getting depressed. However, it is still nice to hear other people say nice things so I decided to convert a toaster into an interactive art project that says nice things when something (usually me) walks in front of it.
The Build
TAKE IT APART!
The first step to any great project seems to begin with a bit of destruction. Good. Nothing really clears my mind like taking something apart. Yea, I laughed when I bought the toaster and I'm still laughing now.
The toaster was soon gutted and a bunch of innards where chucked in the waste bin.
Make some mounting thingies
For this build, I planned on using the Raspberry Pi from the NaNoBox and since someone is a hobby hardware hacker hater, there are no mounting holes on my Raspberry Pi. sigh. Who's a liar? ME (sort of). I said I wouldn't use the Raspberry Pi for a similar project. Fortunately, this project isn't too similar.
A small wooden block was epoxied to the toast box (at least that is my name for it). Similarly, a piece of thick plastic from VHS case was also epoxied to the toast box.
Circuit from the shell
Surrounding the toast box is the toaster shell, and this is the circuit board that was mounted inside of the toaster shell. On the circuit are 3 buttons and two LEDs.
After a bit of scratching at the circuit board and some soldering, the buttons and LEDs where ready to be wired up.
The circuit back in the shell
Oh man, look at that rat's nest of wires.
This is the inside of the shell with most of the wiring finished. This includes the PIR thingy. What's a PIR thingy you might ask? good question.
PIR Thingy
Hey look, kids, it's a PIR thingy! This Passive InfraRed sensor thingy was purchased at for 10 bucks.
A notch was cut in the toaster's lever channel and the PIR was hot glued into place. Damn, I love adhesives.
Sound!
My buddy gave me a small USB amplifier and speaker combo used for plugging into a mobile phone.
In my haste, I obliterated the amplifier before taking a pictures. What a shame. The wires on the amp were to frail for my needs so I soldered on some heavier wires for audio in, audio out, and the power connector. Since the amp was originally powered over USB I figured I could wire it to the 5v pin on the Raspberry Pi. The speaker is from another portable amplifier.
Buckle up
Like I've said may times, the designer of the Raspberry Pi hates me and didn't include mounting holes on the board. Because of this, I needed to find a creative way to keep the board in place and my solution was a nice little 'belt'.
To keep the number of cable going to the toaster to a minimum, an old USB 802.11g was connected to the board.
Add some more LEDs
Aside from the two bright blue LEDs on the toaster shell, I added a green LED to each slot of the toaster box.
All Together
With much finagling, the toaster box and the copious amount of wires was stuffed into the toaster shell and the end result was put on a desk and pointed at the busiest foot traffic area of my home.
The toaster lever, although no longer in use, was hot glued back where it belongs and helps hide the PIR sensor.
What does it do?
When the sensor detects movement, an audio file is selected at random from a directory of audio files, and played through the speaker. While the audio is playing, the LEDs are flashing.
some of the setup
The code for running the toaster is written in python and utilizes gstreamer-0.10 for audio playing. In order to get gstreamer to default to playing through the 'audio out' on the Raspberry Pi, I had to edit the /etc/asound.conf file to look like the following:
pcm.mmap0 { type mmap_emul; slave { pcm "hw:0,0"; } } pcm.!default { type plug; slave { pcm mmap0; } }
Switches
Due to the lack of GPIO documentation for the Raspberry Pi, most tutorials for the device involved wiring in "pull-up" resistor which means that extra work is involved just to get a simple button press to register. However, pins 3,5,7,24, and 26 have built in pull up resistors which makes these pins ideal for connection switches.
Most (if not all) of the information I needed for programming the pins on the Raspberry Pi came from and not from the Raspberry Pi website. Seriously, this is wrong. The RPi website should have some useful information, but alas, it does not.
What's next?
The power for the amplifier was specifically not taken from the one remaining USB port. It would be fairly trivial to plug a USB camera into the USB and, when the PIR detects motion, have the camera take a picture and then upload the picture to a back up server. Hella cheap home security system. booyah!
Also, I need to figure out what to do the the buttons.
if your browser doesn't play ogg files, you should switch browsers
Why? Because if your browser doesn't play ogg:
- your browser hates freedom
- you won't be able to hear
duh!
The System
Like almost all of my computers, the toaster is running Arch Linux
Now quit reading and go make something...
"Talky's the name, toasting's the game."
For those that don't know, November is when NaNoWriMo (National Novel Writing Month) takes place and there is a poster on the wall of my work that tracks the progress of my coworker's word count. However, since I work from home quite a bit, the poster in the office doesn't do me much good.... time to create a device that allows me to track people's progress.
Hello NaNoBox!
The basic idea of of the NaNoBox is to use a mini computer to access the NaNoWriMo wordcount API and do the following:
- Every hour, get the current word count of a small list of NaNoWriMo participants
- Loop through the list of participants and:
- illuminate something that represents a NaNoWriMo participant
- show the progress of the represented participant as a percentage on an analog meter
The Hardware
Earlier this month I acquired a Raspberry Pi from, and I felt that the device would be ideal for this project.... I was wrong.
While I still used the Raspberry Pi for my project, I will never purchase another one, nor will I ever use the Raspberry Pi for another similar project.
Why I don't like the Pi
- There are no mounting holes. When I make a custom enclosure for a computer, I like to mount the motherboard on standoffs, and I can't do this with the Raspberry Pi. lame
- Handling PWM is not as simple as just writing to a file, and I needed to compile a 3rd party application to help me with PWM. I was spoiled by the Beaglebone
- The is little to no documentation for the Raspberry Pi at. Very lame
- Proprietary video drivers. Not a big deal for this project, but still less than ideal
Alright, that's enough complaining about the computer, let's get on with the build.
The Interface
At the suggestion of my friend who is a wood worker, I made a template of how I wanted the interface of the NaNoBox to look.
The Case
There is something about the scent of a nice cedar cigar box that tickles my brain.
This cigar box has been hanging out at my house for long enough. Time to chop it up.
Chop Chop
After laying out the design on the box, I used my poor selection of power tools to hack a bunch of holes in the cigar box.
The logo on the box was impossible to remove, but I sanded it down as best as I could.
Power
On the back of the box I drilled a hole for the power cable to go through.
Ewww, there is a sideburn hair in the picture
Stain
After much sanding, I stained the top of the box with the only stain I have (other than coffee), some red leather stain.
Diffused
On the inside of the box, I hot glued a piece of paper to diffuse light that shines upon it. What? you'll find out.
DVD Box
This is part of a DVD case. I like the way this plastic clip holds paper in the DVD case and I figure it would be a not too crappy way to hold the Raspberry Pi in place within the box.
Computer Mount
The DVD case clip was cut up and hot glued into the cigar box. See the black dots? LEDs will go there.
Like I said earlier, the lack of mounting holes is a serious downside of the Raspberry Pi (at least for the type of projects I like to do).
Put It On The Wall
Two screws and a bit of baling wire make for a great wall hanging bracket.
LEDs Wired Up
Here are the LEDs, soldered together and hot glued in place so that they shine through the square holes in the cigar box.
Voltmeter In Place
A 3.3V voltmeter was bolted into place, and an amber LED was hot glued over a small hole in the center of the box.
All Wired Up
The electronics are all done and ready to roll! I added a small 802.11n wireless USB adapter so that I wouldn't need another cable running to the computer.
Picture Holdy Thingies
Some thick paper was cut and folder in order to make holders for pictures that will be placed over the openings in the case.
Glued In Place
There it is! Two of the image holdy thingies were glued to the box for each of the images.
All Done
The pictures are in place and ready to light up.
The photographs are of my coworkers. The two other images represent podcasters that I listen too who happen to be participating in this years NaNoWriMo, and they are Thistleweb from Crivins and Moosical from The Bugcast.
Tim Kim
Hi Tim! Wow, I took a very unflattering picture of Tim for use in this project. Haha!
In Action
I dropped some test data into the code that runs the NaNoBox so that I could see the device in action before the event starts. When the participants get to 50,000 words, the amber LED in the middle of the box illuminates.
The Code
For this project, I decided to use Ruby because .... um... why not?
require 'open-uri'
require 'rexml/document'
class Pin
def initialize(num)
@gpio = num
#init this pin
`gpio -g mode #{@gpio} out`
end
def on()
`gpio -g write #{@gpio} 1`
end
def off()
`gpio -g write #{@gpio} 0`
end
end
class Nanobox
def initialize()
#keep it clean
clean_up()
#define the pins
@pins = [
Pin.new(4),
Pin.new(17),
Pin.new(23),
Pin.new(24),
Pin.new(25),
Pin.new(22),
Pin.new(21),
Pin.new(10),
]
#create the PWM on 18 (AKA pin 12)
`gpio -g mode 18 pwm`
end
def clean_up()
#unexport all of the assigned pins
`gpio unexportall`
end
def set_pwm_percent( num )
max = 1023
offset_percent = num*0.92
val = max*offset_percent/100
`gpio -g pwm 18 #{val}`
end
def read_config_file
this_dir = File.dirname(__FILE__)
config = File.join(this_dir, "users.conf")
@users = []
File.open(config) do |file|
file.each_line do |line|
if line.chomp != ""
user = {"name" => line.chomp}
@users << user
end
end
end
end
def update_wordcount_of_user(user)
begin
url = ""+user['name']
xml_text = open(url).read
doc = REXML::Document.new xml_text
if doc.root.elements['error'].nil?
wc = doc.root.elements['user_wordcount'].text.to_i/500.to_i
else
wc = 0
end
rescue
#do nothing
end
if wc > 100
wc = 100
end
@users.each_with_index do |u, i|
if u['name'] == user['name']
user['wc'] = wc
@users[i] = user
break
end
end
end
def update_all_wordcounts()
@users.each do |user|
update_wordcount_of_user(user)
end
end
def run
#read the config
read_config_file()
#do the initial wordcount update
update_all_wordcounts()
@running = true
update_wc_count = 0
count = 0
sleep_time = 5 #seconds
update_wc_count_max = 3600/sleep_time
current_pin = nil
while @running
unless current_pin.nil?
current_pin.off()
end
current_pin = @pins[count]
current_pin.on()
count+=1
update_wc_count+=1
if count >= @pins.length or count >= @users.length
count = 0
end
if update_wc_count > update_wc_count_max
update_wc_count = 0
update_all_wordcounts()
end
value = @users[count]["wc"]
if value >= 100
@pins[7].on()
else
@pins[7].off()
end
set_pwm_percent(value)
sleep 5
end
quit
end
def stop
@running = false
end
def quit
set_pwm_percent(0)
#turn off all of the LEDS
@pins.each do |p|
p.off()
end
#do some cleanup
clean_up()
end
end
if __FILE__ == $0
nano = Nanobox.new
trap("INT"){ nano.stop }
nano.run()
end
Yup, that's some ugly, uncommented code. While parsing the XML that gets returned by the Word Count API, I realized that I don't like processing XML in Ruby, and then I had an epiphany: XML is very consistant, I dislike parsing it in any language. ZING!
Wait a second. Don't I have more coworkers? Why aren't they represented in this project? Yes, I do have more coworkers, but the cigar box has a very limited amount of space. Fortunately, I have enough components to make another NaNoWriMo status tracker. Time to get to the drawing board.
Now quit reading, and get ready to start procrastinating.
You probably are already aware of this, but the latest rev of the Raspberry Pi has mounting holes (just got mine today!).
Also, have you checked out Adafruit's modification of Raspbian, called Occidentalis? They've done some stuff to make the GPIO stuff more useful, including PWM. I don't really understand that stuff, but perhaps a real hacker such as yourself will find it useful:
It doesn't sound like they intend to maintain it like a real distro, but it looks useful for single purpose projects.
Maybe some day they'll get around to proper documentation . . . seems like a genuinely useful open graphics driver isn't going to happen though.
Regards,
d-r
The idea of installing as full Desktop distro just to get decent PWM support is not for me. I'll stick with the BeagleBone
Earlier this month, I received a 3V Voltmeter that I purchased on Amazon. The reason for the purchase was so that I could write some code to control the voltmeter from my beaglebone. Well hey! Guess what I finally got around to doing?
Before I get to the code, let me explain how this works, and I'd like to give a big shout out to gigamegablog for being such a great resource.
Controlling the voltmeter with the beaglebone requires a bit of understanding of Pulse-Width Modulation (PWM). The pins on the beaglebone are capable of outputting 3.3V of power. By using PWM we can send the 3.3V of power in pulses, and when these pulses are spaced apart properly, we give the illusion of a lower voltage.
The Pin Layout
According to the beaglebone documentation, pins 14 and 16 of pin header P9 on the beaglebone are PWM pins. It should be possible to use other pins as PWM pins by "muxing" the pins, but for my needs, pin 14 will do just fine.
The positive probe of the voltmeter was connected to pin 14 on P9 and the ground was connected to pin 2 on P9.
The First Test
Since I am runnin Arch Linux on my beaglebone, PWM is not only supported in the kernel, it is also enabled. Rad, that is one less step to take. Thank you Arch Linux!
The test went like this :
- su to become root
- mux pin 14, just to be sure:
echo 6 > /sys/kernel/debug/omap_mux/gpmc_a2
- set the duty_percent to 0 (this is the percent of the 3.3V that we want to emit):
echo 0 > /sys/class/pwm/ehrpwm.1:0/duty_percent
- set the period frequency to 100 (this is the 'pulse' ins Hz):
echo 100 > /sys/class/pwm/ehrpwm.1:0/period_freq
- start the PWM pin running:
echo 1 > /sys/class/pwm/ehrpwm.1:0/run
- start increasing the duty_percent until the voltmeter is at 3V. For me, this was when the duty_percent was 92
Sweet!
Getting Data To Process
Since I didn't want to do any web server configuration in order to get data, I decided to write a very small WSGI app in python and serve it up using the wsgiref.simple_server class.
Enter the Python
from wsgiref.simple_server import make_server
#define some stuff
max_val = 92
pin_path = "/sys/class/pwm/ehrpwm.1:0"
run = pin_path+"/run"
duty_percent = pin_path+"/duty_percent"
period_freq = pin_path+"/period_freq"
#mux the pin
try:
f = open("/sys/kernel/debug/omap_mux/gpmc_a2","w")
f.write("6")
f.close()
except Exception, e:
print e.message
def set_run( val ):
try:
f = open(run,"w")
f.write( str(val) )
f.close()
except Exception, e:
print e.message
def set_duty_percent(val):
try:
f = open(duty_percent,"w")
f.write( str(val) )
f.close()
except Exception, e:
print e.message
def set_period_frequency(val):
try:
f = open(period_freq,"w")
f.write( str(val) )
f.close()
except Exception, e:
print e.message
#set some PWM values
set_run(0)
set_duty_percent(0)
set_period_frequency(100)
set_run(1)
def got_value(val):
val = val.strip("/")
val = int(val,10)
percent = (max_val * val/100)
set_duty_percent(percent)
class my_wsgi_app:
def process_request(self,text):
got_value(text)
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/html')] # HTTP Headers
return status, headers, text
def run(self, environ, start_response):
path = environ['PATH_INFO']
status, headers, content = self.process_request( path )
#begin the response
start_response(status, headers)
#return the content
return content
app = my_wsgi_app()
httpd = make_server('', 8080, app.run)
print "Serving on port 8080..."
# Serve until process is killed
httpd.serve_forever()
For ease of copy, the code is also available at
The code starts serving on port 8080 and sets the percent of the PWM based on the URL used to access the server. For example, to set the voltmeter to 25%, one would need to point a browser at. My beaglebone is mounted on the wall and is named "wallbone", yea original. Anyway, if I want to set the voltmeter to 77%, I would access
Face to Face
It's a shame that the voltmeter as a big "V" on it, as well as 0, 1, 2, 3, and some useless text.
One would think that I could just take apart the voltmeter, make a compass from a pin and a twist-tie, draw a new face, and re-assemble the meter. Oh, don't mind if I do!
How about some video?
Well... it was far too dark and the pin isn't really visible. What a shame.
Now What?
There are plenty of uses for this meter.
- analog progress or volume meter for muttonchop
- add a few more meters and create a neat clock
With the pulse-width modulation, I could connect and control a fan from the beaglebone.
The possibilities are only limited by my imagination.
Now quit reading, and go send me some ideas.
After.
A few weeks ago I purchased a BeagleBone from Amazon. The BeagleBone is a small ARM based computer with programmable Input/Output pins developed by Texas Instruments and is part of their beagleboard line of ARM development boards. After finally deciding what to do with the computer, it was time to build a new computer case.
Where is it Going?
At the thrift store, I purchased a nice jewelry box with flowers etched in its glass. The small, solid box was $3.00.
The plan (play the A-Team theme), is as follows:
- Connect a rotary phone to the BeagleBone for input
- Do some other sweet shit (more on that later)
Alrighty! time to get crackin
Gutted
For some reason, whoever created the box thought it would be a good idea to put a bunch of stuff inside that I don't want or need.
Here is the box with the lid removed and the crap removed.
Making Some Standoffs
When I made the clock server case, I kept some of the wood bits that I needed to remove from the internals of the clock. A wood saw and some small screws made some sweet standoffs for the beaglebone.
A black marker was eventually used to color the light wood.
Mangle the Box
Any dreams I had about making an very clean access hole in the case was dashed upon the rocks of my poor power tool using skills.
Oh well, it doesn't get seen, and it works as it should. Why am I complaining?
Wall Hanging Mount
Some twisted baling wire and two wood screws will make it very easy to hang the box on the wall.
Time to warm up the hot glue gun.
So Far So Good
Once the glue gun was hot, the standoffs were glued into the box.
Look at all of that empty space! The BeagleBone has a USB port so I will be putting something in the box, but I don't know what it will be. So far, I'm thinking it could be:
- a nice laptop hard-drive for file storage
- a character LCD to display information
- or... I could ditch the case and put the BeagleBone in the phone itself
On The Wall
All plugged in a running sweet!
Currently, my BeagleBone is running Arch Linux.
Originally, the BeagleBone ships with Ångström Linux, but I couldn't find any documentation for configuring the opkg package manager that ships with Ångström, and since I was looking to eventually run Lighttpd and MySQL on the device, I switched to a distro with an extremely useful wiki.
The Computers in the Corner
The Phone
The Bone
The Router
The Clock Server
The DSL Modem
The Status Server (between the modem and the router)
Now What to Do?
Put some LEDs in the box and write a program to light up the LEDs when something happens. That something is to be decided
But what else?
Options include putting a hard drive in the box and use it as a federated status.net server or put a character LCD in the case and use LCDproc to display various bits of information.
Currently the machine is programmed to:
- Dial 666 : play random Iron Maiden track on my MuttonChop machine
- Dial 75337 (sleep) : shut down computers
- Dial 9253 (wake) : emit wake-on-lan signal to various computers
Now I need to write a bunch of little programs to be run when various numbers are dialed on the phone, and I need to find a way to get the cables out of the way.
Until next time, hack on!
The BeagleBone story continues at.
If a bump is good, isn't a glow-in-the-dark bump better?