Recent posts (max 10) - Browse or Archive for more

Making toy wooden swords

One of my sons bought an inexpensive wooden sword at a nearby Renaissance festival. And naturally, his older sister wanted one as well,'s gotta be a bigger one. Sibling rivalry? What's that?

Looking at the design of the sword, I could see it was pretty straight-forward to replicate, so I told her that if she bought a 6' 1x3 select pine board at the local hardware store, I'd turn it into a sword. Woodworking is fun! And educational!

The basic design is to cut a board for the cross-guard, 5 to 6 inches long. Then cut another piece to the length of the blade and hilt. I mounted the latter board on a 1x6 with a clamping set to get a straight tapered cut from the tip to where the cross-guard would be. I then put the tablesaw blade at about a 45 and gave it 4 cuts to provide some shape to the blade's cross-section and that look of having a pseudo-edge. My daughter had sketched what she wanted the hilt to look like, so I used a bandsaw to get a rough shape to the grip and pommel, then took that to the bench sander and shaped it generally "by eye". For the part of the grip where the cross-guard belongs, I was aiming for a shape that would fit into a slot cut with a 3/4" straight router bit. Once I had the size of that determined, I shaped the rest of the grip and pommel to have a cross-section no larger than that. Then I mounted the cross-guard in the mill and cut the slot into the center with a 3/4" router bit. Four passes on the tablesaw to take off the corners, and I had a cross-guard.

The two pieces looked like this:


The select pine is right at 3/4" thick, so the cross-guard slid over the hilt with a friction fit.


Of course, a 6-foot board was enough to make *two* swords, so I made an even longer, two-handed sword.


The dangerous duo:


While a proper template and a router would have yielded more precise results for the grips, overall I was pleased with how they turned out.

Playset Construction Discovery

I had an opportunity to acquire a large, second-hand playset for the cost of "tear it down and haul it off." I knew that wasn't going to be as cheap as it sounds, but there were still a number of surprises involved.


As you can see, the structure was leaning rather severely, which I knew meant some of the wood would need replacing or reinforcing. The vertical posts were the main culprit; they had rotted out the bottom 2-3 feet of their 7-foot length.

But what I was surprised by was their construction.


The green wrap is a thick plastic sheathe around the posts. And for some, the bottom end of the post was sealed with this same plastic. With the plastic removed, you can see that the 3"x3" post is not a single piece of wood, but built up from smaller lumber. I understand the cost savings of that approach, but I was surprised when I pealed a 1x4 (ish) off the side of the post to reveal that the core was hollow. I had expected the central 2x2 (ish) to run the length of the post. These are, after all, the load-bearing posts for the whole construction.

I presume the resulting box was structurally sound for the intended purpose originally, but it appears that the plastic sheathe acted like a plastic cup and held moisture in the lower portion of the post. It rotted out quite thoroughly.


The rotted portion was black enough you would have thought someone had used it for a campfire.

Rather than try to duplicate the construction technique, I bought 4x4 cedar posts, cut them to length, and planed them to 3"x3" to match the original post dimensions and exceed the original post strength. That generated mountains of cedar sawdust, but I'm pleased with the result.

More importantly, I'm not the only one who is happy with how the final playset turned out:


LeoCAD 17.02 - Packaged for Linux

LeoCAD is a CAD application for building digital models with Lego-compatible parts drawn from the LDraw parts library.

I packaged the 17.02 release of LeoCAD for Fedora 25. This package requires the LDraw parts library packaged earlier.

Install the binary rpm. The source rpm contains the files to allow you to rebuild the packge for another distribution.



LDraw Parts Library 2016-01 - Packaged for Linux maintains a library of Lego part models upon which a number of related tools such as LeoCAD, LDView and LPub rely.

I packaged the 2016-01 parts library for Fedora 25 to install to /usr/share/ldraw; it should be straight-forward to adapt to other distributions.

The *.noarch.rpm files are the ones to install, and the .src.rpm contains everything so it can be rebuilt for another rpm-based distribution.



Réinventer Lego

Back in 2010, I added Lego to a Rubik's Cube to create something awesome. Last year, French publisher Hoëbeke published a French-language book Réinventer Lego.

cover photo

When they reached out to me, I was happy to have my Lego Rubik's cube included in their book, though a bit surprised given the relative simplicity of the creation. When my copy arrived, I was pleasantly surprised to have gotten four pages in the book.

page 1 page 2

They have included a wide variety of projects which incorporated Lego parts as a material; from clothing accessories to furniture to home remodeling. People really do a lot of weird things with Lego.

"Réinventer Lego" is available via Amazon

