For some reason, I am drawn to Will-o'-the-wisp even though I have never seen them. Fortunately I have an inclination for breaking things and making things and it seemed obvious that I would need to make my own Will-o'-the-wisp with some hardware and software hacking.
In a nutshell, I wanted to put some LEDs in a lantern and randomize the LEDs brightness with a computer to emulate a flickering effect.
Hardware Used
- phone cord : because I have plenty of it
- tin candle lantern : because it was available
- beaglebone ( I used my wall mounted beaglebone ) : because it can have more than one PWM controlled pin
Will-o'-the-Wisp Hardware
The Lantern
This tin candle lantern was the obvious choice for this project because it has been at my home for a few years and I don't really use it. TAKE IT APART!!!
There was a small tin cylinder in the lantern that held candles. Some gentle twisting quickly removed the holder. This was followed by sanding the inside of the lantern to make it more reflective and then small hole was punched in the bottom of the lantern.
This was my first time working with tin.
Solder some LEDs
Three bright LEDs were soldered to a four wire phone cord. Three wires for power and one wire for ground. The phone line adapter was scavenged from a broken touch-tone phone.
pfffttt touch tone
Hack a Notch in the Box
While putting together this hack, I thought it would be a good idea to include a phone cord jack for the rotary input device as well as the lantern.
Why Cringe?
I have friends that are wood crafters, and whenever they see my wood working skills they cringe a little bit. The easiest solution to the problem is to not show them what I do, but that wouldn't be as much fun.
Two phone cord jacks hot glued into the notch. It looks fairly flush on the top... and functional (which is what I really want).
Move the Beaglebone
While I had the box disassembled, I move the stand-offs closer to the wall of the box so that the beaglebone's USB port can be accessed more easily. I don't know what I'll use the USB port for, but it's nice to know that it is ready when I need it.
Plugged In Phone Jacks
All glued up, the lid closes properly, and I'm happy.
On the left is the lantern cord and the rotary phone is on the right.
LEDs
The LEDs are mounted in the tin lantern with a heavy dollop of hot glue! RAD!
Will-O'-The-Wisp Code
For this project, I opted to use the Ruby programming language because... well... just because. For now, all I need is a bit of File IO to write data to files. One of the reasons that I'm such a fan of the beaglebone is that in most instances, controlling the pins can easily be done simply by writing to a file.
All I really need to do, is have 3 instances of PWM on the Beaglebone and set the value of the pins to a random number in order to emulate a flickering effect.
Enter the Ruby
#define the pins that will be used, and their muxing values
#these are:
# 9.14
# 9.16
# 8.13
pins = [
{:mux_value=>6, :mux_target=>"gpmc_a2", :pwm_dir=>"ehrpwm.1:0"},
{:mux_value=>6, :mux_target=>"gpmc_a3", :pwm_dir=>"ehrpwm.1:1"},
{:mux_value=>4, :mux_target=>"gpmc_ad9", :pwm_dir=>"ehrpwm.2:1"}
]
#a class to represent an LED
class Wisp
def initialize( pin )
@min_val = 0
@max_val = 100
#set the pwm_dir
pwm_dir = File.join("/sys/class/pwm",pin[:pwm_dir])
#set the pwm duty_percent file
@duty_percent = File.join(pwm_dir, "duty_percent")
@run = File.join(pwm_dir, "run" )
#mux the target
target = File.join("/sys/kernel/debug/omap_mux", pin[:mux_target])
set_file_value(target, pin[:mux_value] )
#set up the PWM
set_file_value(@duty_percent, 0)
set_file_value(File.join(pwm_dir,"period_freq"), 100)
set_file_value(@run, 1)
end
def clean_up()
set_percent(0)
set_file_value(@run,0)
end
def set_percent( value )
set_file_value(@duty_percent, value)
end
def random()
val = rand(@min_val..@max_val)
set_percent(val)
end
def set_min_val(value)
@min_val = value if value >=0 and value <=100
end
def set_max_val(value)
@max_val = value if value >=0 and value <=100
end
private
def set_file_value(file, value)
#puts "#{file} : #{value}"
File.open(file, 'w') do |f|
f.puts( value )
end
end
end
#make an array of wisps
wisps = pins.each.map {|p| Wisp.new(p)}
#we want to create a controllable loop
loop = true
#let Ctrl+c break the loop
trap "INT" do
loop = false
end
#start looping
while loop do
#give each wisp a random percent
wisps.each do |w|
w.random()
end
#take a bit of a nap
sleep 0.1
end
#when the loop is broken, clean up
wisps.each do |w|
w.clean_up()
end
For easy copy and paste, this code is available at http://hoof.jezra.net/snip/o6.
It should be noted that this code is running on a beaglebone Rev. 3 using Arch Linux.
If I had the hardware, I probably would have used an ethernet cable instead of a phone cord. That way, I could run 7 LEDs instead of 3. Well it works, and that's what really counts. Now I have to start writing the web UI that will allow me to control the LEDs from a web browser. In case you haven't noticed, I like internetted things.
Now quit reading, and go find a will-o'-the-wisps.
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 http://hoof.jezra.net/snip/o3
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 http://NAME_BEAGLEBONE:8080/25. 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 http://wallbone:8080/77
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.
http://www.youtube.com/watch?v=ldcwMYj5AIc
http://www.youtube.com/watch?v=SdbBgiZn1UM
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 putting together the rotary phone beaglebone machine, I decided that I still needed to do something with the extra pinouts on the beaglebone. Since I had recently started using MyTinyTodo to keep track of my todo list, I thought it would be nice to have a quick visual display of how many things are still on my todo list.
To Accomplish this my goal, I would need to add some LEDs to the beagle bone and then hack some code to do what needs doing. First thing first: add the idea to the todo list.
Gather Some Components
In order to get this project going, a trip to the nearby electronics store was in order. After returning home with 10 green LEDs ( the plan was to use 6, but I figured buying extra would let me fry a few), I realized that there was a lack of 100 Ohm resistors in my home.
Fortunately, I had some 50 Ohms that I soldered in series to handle the job.
This is a very boring pictures; don't look at it.
Solder 6 of These
This is the basic circuit that get's wired to the BeagleBone. The extra length of wire will get cut off and the entire thing will be wrapped in a bit of electrical tape.
While I was at the electronics store, I bought some fans to replace the fans in the clock server because I think it runs too hot.
The Finished Circuit
Well looky looky! The circuit is finished. Six LEDs with a common ground, with a 100 Ohms of resistance for each LED.
Time to wrap these babies up with electrical tape and hot glue them into the BeagleBone's case.
Glued in Place
On the third attempt, I managed to almost get the LEDs glued into place where I wanted them. Yea, it took me a few time of gluing, and then prying the LEDs from the case a regluing before things were working properly.
As it is, one of the LEDs still doesn't let the box close very easily. Terrible terrible design. That's it! I'm firing myself.
Oh hey! This is probably the best picture that shows off the flowers etched in the glass.
7 Things On The ToDo List
At the time this picture was taken, there were 7 things on my todo list. But there are only 3 LEDs lit up. That's right, the LEDs need to be counted in binary from left to right.
With this setup, using 6 LEDs, the ToDo List will max out at 63 items; and I if I have that many things to do, something is very wrong.
Every 5 minutes, the LEDs run a simple animation sequence, parse the ToDo List RSS feed and then turn on or turn off LEDs as necessary.
Since there is still plenty of room in the box, I'm thinking of adding another something-or-other that is controlled by the BeagleBone pins. I'm not sure what it will be, but I can guarantee I'll have fun making it.
Hack on!
PS. I really want to have 15 things on my ToDo list, just so I can say "THERE...ARE...FOUR...LIGHTS" Ha hahahaha, I crack me up.
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 http://www.jezra.net/blog/LEDs_BeagleBone_and_my_ToDo_List





