Tup: Make Alternative for Embedded Systems


I hate Make.  With a fiery burning passion, I hate Make.  From day one, I found it difficult to understand, difficult to write Makefiles, difficult to modify Makefiles, and difficult to use Makefiles.  Over the years, I have built a collection of boilerplate Makefiles that only sort-of worked for a given project, and any time I wanted to do something creative with the build system, it was a challenge to figure out how to force Make to do what I knew damn well how to do via the command line.

There has to be a better way!
There has to be a better way!

Wasting time on HackerNews, I saw a post about a build system called Tup.  It was designed as a pet project for a pet project, but I was able to understand the syntax in just a couple hours of reading and experimenting.  Seriously, in just a couple hours, I was writing Tupfiles from scratch, something I would never think of doing with Make.

Tup has some seriously huge benefits if you’re building projects with thousands of files, and lots of nested directories.  Tup uses inotify and some other tricks to automatically figure out what needs to be rebuilt, and when it needs to be rebuilt.  I’ve been told that you can do a lot of this using Make, but I have never been able to write a Makefile that didn’t try to rebuild everything all the time, so even though I shouldn’t be saving build time using Tup on small embedded projects, I am, by a huge margin.

In fact, “tup monitor -a” is probably the most magical command I’ve encountered in any build system ever.  Because tup uses inotify, the monitor daemon can receive notifications that files in the build chain have changed, and automatically determine what parts of the project need to be rebuilt.  As a result of this, my project is often rebuilt by the time I’ve alt-tabbed to the terminal to check the results of the build and upload to the board.  Serious, magic.

Most of my projects lately have been built on AVR8 processors, so I’ve created two Tup skeletons on github, if you’d like to try it out:



The first is an Arduino skeleton project that allows you to easily write Arduino code using whatever text editor and programmer you damn well please.  Simply #include “Arduino.h” at the top of every file, and you’re in Arduino-land.  Works out-of-the-box with any AVR processor used on an Arduino, including the AtMega328, and AtMega2560.  Other processors will require a pin definition file in order to work with Arduino functions.  To use, clone it, run “tup init” then “tup upd”.

The second is a skeleton project for LUFA, the AVR USB library.  I’ve been using LUFA with the Teensy++ 2.0, but there are plenty of other boards and processors that can make use of the library.

If you want to improve the skeletons, or submit your own, I welcome all pull requests.  I’m also happy to help folks get started with tup.  The more folks using it, the more well-supported it will be in the future!



3D Printing WorkshopThis past weekend, we had a 3D printing workshop at LVL1.  I built a Mendel Prusa i2, along with 9 other folks in the LVL1 community. Sonny Mounicou came up from Memphis, TN, while Jon Oly of SeeMeCNC came down from Goshen, IN to help us build 3D printers.  One guy had his printer up and running in a mere 14 hours!  I had to get some sleep, so I was a little bit behind that.

Needless to say, everyone had a great time, and walked out with some working 3D printers.  I’ve since gotten my Prusa home and had some time to play with it.

Prusa at HomeI’ve already got plans to make it better.  Tonight, I’m going to redo all the wiring to make it nicer, more reliable, and better looking.  Next, I intend to scrounge a server power supply out of the basement of LVL1.  Currently, it’s attached to a 200W Dell Power supply, which can only push out 200W.  This is fine for most things, but it just can’t put our the juice needed for heating the build platform to ABS temperatures.  I was able to get some calibration cubes of ABS to stick to the build platform, but nothing bigger. After that, sky’s the limit.  I’m also going to use this printer to print parts for another 3D printer, a Rostock.

Unfortunately, I’ll be missing the Midwest RepRap Fest this weekend, but I’ll be there in spirit!



Hacking at the Light Strike Laser Tag Game


My friend Jon has been working on Laser Taser tag, modifying perfectly ordinary toy laser guns to provide an electric shock when you get hit.  As he was working on this game for Makerfaire Detroit 2012, I noticed that these guns are really freaking cool.  10 years ago, I paid good teenage summer job money to play laser tag, and it wasn’t as good as this.  You can now buy a $30 toy that rivals the fanciest laser tag equipment of the previous decade.

This is one of the rifles you can buy for the Wowwee Light Strike game.  They’ve got a bunch of capacitive touch button on the side to change gun settings, LED lights to indicate health, team, and who you got hit by, a reload button, an IR receiver and transmitter, and a couple of ports for add-on accessories.  Jon did a lot of the ground work for what I’m summarizing in this post.  The guns (and accessories) send out 38 kHz IR.  The guns use a custom packet format, and each message is 32 bits.

