back
Teensy Saber OS
Got Pike?
DIY Teensy based lightsaber


What you will need:

Download version 1.157 here

ChangeLog (since 1.153)
  • TeensySaber V3 support
  • Re-wrote button input handling
  • Latching button support

Features

  • 100% open-source, you may add any feature you like. (GPLv3)
  • Speedy 32-bit processor makes advanced features like sound filters, synthesizing and mp3 playback possible.
  • 12-bit digital-to-analog output
  • Default sample rate is 44kHz
  • 22kHz and 11kHz samples are supported and upsampled to 44kHz automatically.
  • Gapless playback, with 2.5ms cross-fade when you interrupt one sample to go to another.
  • Polyphonic playback, currently configured for up to 5 simultaneous samples.
  • Support for PL9823 or neopixel strings.
  • Support for arbitrary 1/2/3/4-color stars/strings.
  • Supports segmented string blades. (with flash string)
  • Multi-blade support for dual and crossguard setups.
  • Crystal chamber support.
  • Power-level indicator with neopixel blade.
  • OLED PLI display
  • MTP support (drag-n-drop files from windows through USB connection)
  • POV (persistance of vision) mode.
  • Multiple blades. (at the same time)
  • Accent LEDs. (also implemented as additional "blades".)
  • Spoken error messages.
  • Easy software updates.

If you want any of these features, contact me on the fx-sabers forum and I'll see what I can do.

Install
Step-by-step instructions:

  1. Install latest arduino software.
  2. Install latest teensyduino software (in same directory)
  3. Load up lightsaber.ino in the arduino software.
  4. Go to the Tools menu, select Board: Teensy 3.1/3.2
  5. (optional) Also in the Tools menu, select: USB Type: "MTP Disk (Experimental)"
  6. (optional, skip to step 8 if you're in a hurry) Make a copy of one of the config files, like owk_v2_config.h, let's call it mysaber_config.h (you can call it anything as long as it's only letters and numbers (and doesn't start with a number))
  7. In lightsaber.ino, go to line ~25, and change it to: #define CONFIG_FILE "mysaber_config.h" (make sure the other config files are commented out, there should only be one CONFIG_FILE without //)
  8. Edit mysaber_config.h to match your saber, you might not need to change anything though.
  9. Edit the blades array (either in common_config.h or in the copied config file). See below for how.
  10. Edit the presets array in (either in common_config.h or in the copied config file) to specify where your fonts are and what effects you want.
  11. Hook up the teensy to your computer with an USB cable
  12. Power the teensy with a battery. (You did cut the VIN/VUSB, right?)
  13. Press the arrow button near the top left in the arduino interface, and it will compile and upload the program.
  14. Done
If you have a problem, you can contact me on the fx-sabers forum, but there is also lots of online informtation about arduinos and teensys, so some googling probably won't hurt.

Configuration
While you can obviously change *anything* in the source, the parts you may need to change depending on how you wired your electronics is maked with a CONFIGURABLE comment, so go find those and modify them to your hearts content.

The blades[] array
One of the first things you'll need to configure is the blades[] array. If your build only has one blade, you should remove all entries but one. If you have a blade connector, and use a resistor in the blade to identify each blade, you'll need to update the blades[] array to match the blades you have. Each entry, in the blades[] array looks something like this:

  {   2600, WS2811BladePtr<97, WS2811_580kHz>(), CONFIGARRAY(presets) },
The first value is the value of the resistor used to identify the blade, in homes. (2.7kOhm in this case) The second value is a pointer to the blade driver. In this case, it is a neopixel blade with 97 LEDs. The third entry is a list of presets, which will be used with this blade.

Currently there are four different blade drivers:

  • WS2811BladePtr - for WS2811/neopixel style blades
  • FASTLEDBladePtr - for APA102/dotstar style blades
  • SimpleBladePtr - for RGB/RGBW stars and strings (strings with no segments)
  • StringBladePtr - for segmented string blades.
Each driver needs some arguments that specifies how they behave, but drivers do not have any influence over when the LEDs should be on, and what color to use. That is handled by a blade style, which is part of the list of presets.

The presets[] array
Like the blades[] array, the preset array(s) have three entries per line. You can have as many preset arrays as you like, but it doesn't make much sense to have more than one per blade.

  { "font01", "tracks/title.wav", StyleNormalPtr<CYAN, WHITE, 300, 800>() },