Corsair keyboard replacement rubber feet

In the course of carting my Corsair K70-RGB around, a couple of the rubber feet on the bottom of the keyboard came off, one of which I lost. After searching Corsair's webstore in vain, I contacted Corsair about buying replacements. They don't sell the rubber feet, but they were willing to RMA my keyboard because it was wobbly. Unfortunately, I would have recieved a newer model with an updated controller. That's usually a bonus, but I'm using the Open Source ckb to drive the keyboard, and support for the newer model is still in a development branch.

So I went looking for an alternative solution.

I carved a replacement rubber foot out of some old tire rubber. While that worked, there's a better solution.

Corsair does not sell replacement rubber feet for the K70, but they do sell replacement wrist rests. Those wrist rests sport three of these same rubber feet on the bottom.

picture of rubber foot on bottom of wrist rest

They appear to be the same as on the K95 and its wrist rest. I used Gorilla brand superglue gel to affix them to the keyboard, which bonds them more securely than Corsair's original adhesive.

So for $10+s/h, you can buy a set of three rubber feet... they just come packaged on a wrist rest.

Having fun with the bash prompt

Run Time

I frequently want to know how long a command took, but only after I realize that it's taking longer than I expected. So I modified my bash prompt to time every single command I run. So each prompt looks like

[eli@hostname blog]$ [13]

When a command takes a long time, I may want to go work on something else for a couple of minutes, but still want to know when it completes. So I made the command prompt include a bell character and an exclamation point if the command exceeded 5 seconds.

[eli@hostname blog]$ [13!]

It would also be nice to have my eye drawn to the prompt if it took a long time, but I don't want to be distracted by all the [0]'s getting displayed. So I made the color vary based on the length of time. If it is 0 seconds, it's displayed in black, and as it takes longer, it transitions to white, and then to increasingly brighter shades of red, maxing out at bright red on a 5 minute run time.

[eli@hostname blog]$ [0s] sleep 5
[eli@hostname blog]$ [5s!] sleep 60
[eli@hostname blog]$ [60s!] sleep 252
[eli@hostname blog]$ [252s!] 
[eli@hostname blog]$ [0s] sleep 1
[eli@hostname blog]$ [1s] 
[eli@hostname blog]$ [0s] 

So all that code went into a dotscript I called promptautobell:

function prompt_autobell_start {
function prompt_autobell_stop {
    local retval=$?
    unset prompt_autobell_timer

    local color
    local bell
    if [ $prompt_autobell_elapsed -ge 5 ]; then
    color="$(tput bold)$(tput setaf $((prompt_autobell_elapsed > 300 ? 196 \
: prompt_autobell_elapsed > 22 ? 16+(1+(prompt_autobell_elapsed-1)/60)*36: \

    prompt_autobell_show="$(echo -e "\001${color}\002[\
${prompt_autobell_elapsed}s$bell]\001$(tput sgr0)\002")"

    return $retval
trap 'prompt_autobell_start' DEBUG
PS1="$PS1\${prompt_autobell_show} "

So that's nice, we get to know how long our commands take, and automatically get nudged when a long-running command finally completes.

Return Codes

But that doesn't tell us if the command passed or failed. And in the *NIX tradition, commands are generally silent on success. So what if we make the prompt display an appropriate emoticon based on the exit code? Like, a green smiley on success, and a red frown on failure. And maybe a few other expressions as well.

[eli@hostname blog]$ source ~/bin/promptsmile
[eli@hostname blog]$ :) 
[eli@hostname blog]$ :) false
[eli@hostname blog]$ :( sleep 60
[eli@hostname blog]$ :| sleep 60
[eli@hostname blog]$ x_x sleep 60
Segmentation fault (core dumped)
[eli@hostname blog]$ >_< true
[eli@hostname blog]$ :) 

So into a dotscript called promptsmile goes:

# source this
function prompt_smile () {
local retval=$?
if [ $retval -eq 0 ]; then
elif [ $retval -eq 1 ]; then
elif [ $retval -eq 130 ]; then # INT
elif [ $retval -eq 139 ]; then # SEGV
elif [ $retval -eq 143 ]; then # TERM
echo -e "\001$(tput setaf $color; tput bold)\002$face\001$(tput sgr0)\002"
return $retval # preserve the value of $?
PS1="$PS1\$(prompt_smile) "

Note that the emoticon logic is readily extensible. Do you frequently deal with a program that has a couple of special exit codes? Make those stand out with a bit of straight-forward customization of the prompt_smile function.


And of course, I want an easy way to get both of these behaviors at the same time, so I created a dotscript called promptfancy:

source ~/bin/promptautobell
source ~/bin/promptsmile

And to make it easy to apply to a shell, I added to ~/.bashrc:

alias fancyprompt="source ~/bin/promptfancy"

And now,

[eli@hostname blog]$ fancyprompt 
[eli@hostname blog]$ [0s] :) 
[eli@hostname blog]$ [0s] :) sleep 60
[eli@hostname blog]$ [1s] :| sleep 60
[eli@hostname blog]$ [12s!] x_x sleep 60
Segmentation fault (core dumped)
[eli@hostname blog]$ [12s!] >_< false
[eli@hostname blog]$ [0s] :( sleep 6
[eli@hostname blog]$ [6s!] :) 
[eli@hostname blog]$ [0s] :) 
[eli@hostname blog]$ [0s] :) 

