2012-12-01

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

#!/usr/bin/env 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 initializepin )
    @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(targetpin[:mux_value] )
    #set up the PWM
    set_file_value(@duty_percent0)
    set_file_value(File.join(pwm_dir,"period_freq"), 100
    set_file_value(@run1)
  end

  def clean_up()
    set_percent(0)
    set_file_value(@run,0)
  end
  
  def set_percentvalue )
    set_file_value(@duty_percentvalue)
  end

  def random()
    val rand(@min_val..@max_val)
    set_percent(val)
  end

  def set_min_val(value)
    @min_val value if value >=and value <=100
  end
  
  def set_max_val(value)
    @max_val value if value >=and value <=100
  end
  
  private 
  def set_file_value(filevalue)
    #puts "#{file} :  #{value}"
    File.open(file'w'do |f|
      f.putsvalue )
    end
  end
end

#make an array of wisps
wisps pins.each.map {|pWisp.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.

Comments
2012-12-09 Alison Chaiken:
Needs a video!
2012-12-10 jezra:
A poorly created video is now available at http://www.youtube.com/watch?v=zNztCHwPolc&feature=plcp
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
9 minus 3
Answer:
required
subscribe
 
2019
2016
2015
2014
2013
2012
2011
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008