In this case, the first entry is a directory containing a sound font. (More about that below.) The second entry is a sound track that can be played in the background, and the third entry is a BladeStyle pointer, which specifies what the blade will actually look like.

There is a bunch of different ways to setup blade styles, including write new ones. Here are a list of already implemented ones:

  • StyleNormalPtr<COLOR, FLASH_COLOR, OUT_MILLIS, IN_MILLIS> - Normal solid-color lightsaber blade.
  • StyleFirePtr<COLOR1, COLOR2> - Fire-style lightsaber blade.
  • StyleRainBowPtr<OUT_MILLIS, IN_MILLIS> - Rainbow blade
  • StyleStrobePtr<FLASH_COLOR, CLASH_COLOR, OUT_MILLIS, IN_MILLIS> - stroboscope style blade
  • &style_pov - POV writer (shows the STAR WARS logo if you have a WS2811 or FASTLED blade.)
  • &style_charging - battery level monitor
There is also a template-based system which can build up a bladestyle from a bunch of simpler effects. For instance, StyleNormalPtr is actually implemented as:
StylePtr<InOutHelper<SimpleClash<COLOR, CLASH_COLOR>, OUT_MILLIS, IN_MILLIS>()
Here is a list of individual components that can be used to build a blade style:
  • Rgb<R, G, B> - Solid color
  • Gradient<BASE_COLOR, TIP_COLOR> - smooth fade from base to tip
  • Rainbow - scrolling RGB rainbow
  • RandomFlicker<COLOR1, COLOR2> - Randomly mixes between COLOR1 and COLOR2, mix is even over entire blade.
  • RandomPerLEDFlicker<COLOR1, COLOR2> - Randomly mixes between COLOR1 and COLOR2, mix is different for each LED.
  • AudioFlicker<COLOR1, COLOR2> - Like RandomFlicker, but chooses based on audio, quiet audio means more COLOR1, loud audio means more COLOR2. The choice is made based on a single sample to make it flickery.
  • OnSpark<COLOR, SPARK_COLOR, MILLIS< - Normally defaults to "COLOR", but right as you turn on the saber, it uses SPARK_COLOR, then fads back to COLOR.
  • SimpleClash<COLOR, CLASH_COLOR, CLASH_MILLIS< - Normally defaults to "COLOR", but when when you whack the saber, it will use CLASH_COLOR for CLASH_MILLIS millseconds.
  • Lockup<COLOR, LOCKUP_COLOR> - Normally uses "COLOR", but during lockup, use "LOCKUP_COLOR" instead.
  • Strobe<COLOR, STROBE_COLOR, FREQUENCY, STROBE_MILLIS< - Similar to SimpleClash, but flickers at a fixed frequency.
  • InOutHelper<COLOR, OUT_MILLIS, IN_MILLIS> - Makes part of the blade black to make in/out/on/off work the way you expect.
  • InOutSparkTip<COLOR, OUT_MILLIS, IN_MILLIS, SPARK_COLOR> - Similar to InOutHelper, but as the blade is extended, the part closest to the tip will be SPARK_COLOR. (usually white)
  • StylePtr<COLOR> - Converts one of the templates from above to a BladeStylePtr so you can use it in a preset array.
Now here's the really cool part: Anywhere where you can specify a color above, you can also specify a component, making a LOT of combinations possible.

LED configuration
The teensysaber already contains definitions for some popular Cree LEDs, so most of the time, all you need to do is to change the R = to match the resistor you use. If you use a different LED, make a copy of onf of the LED structs and modify it.

struct MyRedLED {
  static constexpr float MaxAmps = 1.0;
  static constexpr float MaxVolts = 3.15;
  static constexpr float P2Amps = 0.7;
  static constexpr float P2Volts = 3.05;
  static constexpr float R = 0.55;

  // LED color
  static const int Red = 255;
  static const int Green = 0;
  static const int Blue = 0;
};
MaxAmps & MaxVolts is the amps and volts when the LED is fully on. It's best to get these values from the data sheet if possible. If not, you'll have to guess the MaxAmps, and measure at what voltage you get that. The P2Amps and P2Volts are similar, but at some other point, for instance when the LED is half-on. If the data sheet doesn't provide this, it is fine to just measure it. R is the value of the resistor you used, zero if there is no resistor.