Go then, and liven up your own bash prompts!

Driving Corsair Gaming keyboards on Linux with Python, IV

Here is a new release of my Corsair keyboard software.

The 0.4 release of rgbkbd includes:

  • Union Jack animation and still image
  • Templates and tools for easier customization
  • Re-introduced brightness control

New Flag

For our friends across the pond, here's a Union Jack.

I started with this public domain image (from Wikipedia)

I scaled it down to 53px wide, cropped it to 18px tall, and saved that as uka.png in the flags/k95 directory. I then cropped it to 46px wide and saved that as flags/k70/uka.png. Then I ran make.

Here is what it looks like on the K95:

Union Jack animation


To make it easier to draw images for the keyboard, I created templates for the supported keyboards that are suitable for use with simple graphics programs.

K95 template

K70 template

Each key has an outline in not-quite-black, so you can flood fill each key. Once that image is saved, ./tools/template2pattern modified-template-k95.png images/k95/mine.png will convert that template to something the animated GIF mode can use. A single image will obviously give you a static image on the keyboard.

But you can also use this with ImageMagick's convert to create an animation without too much trouble.

For example, if you used template-k70.png to create 25 individual frames of an animation called template-k70-fun-1.png through template-k70-run-25.png, you could create an animated GIF with these commands (in bash):

for frame in {1..25}; do
    ./tools/template2pattern template-k70-fun-$frame.png /tmp/k70-fun-$frame.png
convert /tmp/k70-fun-{1..25}.png images/k70/fun.gif
rm -f /tmp/k70-fun-{1..25}.png

Brightness control

This version re-introduces the brightness level control so the "light" key toggles through four brightness levels.

Grab the source code, or the pre-built binary tarball.

Previous release

Driving Corsair Gaming keyboards on Linux with Python, III

Here is a new release of my Corsair keyboard software.

The 0.3 release of rgbkbd includes:

  • Add flying flag animations
  • Add Knight Rider inspired animation
  • Support images with filenames that have extensions
  • Cleanup of the Pac-Man inspired animation code

Here is what the flying Texas flag looks like: Animated Texas flag

And the Knight Rider inspired animation: Knight Rider inspired animation

Grab the source code, or the pre-built binary tarball.

Previous release

Update: Driving Corsair Gaming keyboards on Linux with Python, IV

Driving Corsair Gaming keyboards on Linux with Python, II

Since I wrote about Driving the Corsair Gaming K70 RGB keyboard on Linux with Python, the ckb project has released v0.2. With that came changes to the protocol used to communicate with ckb-daemon which broke my rgbkbd tool.

So I had to do some work on the code. But that wasn't the only thing I tackled.

The 0.2 release of rgbkbd includes:

  • Updates the code to work with ckb-daemon v0.2
  • Adds support for the K95-RGB, in addition to the existing support for the K70-RGB.
  • Adds a key-stroke driven "ripple" effect.
  • Adds a "falling-letter" animation, inspired by a screen saver which was inspired by The Matrix.
  • Adds support for displaying images on the keyboard, with a couple of example images.
  • Adds support for displaying animated GIFs on the keyboard, with an example animated GIF.

That's right; you can play animated GIFs on these keyboards. The keyboards have a very low resolution, obviously, but internally, I represent them as an image sized based on a standard key being 2x2 pixels. That allows for half-key offsets in the mapping of pixels to keys which gets a reasonable approximation. Keys are colored based on averaging the color of the pixels for that key. Larger keys are backed by more pixels. If the image dimensions don't match the dimensions of the keyboard's image buffer (46x14 for K70, 53x14 for K95), it will slowly scroll around the image. Since the ideal image size depends on the keyboard model, the image files are segregated by model name.

Here is what that looks like:

(Also available on YouTube)

Grab the source code and have fun.

Previous release

Update: Driving Corsair Gaming keyboards on Linux with Python, III