After taking a look inside these guns, I realized that they have a lot of potential.  They’re a really great sensor platform for a laser tag game, with a great form factor, but the electronics inside don’t offer a lot of flexibility in game mode, and players have to use the honor system to keep score.  My end goal is to provide drop in replacement electronics, which allow for more teams, additional game modes, zigbee scorekeeping, custom guns, custom sounds, and provide a standard data output, so people (like Jon) can build accessories a little easier.

Light Strike rifle with all screws highlighted

These guns are really easy to get into.  Just regular phillips head screws, nothing special.  A bunch of them are hidden under the sticker on the side opposite the buttons.  These can be hard to find, so to the left is a picture with all the screws circled (click to embiggen).  Once you get inside, the main feature is a really well-labeled PCB that connects all the different sensors and outputs.  Of  course, the microcontroller is covered in a big blob of epoxy, but I’m going to replace the entire board, so it isn’t going to be a problem in the long run.

 Ultimately, I want the new electronics to be backwards compatible with the old electronics, so I need to decode all the messages that are sent out by the stock rifle.  Fortunately, the rifle comes with a little target practice toy.  Taking it apart reveals an IR decoder, RGB LED, and a speaker. I added a Teensy, wired the IR decoder in, and added an IR LED to output my own codes.  The IR decoder is connected to pin D7 on the Teensy (arbitrary choice), while the IR output is connected to pin C7 (this is the PWM output from the high-speed timer/counter on the Atmega32U4).  I started out using the Arduino IR Remote library from Ken Shirrif, just outputting raw timing values from the IR input.  This ended up being frustrating, and I used a logic analyzer to confirm.  Getting a graphical view of the IR output helped a lot.

As you can see from the logical analyzer output, there are a few different marks and spaces (marks are where the LED is active).  There’s a long header mark at the start of the message, followed by equal-length inter-bit marks, with either a short space (for 0) or a long space (for 1).  Timings are as follows:

  • Header Mark: 6750 us
  • Inter-bit Mark: 900 us
  • Zero Space: 900 us
  • One Space: 3700 us

At this point, I modified the IRRemote library to decode the incoming messages.  I had to add the mark and space timings above, and write functions for decoding and encoding data.  I also had to modify some #defines for the Teensy to tweak the outgoing IR into a 50% duty cycle, and adjust the timings: The guns send out ~37.8 kHz IR, but the default settings sent out ~38.2 kHz IR.  This shouldn’t matter, but a simple tweak made everything work as it should.  The most difficult part was getting the IR send function working.  Here’s my new IR Send:

In order to get the gun to accept the header, I had to send out a 0 length space after the header pulse, then begin sending data.  This took a while to nail down. I’ve put the code on GitHub here: https://github.com/LightStrikePlusPlus/LightStrikeDecode

Amazingly, after decoding some data packets, it appeared that everything was just a 32 bit output packet, and some obvious patterns emerged once I fired a few shots with different weapons and different teams.  Of the 4 bytes in the message, Byte 3 indicates the team (0x07 for Blue (default), 0x04 for Red, 0x05 for Yellow and 0x06 for Green), Byte 2 indicates a count of some sort (only used for the turret bomb mode.  It increases by one every time the bomb goes off, but any number of “count” will trip the gun, except 0.), and Bytes 0 and 1 indicate the weapon.  Below are the weapons:

  • Laser Strike: 0x0502
    • 12 hits to kill from full health
      Inside of the target, with the stock electronics, modified with wires for power and sensor input to the teensy.
  • Stealth Strike: 0x0602
    • 12 hits to kill from full health
  • Pulse Strike: 0x0703
    • 8 hits to kill from full health
  • Rail Strike: 0x0806
    • 4 hits to kill from full health
  • Sonic Strike: 0x908
    • 3 hits to kill from full health
  • Bomb: 0x0E18
    • MUST include a non-zero “count” field
    • 1 hit to kill
  • Sentry: 0x0F08
    • 3 hits to kill from full health
  • Health: 0x08–
    • MUST be used with team 0x08
    • Final byte is team byte for healing pulse (0x07 for blue, etc)
    • 3 hits to full health
Target with Teensy installed

Interestingly enough, the guns appear to be more particular about the codes they receive than the sentry or the target module.  Both of these devices will activate on codes that don’t activate the gun.  The target, in particular, treats team codes 0x0D, 0x0A, 0x0B and 0x0C as Blue, Red, Yellow, and Green, respectively.

Now I think I’ve got enough data to build a protocol for the new electronics that will be backwards compatible, but add a whole lot of functionality. If you’d like to mess around with this on your own, check out the Arduino code I’ve uploaded here: https://github.com/LightStrikePlusPlus/LightStrikeDecode.