LED Color configuration
Most of the time, TeensySaber simply uses RGB colors to run everything, however, if you're using an LED star, things can get a bit more complicated. For instance if you have a Blue-Blue-White LED star, you have two choices for how to configure the driver class. The first choice is something like: SimpleBladePtr<CreeXPE2Blue, CreeXPE2Blue, CreeXPE2White, NoLED>(). This means that when the Style classes tells the blade to be blue, the channel one and two turns on, and when the style class say to make it white, all three channels turn on. This is usually what you want to make the blade flash on impact. With this setup, the style setup becomes simple as well, you just do something like: StyleNormalPtr<BLUE, WHITE, 300, 800>(). However, there is one drawback; if you want to actually use the white LED by itself, there no way to do it. The only way to activate the white LED is for the Style to specify a white color, and that will also activate the blue LEDs.

We can get greater control over the color combinations by re-defining how colors are defined. We'll need to make copies of the CreeXPE2Blue and CreeXPE2White classes, like so:

struct MYCreeXPE2White {
  static constexpr float MaxAmps = 1.0;
  static constexpr float MaxVolts = 3.15;
  static constexpr float P2Amps = 0.7;
  static constexpr float P2Volts = 3.05;
  static constexpr float R = 0.55;

  // LED color
  static const int Red = 0;
  static const int Green = 0;
  static const int Blue = 255;
};

struct MYCreeXPE2Blue {
  static constexpr float MaxAmps = 1.0;
  static constexpr float MaxVolts = 3.4;
  static constexpr float P2Amps = 0.35;
  static constexpr float P2Volts = 3.1;
  static constexpr float R = 0.24;
  static const int Red = 255;
  static const int Green = 255;
  static const int Blue = 0;
};

And we'll add some new defines: #define BBW_BLUE 255,255,0 and #define BBW_WHITE 0,0,255. Now we can set up the blade like so: SimpleBladePtr<MyCreeXPE2Blue, MyCreeXPE2Blue, MyCreeXPE2White, NoLED>(). And the style configuration becomes StyleNormalPtr<BBW_BLUE, BBW_WHITE>(). This makes the flash pure white, and the blue LEDs are turned off during the flash. If we want to turn on both, we can do that by specifying 255,255,255.

Sound Fonts
Once you have the firmware installed, you'll need at least one sound font. Sound fonts are stored on the SD card, just create a subdirectory and put the files from the font in there, and it should work. Most fonts are monophonic, meaning that only one sound is played at a time, but some are polyphonic, meaning that sound effects are played over the basic humm sound of the saber. The teensy saber os supports both types and should be able to figure out what kind it is based on the file names. Here are a few places where you can obtain sound fonts:

