Unlike the V1 TeensySaber electronics, the Proffieboard is not
something I recommend that most people build themselves. All the
instructions for doing so are available here,
but most people should just continue reading to find out how to use
the board.
What you will need:
(optional) ST-Link V2 - Lets you run a debugger on the program running on the Proffieboard.
Pinout
Arduino pin numbers in parenthesis.
BATT+ - 2.6 to 4.5 volt input, drives everything except the LEDs
BATT- - negative pad for LEDs, needs to be at same level as GND when both are connected. Note that there are two of them, which can be useful when driving many powerful LEDs.
GND - ground for electronics except LEDs. Note that the two GND pads are interchangable and connected through the board.
Speaker +/- - hooks up to speaker
Button 1/2/3 - Hook up to closing buttons, or potentially touch buttons.
Data 1 / ID - Normally used to measure the blade ID restor, and if it's a neopixel blade, feed out neopixel data. For a fixed non-neopixel saber, it could be repurposed.
Data 2-5 - additional neopixel data outputs, or free for other purposes.
LED 1-6 - Hooks up to negative side of LED (positive side of LED hooks up directly to battery.) These pads can handle up to 30 volts.
SDA, SCL - these pins are used to communicate with the gyro and accelerometer chip.
5v - generated by the proffieboard, normally it's only on when sound is playing.
3.3v - generated by the proffieboard.
SWDIO, SWDCLK - can be hooked up to a ST-LINK device and lets you debug programs running on the proffieboard.
Wire gauges
Most pads on the proffieboard will not need to carry any significant amount
of power and can use 30 awg (very thin) wire if you choose.
However, Battery- will carry the combined power of all your LEDs, which is a fair amount of power. It is recommended to use thicker wires, for these wires. There is no absolute rules for what wire guages are required, but here is a helpful chart. (See the "chassis wiring" column.) Keeping the high-power wires short helps as well.
Configurator
Select your configuration below. Note that while this tool can show many different configurations for the
Proffieboard, there are many many more possible configurations.
// Fire speed, valid values are 1 - 10
#define FIRE1_SPEED 2
// How long to wait before firing up crossguards.
#define FIRE1_DELAY 800
// Each of these have three values: A, B, C
// A = non-random intensity
// B = random intensity
// C = cooling
// The first two control temperature, and as we add
// A + rnd(B) to the base of the blade each animation frame.
// The second controls how rapidly the fire cools down
// This is used during normal operation.
#define FIRE1_NORMAL 0, 1000, 2
// This is used when a clash occurs
#define FIRE1_CLASH 3000, 0, 0
// This is used during lockup.
#define FIRE1_LOCKUP 0, 5000, 10
// Helper
#define FIRE1PTR(NUM, DELAY) \
StyleFirePtr<RED, YELLOW, NUM, DELAY, FIRE1_SPEED, \
FIRE1_NORMAL, FIRE1_CLASH, FIRE1_LOCKUP>()
Preset presets[] = {
{ "fontdir", "track.wav",
FIRE1PTR(0, 0),
FIRE1PTR(1, FIRE1_DELAY),
FIRE1PTR(2, FIRE1_DELAY),
},
{ "fontdir", "track.wav",
StyleNormalPtr<RED, WHITE, 200, 300>(),
StyleNormalPtr<RED, WHITE, 200, 300>(),
StyleNormalPtr<RED, WHITE, 200, 300>()
},
{ "fontdir", "track.wav",
StyleRainbowPtr<300, 800>(),
StyleRainbowPtr<300, 800>(),
StyleRainbowPtr<300, 800>()
},
{ "fontdir", "track.wav",
StyleNormalPtr<CYAN, WHITE, 300, 800>(),
StyleNormalPtr<CYAN, WHITE, 300, 800>(),
StyleNormalPtr<CYAN, WHITE, 300, 800>()
},
{ "fontdir", "track.wav",
StylePtr<InOutSparkTip<EASYBLADE(BLUE, WHITE), 300, 800> >(),
StylePtr<InOutSparkTip<EASYBLADE(BLUE, WHITE), 300, 800> >(),
StylePtr<InOutSparkTip<EASYBLADE(BLUE, WHITE), 300, 800> >()
},
{ "fontdir", "track.wav",
StyleFirePtr<BLUE, CYAN, 0>(),
StyleFirePtr<BLUE, CYAN, 1>(),
StyleFirePtr<BLUE, CYAN, 2>()
},
{ "fontdir", "track.wav",
StylePtr<InOutHelper<EASYBLADE(OnSpark<GREEN>, WHITE), 300, 800> >(),
StylePtr<InOutHelper<EASYBLADE(OnSpark<GREEN>, WHITE), 300, 800> >(),
StylePtr<InOutHelper<EASYBLADE(OnSpark<GREEN>, WHITE), 300, 800> >()
},
{ "fontdir", "track.wav",
StyleNormalPtr<WHITE, RED, 300, 800, RED>(),
StyleNormalPtr<WHITE, RED, 300, 800, RED>(),
StyleNormalPtr<WHITE, RED, 300, 800, RED>()
},
{ "fontdir", "track.wav",
StyleNormalPtr<AudioFlicker<YELLOW, WHITE>, BLUE, 300, 800>(),
StyleNormalPtr<AudioFlicker<YELLOW, WHITE>, BLUE, 300, 800>(),
StyleNormalPtr<AudioFlicker<YELLOW, WHITE>, BLUE, 300, 800>()
},
{ "fontdir", "track.wav",
StylePtr<InOutSparkTip<EASYBLADE(MAGENTA, WHITE), 300, 800> >(),
StylePtr<InOutSparkTip<EASYBLADE(MAGENTA, WHITE), 300, 800> >(),
StylePtr<InOutSparkTip<EASYBLADE(MAGENTA, WHITE), 300, 800> >()
},
{ "fontdir", "track.wav",
StyleNormalPtr<Gradient<RED, BLUE>, Gradient<CYAN, YELLOW>, 300, 800>(),
StyleNormalPtr<Gradient<RED, BLUE>, Gradient<CYAN, YELLOW>, 300, 800>(),
StyleNormalPtr<Gradient<RED, BLUE>, Gradient<CYAN, YELLOW>, 300, 800>()
},
{ "fontdir", "track.wav",
StyleStrobePtr<WHITE, Rainbow, 15, 300, 800>(),
StyleStrobePtr<WHITE, Rainbow, 15, 300, 800>(),
StyleStrobePtr<WHITE, Rainbow, 15, 300, 800>()
},
{ "fontdir", "track.wav",
&style_pov,
StyleNormalPtr<BLACK, BLACK, 100,100>(),
StyleNormalPtr<BLACK, BLACK, 100,100>(),
},
{ "charging", "notrack.wav",
&style_charging,
StyleNormalPtr<BLACK, BLACK, 100,100>(),
StyleNormalPtr<BLACK, BLACK, 100,100>(),
},
};
// Hook up the main blade as normal.
// Hook up one of the crossguards like this:
// NEOPIXEL + <--> positive power (probably from charge port)
// NEOPIXEL - <--> LED4 pad on the bottom of the teensysaber
// NEOPIXEL data <--> Nepixel data 2 (through a 300ohm resistor)
// Hook up the other crossguards like this:
// NEOPIXEL + <--> positive power (probably from charge port)
// NEOPIXEL - <--> LED5 pad on the bottom of the teensysaber
// NEOPIXEL data <--> Nepixel data 3 (through a 300ohm resistor)
BladeConfig blades[] = {
{ 0, // blade ID resistor not used
// Main blade, 118 LEDs
WS2811BladePtr<118, WS2811_800kHz | WS2811_GRB>(),
// First crossguard, 26 LEDS, power on LED4, data on pixel data 2
WS2811BladePtr<26, WS2811_800kHz | WS2811_GRB, blade2Pin, PowerPINS<bladePowerPin4> >(),
// First crossguard, 26 LEDS, power on LED5, data on pixel data 3
WS2811BladePtr<26, WS2811_800kHz | WS2811_GRB, blade3Pin, PowerPINS<bladePowerPin5> >(),
CONFIGARRAY(presets)
},
};
Programming
Most of the time, programming the Proffieboard is as easy as hookin up the USB cable to a
computer and pressing the "upload" button in the Arduino IDE. However, an interrupted upload
or a crashing program can sometimes stop that from working. If that happens, hold the boot
button, then press and release the reset button. This will put the Proffieboard in bootloader
mode, and pressing "upload" should now work.
Touch Buttons
Any of the buttons can replaced with a touch button.
To wire a touch button, simply hook up the corresponding wire to a metal surface. Note that in spite of the name, you don't
actually want anybody to actuall touch the touch buttons. The metal surface needs to be insulated, both from the
rest of the hilt, and from the fingers that will be "touching" it. In my case, I used a circuit-board clamp card in a Graflex
lightsaber, then I covered it up with tape to insulate it from everything else.
More details here.
Choosing Resistors
Calculating resistor values is fairly easy. Just look up how many amps the LED can handle and at what voltage it expects to achive that current. Then the resitor value we want is (BatteryVoltage - LedVoltage) / LedAmps. And the resistor needs to handle (BatteryVoltage - LedVoltage) * LedAmps watts. Example, if the LED wants 1A @ 3.2 volts, the resistor would be (3.7 - 3.2)/1 = 0.5 ohms, (3.7 - 3.2) * 1 = 0.5 watts.
Note that I use 3.7 volts for the battery in these calculations, while li-ion batteries tends to top out at 4.2 volts.
Proffieboard can compensate for this by using PWM to reduce the total amount of power and heat generated by the LED when
the voltage is higher than what it is rated for. This mode is efficient and seems to work well, but it is possible that it
will reduce the life of the LEDs. If you are not comfortable with this, you should use 4.1 or 4.2 volts in the calculations above.
Multi-battery setup
The FETs on the proffieboard can handle voltages up to 30v, so it's possible to do multi-cell setups. However, "Battery+" cannnot handle more than ~4.5 volts. So you would need a separate battery to power the CPU. Another possibility would be to do two batteries in series, but only use one of them to power the CPU. Since the batteries would be discharged unevently, they would have to be charged separately. In the future, I hope to make "Battery+" handle a wider range of voltages, which would make multi-cell configurations a lot simpler.
Using Data 1, 2, 3 and 5 (not 4) for PWM
Data 1, 2, 3 and 5 can be used to drive LEDs instead of neopixels.
However, a single timer is used to drive these pins. For PWM, the timer is usually set to 800Hz, however, when neopixels are used, this timer is set to 800kHz. This basically means that if you use any neopixels, all of these pins become unsuitable for driving LEDs. So, if you select a 6-segment blade + flash string in the configurator above, you cannot use the other data pins to drive nepixels unfortunately.
Troubleshooting
If you're having problems, check out the troubleshooting page.
Problems? Questions? Suggestions? Check out The Crucible.
This page has been accessed 130,924 times since
July
22nd,
2018.
Last modified:
March
29th,
2021
- Design by
Monica &
FredrikHübinette