Button configuration
By default, TeensySaber is configured to use a touch button for power, while the other buttons use regular momentary switches. There is currently no support for latching switches. If you want to use a momentary switch for the power button, you'll need to change two things.

  1. Find the line that says TouchButton power_; and replace it with Button power_;.
  2. Find the line that says power_(powerButtonPin, 1700, "pow"); and replace it with power_(powerButtonPin, "pow");. (The 1700 is the sensetivity of the touch button, at some point I might calculate the sensetivity automatically, and then this step won't be required anymore.)
Note that you can do the opposite of these two steps to the other buttons if you want to make them into touch buttons.

Sound Effect File Names
A sound font is made up of many sound files, the filename of these files should look something like this:

font1/clash001.wav
The file name is made up of four parts:
  1. The directory - This can be anything you like. All the files belonging to the same font should be in the same directory though. You can put fonts in sub-directories if you like, so it could be something like: fonts/dark/1/hum.wav if you like. The first entry in the preset[] array specifies the directory.
  2. The name - One of a set of pre-defined names specified below.
  3. The number - When playing a sound, TeensySaber will generally pick one of them randomly. The numbers can either be on the form 1,2,3,4,5,6,7,8,9,10,11, etc. or 01, 02, 03, etc. or 001, 002, 003, etc. The number sequence must be consistent and without any gaps. It's also possible to omit the number completely. For looping sounds, TeensySaber will randomly pick one of the numbered files each time it starts over, so it's possible to create a more interesting hum by having "hum.wav", "hum1.waw", "hum2.wav" etc. Note that since we're using an ancient file system, the length of the name and number must not total more than 8 characters. (So you can only have 11 poweron sounds: poweron.wav, poweron0.wav, poweron1.wav....poweron9.wav)
  4. The extension - I recommend using .wav files, 11, 22 and 44khz mono/stero wav files are supported. .raw and .usl files are also supported, but must be 44khz mono.

Sound Effect Names
The name part of the filename needs to be one that TeensySaber can recognize. Sound fonts can either be monophonic (Plecter) or polyphonic (Naigon Electronics) style. In monophonic mode, the following names are recognized:

  • boot - Played when TeensySaber boots up.
  • swing - Played when you move the saber around.
  • hum - Played when you don't move the saber around. (looped)
  • poweron - Played when you turn the saber on.
  • poweroff / pwroff - Played when you turn the saber off.
  • clash - Played when you hit something with the saber.
  • force - Force use sound.
  • stab - Played when you make a stabbing motion. (Not yet implemented)
  • blaster - Played when you press the AUX button.
  • lockup - Lockup (not yet implemented)
  • poweronf - Force power on (not yet implemented)
  • font - Played when you switch to this font / preset.
Note that in monophinic mode, the end of all sounds (except poweroff) smoothly join up with the beginning of the "hum" sound(s).

In polyphonic mode, the following names are recognized:

  • boot - Played when TeensySaber boots up.
  • swng - Played when you move the saber around.
  • hum - Played when you don't move the saber around. (looped)
  • out - Played when you turn the saber on.
  • in - Played when you turn the saber off.
  • clsh - Played when you hit something with the saber.
  • force - Force use sound.
  • stab - Played when you make a stabbing motion. (Not yet implemented)
  • blst - Played when you press the AUX button.
  • lock - Lockup (not yet implemented)
  • font - Played when you switch to this font / preset.
TeensySaber will automatically decide if a directory contains a monophonic or polyphonic font based on the filenames.

In addition, if the sounds "swingl" and "swingh" are present, they are assumed to be looped hum-style sounds. TeensySaber will blend the hum/swingl/swingh sounds to create swing effects instead of using the swing/swng sounds.

Serial Monitor Commands
You can use the serial monitor to debug and control the software once uploaded, here is an incomplete list of commands:

  • help - prints a list of known commands
  • on - turns the saber on
  • off - turns the saber off
  • blade on - turns the blade on (but leaves the sound off)
  • blade off - turns the blade off
  • clash - trigger a clash effect
  • dir [directory] - list files on sd card
  • cd [directory] - change directory, and sound font
  • play [file] - play wav file
Note that there is a drop-down at the bottom of the serial monitor that defaults to "No Line Feed", you must change it to "Newline" to use the serial monitor with TeensySaber.

Download Older versions

  • 1.8 - pre-alpha version
  • 1.10 - alpha version
  • 1.11 - beta version
  • 1.14 - first recommended version
  • 1.18 - preliminary teensy 3.5/3.6 and TeensySaber V2 support
  • 1.19 - Fixed BUILTIN_SDCARD
  • 1.20 - Fixed hang when reading directories ending in /
  • 1.40 - new LED configuration system, PWM over volt protection, audio bugfixes, improved audio buffering, better help system, multiple touch buttons, code cleanup
  • 1.43 - looped swing sound support
  • 1.45 - MTP, power+clash=previous preset, RAW/USL support
  • 1.60 - POV, V2 motion, APA102/Dotstar (Experimental)
  • 1.86 - multi-blade support
  • 1.89 - blade template system
  • 1.93 - fixed short activation
  • 1.110 - louder, lockup, flicker
  • 1.119 - bugfixes
  • 1.144 - GPLv3, speech, separate configuration files, zero-button sabers, mtp support for serialflash
  • 1.153 - Display/PLI, crossguard

Troubleshooting
If you're having problems, check out the troubleshooting page.

Problems? Questions? Suggestions? Check out the fx-sabers online forum.
This page has been accessed 3,629 times since July 25th, 2016.
Last modified: September 10th, 2017 - Design by Monica & Fredrik Hübinette