First Saber Build – Need Help with Custom Blade Behavior (Tri-Cree+Proffieboard v3)

Hey, I’m working on my first lightsaber build and have no experience with programming. I’ve used ChatGPT to help me write some code, but I feel like I’ve been trying to reinvent the wheel with it all, and I’d appreciate help getting it to run properly.

I’m using a proffieboard v3, tri-cree LED (white, white, and white), and I have one illuminated momentary button. All these parts came from The Saber Armory. I’m using them in a hilt I built from scratch.

This is my vision for how the saber would behave:

  1. Short press to ignite/retract the blade. I want it to fade in/out, but during ignition, I’d like it to “jump” out to 25% brightness immediately and then fade in the rest of the way from there.

  2. Long press triggers bladelock for the duration of the long press. I think bladelock is normally triggered by a press and clash at the same time, I don’t particularly care which it is for my setup, just whatever is simpler. I don’t need the “force” effect a long press normally triggers. here’s an example of the bladelock effect I already wrote with ChatGPT (I like the way it behaves):

void handleBladeLockEffect() {
  unsigned long elapsedTime = millis() - bladelockStartTime;

  if (elapsedTime % bladelockFlickerInterval < bladelockFlickerInterval / 2) {
    analogWrite(bladePowerPin1, random(100, pwmMax));
    analogWrite(bladePowerPin2, random(100, pwmMax));
    analogWrite(bladePowerPin3, random(100, pwmMax));
  } else {
    analogWrite(bladePowerPin1, pwmMax);
    analogWrite(bladePowerPin2, pwmMax);
    analogWrite(bladePowerPin3, pwmMax);
  }
}
  1. I want the blade to flicker during a clash (think half a second of the bladelock effect). my LEDs can’t flash a different color, so this is my “flash on clash”

  2. A double press switches sound fonts

  3. I want SmoothSwing and standard clash sounds

Those are all the features I’m aiming for in this build. I’ve gone down a rabbit hole with ChatGPT with making different .h files in various folders to do all that, but getting that to mesh with ProffieOS.ino is proving to be quite a headache. So my questions are:

  • Is this kind of behavior already implemented somewhere?
  • If not, is there a way to write custom behaviors like this into ProffieOS without rewriting everything myself?
  • I’ve read about saber.h and how it handles things, but some of it confused me… like the drag effect, is it just the same as bladelock for me because I don’t have a neopixel blade? And would my single button be considered the “POW” button?

Thank you for any help you can offer, I’m eager to get this thing working!

Have you tried using ProffieOS?
All of the things you want are already there.

You can start here: ProffieOS Documentation: Your first config file
Or, go find a video on youtube that explains how to configure and program a proffieboard. Some of them are good, some of them are bad, but ALL of them are better than chatgpt.

2 Likes

Yeah, what I’ve done is used the config generator to get my config file, then plugged that into ProffieOS with the #define CONFIG_FILE line. But when I upload that to my board and run it, the lights don’t turn on except for a flash during a clash. So I was trying to write things myself to get it working… but that didn’t work. I guess I’m just not sure how to utilize ProffieOS properly to get what I want from it.

What does the config file you created look like?

This is the auto-generated one:

#ifdef CONFIG_TOP
#include "proffieboard_v3_config.h"
#define NUM_BLADES 2
#define NUM_BUTTONS 1
#define VOLUME 1000
const unsigned int maxLedsPerStrip = 144;
#define CLASH_THRESHOLD_G 1.0
#define ENABLE_AUDIO
#define ENABLE_MOTION
#define ENABLE_WS2811
#define ENABLE_SD
#endif

#ifdef CONFIG_PRESETS
Preset presets[] = {
   { "TeensySF", "tracks/venus.wav",
    StyleNormalPtr<CYAN, WHITE, 300, 800>(),
    StyleNormalPtr<CYAN, WHITE, 300, 800>(), "cyan"},
   { "SmthJedi", "tracks/mars.wav",
    StylePtr<InOutSparkTip<EASYBLADE(BLUE, WHITE), 300, 800> >(),
    StylePtr<InOutSparkTip<EASYBLADE(BLUE, WHITE), 300, 800> >(), "blue"},
   { "SmthGrey", "tracks/mercury.wav",
    StyleNormalPtr<RED, WHITE, 300, 800>(),
    StyleNormalPtr<RED, WHITE, 300, 800>(), "red"},
   { "SmthFuzz", "tracks/uranus.wav",
    StylePtr<InOutHelper<EASYBLADE(OnSpark<GREEN>, WHITE), 300, 800> >(),
    StylePtr<InOutHelper<EASYBLADE(OnSpark<GREEN>, WHITE), 300, 800> >(), "green"},
   { "RgueCmdr", "tracks/venus.wav",
    StyleNormalPtr<WHITE, RED, 300, 800, RED>(),
    StyleNormalPtr<WHITE, RED, 300, 800, RED>(), "white"},
   { "TthCrstl", "tracks/mars.wav",
    StyleNormalPtr<AudioFlicker<YELLOW, WHITE>, BLUE, 300, 800>(),
    StyleNormalPtr<AudioFlicker<YELLOW, WHITE>, BLUE, 300, 800>(), "yellow"},
   { "TeensySF", "tracks/mercury.wav",
    StylePtr<InOutSparkTip<EASYBLADE(MAGENTA, WHITE), 300, 800> >(),
    StylePtr<InOutSparkTip<EASYBLADE(MAGENTA, WHITE), 300, 800> >(), "magenta"},
   { "SmthJedi", "tracks/uranus.wav",
    StyleStrobePtr<WHITE, Rainbow, 15, 300, 800>(),
    StyleStrobePtr<WHITE, Rainbow, 15, 300, 800>(), "strobe"}
};
BladeConfig blades[] = {
 { 0, SimpleBladePtr<CreeXPE2WhiteTemplate<550>, CreeXPE2WhiteTemplate<550>, CreeXPE2WhiteTemplate<550>, NoLED, bladePowerPin1, bladePowerPin2, bladePowerPin3, -1>(),
    SimpleBladePtr<CreeXPE2WhiteTemplate<550>, NoLED, NoLED, NoLED, blade5Pin, -1, -1, -1>()
  , CONFIGARRAY(presets) },
};
#endif

#ifdef CONFIG_BUTTONS
Button PowerButton(BUTTON_POWER, powerButtonPin, "pow");
#endif

That one kept my lights from working except for during a clash. This next one was what I tried to write after a lot of trial and error, but I couldn’t get it to verify (mostly due to definition or dependency errors):

#ifdef CONFIG_TOP
#include <Arduino.h>
#include <algorithm>
#include <utility>
#include <type_traits>
#include "../blades/LightsaberV3_DummyBlade.h"
#include "proffieboard_v3_config.h"
#include "../buttons/LightsaberV3_Button.h" 
#include "../common/saber_base.h"

extern const int pwmMax;
extern const int initialBrightness;
extern const unsigned long bladelockFlickerInterval;
extern const unsigned long longPressDuration;
extern const unsigned long clashDurationMs;
extern unsigned long bladelockStartTime;
extern unsigned long clashStartTime;
extern unsigned long lastButtonPressTime;

#define NUM_BLADES 1
#define NUM_BUTTONS 1
#define VOLUME 1000
const unsigned int maxLedsPerStrip = 144;
#define CLASH_THRESHOLD_G 1.0
#define ENABLE_SERIAL
#define ENABLE_AUDIO
#define ENABLE_MOTION
#define ENABLE_WS2811
#define ENABLE_SD
#define MOTION_SENSOR LSM6DS3

extern bool bladeOn;
extern bool bladelockActive;
extern unsigned long bladelockStartTime;
extern bool bladeFading;

#include "../blades/LightsaberV3_Blade.h"

// Define the ProffieOS-compatible action function
inline void ActionToggleBlade(EventPtr event) {
    toggleBlade(); // Call the toggleBlade function defined in _Button.h
}

// Configure Buttons and Actions
#ifdef CONFIG_BUTTONS
const PROGMEM ActionWrapper actions[] = {
    { BUTTON_POWER, EVENT_CLICK_SHORT, ActionToggleBlade },
    // Add other button actions here if needed
};
#endif

#endif

// Dummy blade to pass ProffieOS's internal checks (actual blade logic is custom)
#ifdef CONFIG_PRESETS
#include "../common/blade_config.h"
#include "../blades/LightsaberV3_DummyBlade.h"
#include "../common/preset.h"
#include "../blades/simple_blade.h"

Preset presets[] = {
    { "TeensySF", "boot.wav" }
};

BladeConfig blades[1] = {
    {
        0,
        SimpleBladePtr<NoLED, NoLED, NoLED, NoLED, bladePowerPin1, bladePowerPin2, bladePowerPin3, -1>(), // blade1
        presets, // presets
        (size_t)NELEM(presets), // num_presets
        "common" // save_dir (using "common" as a placeholder)
    }
};
#endif

My thinking was to give ProffieOS a “dummy blade” to work with so that the actual blade could be controlled with my code, and I was trying a similar thing with the button as well. The main reason I was trying to mix this with ProffieOS was for smoothswing. but here are those other files:
for the button…

#ifndef LIGHTSABER_V3_BUTTON_H
#define LIGHTSABER_V3_BUTTON_H

#include "../blades/LightsaberV3_Blade.h"
#include "Arduino.h"
#include "../common/saber_base.h"

extern bool bladeOn;
extern bool bladeFading;
extern bool bladelockActive;
extern unsigned long bladelockStartTime;
extern const unsigned long longPressDuration;
extern const int pwmMax;
extern const int initialBrightness;

void toggleBlade();

void ActionToggleBlade(EventPtr event);

void toggleBlade() {
    if (bladeFading) return;

    bladeOn = !bladeOn;
    bladeFading = true;

    if (bladeOn) {
        Serial.println("Blade activated.");
        analogWrite(bladePowerPin1, initialBrightness);
        analogWrite(bladePowerPin2, initialBrightness);
        analogWrite(bladePowerPin3, initialBrightness);
        delay(100);
        for (int brightness = initialBrightness; brightness <= pwmMax; brightness++) {
            analogWrite(bladePowerPin1, brightness);
            analogWrite(bladePowerPin2, brightness);
            analogWrite(bladePowerPin3, brightness);
            delay(5);
        }
    } else {
        Serial.println("Blade deactivated.");
        for (int brightness = pwmMax; brightness >= 0; brightness--) {
            analogWrite(bladePowerPin1, brightness);
            analogWrite(bladePowerPin2, brightness);
            analogWrite(bladePowerPin3, brightness);
            delay(5);
        }
    }
    bladeFading = false;
}

#endif // LIGHTSABER_V3_BUTTON_H

for the blade…

#ifndef LIGHTSABER_V3_BLADE_H
#define LIGHTSABER_V3_BLADE_H

#include "../sound/audiostream.h"

extern bool bladeOn;
extern bool bladelockActive;
extern const int pwmMax;
extern unsigned long clashStartTime;
extern unsigned long bladelockStartTime;
extern const unsigned long bladelockFlickerInterval;
extern int currentPreset;

void handleClashEffect();
void handleBladelockEffect();

void handleClashEffect() {
  Serial.println("Clash detected");
  for (int i = 0; i < 3; i++) {
    analogWrite(bladePowerPin1, random(100, pwmMax));
    analogWrite(bladePowerPin2, random(100, pwmMax));
    analogWrite(bladePowerPin3, random(100, pwmMax));
    delay(25);
    if (bladeOn) {
      analogWrite(bladePowerPin1, pwmMax);
      analogWrite(bladePowerPin2, pwmMax);
      analogWrite(bladePowerPin3, pwmMax);
    }
    delay(25);
  }
}

void handleBladeLockEffect() {
  unsigned long elapsedTime = millis() - bladelockStartTime;

  if (elapsedTime % bladelockFlickerInterval < bladelockFlickerInterval / 2) {
    analogWrite(bladePowerPin1, random(100, pwmMax));
    analogWrite(bladePowerPin2, random(100, pwmMax));
    analogWrite(bladePowerPin3, random(100, pwmMax));
  } else {
    analogWrite(bladePowerPin1, pwmMax);
    analogWrite(bladePowerPin2, pwmMax);
    analogWrite(bladePowerPin3, pwmMax);
  }
}

#endif // LIGHTSABER_V3_BLADE_H

for the dummy blade…

#ifndef LIGHTSABER_V3_DUMMYBLADE_H
#define LIGHTSABER_V3_DUMMYBLADE_H

#include "../common/profiling.h"
#include "../common/stdout.h"
#include "../common/math_utils.h"
#include "../common/color.h"
#include "../blades/blade_base.h"

extern bool bladeOn;

class DummyBlade : public BladeBase {
public:
    DummyBlade() {}
    virtual ~DummyBlade() {}

    virtual int num_leds() const override { return 0; }
    virtual Color8::Byteorder get_byteorder() const override { return Color8::RGB; }
    virtual bool is_on() const override { return bladeOn; } // Return the global state
    virtual bool is_powered() const override { return bladeOn; } // Return the global state
    virtual size_t GetEffects(BladeEffect** blade_effects) override { return 0; }
    virtual void set(int led, Color16 c) override {}
    virtual void allow_disable() override {}
    virtual bool IsPrimary() override { return true; } // It's the only blade
    virtual void Activate() override {}
    virtual void Deactivate() override {}
    virtual BladeStyle* UnSetStyle() override { return nullptr; }
    virtual void SetStyle(BladeStyle* style) override {}
    virtual BladeStyle* current_style() const override { return nullptr; }
};

extern DummyBlade dummyBlade;

#endif // LIGHTSABER_V3_DUMMYBLADE_H

and then a cpp file for the variables:

#include "LightsaberV3_Config.h"
#include "../buttons/LightsaberV3_Button.h"
#include "../blades/LightsaberV3_Blade.h"
#include "../sound/audiostream.h"
#include "../blades/LightsaberV3_DummyBlade.h"

DummyBlade dummyBlade;

bool bladeOn = false;
bool bladelockActive = false;
bool bladeFading = false;
bool clashActive = false;

int currentPreset = 0;

const int pwmMax = 255;
const int initialBrightness = pwmMax * 0.12;
const unsigned long bladelockFlickerInterval = 50;
const unsigned long longPressDuration = 750;
const unsigned long clashDurationMs = 150;

unsigned long bladelockStartTime = 0;
unsigned long clashStartTime = 0;
unsigned long lastButtonPressTime = 0;

unsigned long lastUpdate = 0;

void loop() {
  handleButtonPress();
   if (bladeOn && bladelockActive) {
    handleBladelockEffect(); // <== move it here
   }
   if (clashActive && (millis() - clashStartTime) > clashDurationMs) {
    clashActive = false;
   }
  handleBladeLockEffect();

  // Optional: if you still want custom clash override logic
  if (bladeOn && !clashActive) {
    // (Optional custom clash detection if not using built-in)
  }

  // Reset clashActive after clashDurationMs
  if (clashActive && (millis() - clashStartTime) > clashDurationMs) {
    clashActive = false;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(powerButtonPin, INPUT_PULLUP);
}

As I said, I feel like I’m trying to reinvent the wheel here. And I’m not even out of high school yet, so this project is my very first exposure to this whole programming world; I don’t know my way around yet at all. What would you recommend?

Sorry my backticks got messed up there

Fixed your backticks.

Don’t listen to chatgpt.
Ask here when you run into trouble instead.
Learn how to program. (optional)

All but the first example seems to be made up of random crap that kind of looks like code, but isn’t.

IMHO, the only thing wrong with the first example is that it has blades that can only show white colors. That means that all the other colors don’t show up. So if you replace CYAN, BLUE, RED, GREEN, YELLOW and MAGENTA with WHITE, it should work better.

Clashes won’t show up though, because they will be white on white.
In most presets, that can be fixed by replacing the second WHITE with BLACK (or some gray color, or some flickering color maybe.)

Thank you! I got it to turn the blade on properly. Here’s the BladeConfig blades section now:

BladeConfig blades[] = {
 { 0, SimpleBladePtr<CreeXPE2WhiteTemplate<550>, CreeXPE2BlueTemplate<550>, CreeXPE2WhiteTemplate<550>, NoLED, bladePowerPin1, bladePowerPin2, bladePowerPin3, -1>(),
    SimpleBladePtr<CreeXPE2WhiteTemplate<550>, NoLED, NoLED, NoLED, blade5Pin, -1, -1, -1>()
  , CONFIGARRAY(presets) },
};

I made the second CreeXPE2 blue instead of white (black was throwing up errors… I assume that’s because they don’t make a black cree LED). I can’t do proper clashes on my saber anyway because my LEDs can’t flash a different color; the color of the diode is set. Correct me if I’m wrong on that though.

I like the way everything runs, except for these two things:

  1. Can I adjust the way the blade ignites? I’d like it to jump to a higher brightness immediately and then fade in slower the rest of the way.

  2. Can/how do you switch sound fonts?

And if I wanted to use a sound font that isn’t on it currently, I would download it from wherever onto my computer, put the files on the SD card, but then what would I need to change in the code to get it in there? I’m guessing I’d add another section of this…

   { "SmthJedi", "tracks/uranus.wav",
    StyleStrobePtr<WHITE, Rainbow, 15, 300, 800>(),
    StyleStrobePtr<WHITE, Rainbow, 15, 300, 800>(), "strobe"}

I didn’t mean to change the BladeConfig though, it would be better to change the presets.

Depends on what you mean by “proper”.
I find that just turning the LED off briefly by setting the clash color to BLACK works well for sabers with only a single color LEDs.

Yes, you can do that by creating a new blade style which does what you want.
We have a style editor that lets you do lots of things like that:

Here is an example of a style that does what you want:

StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,100,100>,TrFade<300>>,TrFade<500>>>()

For the default prop setup, this page explains how the buttons work:

As you can see, hold the button and clash the blade while off to go to the next preset.

That is correct. That portion is called a “preset” and you can have as many of them as can fit in memory if you want. (Although it gets hard to navigate, so I recommend sticking with ~10 or so.) To add a font, you add another one of those, and change the first string to the name of the font.

To learn more about how to add a font, read this:

To learn more about presets and how they work, read this:

Why is it better to change the presets? and is this correctly done:

Preset presets[] = {
   { "TeensySF", "tracks/venus.wav",
    StyleNormalPtr<CYAN, WHITE, 300, 800>(),
    StyleNormalPtr<CYAN, BLACK, 300, 800>(), "cyan"},
   { "SmthJedi", "tracks/mars.wav",
    StylePtr<InOutSparkTip<EASYBLADE(BLUE, WHITE), 300, 800> >(),
    StylePtr<InOutSparkTip<EASYBLADE(BLUE, BLACK), 300, 800> >(), "blue"},
   { "SmthGrey", "tracks/mercury.wav",
    StyleNormalPtr<RED, WHITE, 300, 800>(),
    StyleNormalPtr<RED, WHITE, 300, 800>(), "red"},
   { "SmthFuzz", "tracks/uranus.wav",
    StylePtr<InOutHelper<EASYBLADE(OnSpark<GREEN>, WHITE), 300, 800> >(),
    StylePtr<InOutHelper<EASYBLADE(OnSpark<GREEN>, BLACK), 300, 800> >(), "green"},
   { "RgueCmdr", "tracks/venus.wav",
    StyleNormalPtr<WHITE, RED, 300, 800, RED>(),
    StyleNormalPtr<BLACK, RED, 300, 800, RED>(), "white"},
   { "TthCrstl", "tracks/mars.wav",
    StyleNormalPtr<AudioFlicker<YELLOW, WHITE>, BLUE, 300, 800>(),
    StyleNormalPtr<AudioFlicker<YELLOW, BLACK>, BLUE, 300, 800>(), "yellow"},
   { "TeensySF", "tracks/mercury.wav",
    StylePtr<InOutSparkTip<EASYBLADE(MAGENTA, WHITE), 300, 800> >(),
    StylePtr<InOutSparkTip<EASYBLADE(MAGENTA, BLACK), 300, 800> >(), "magenta"},
   { "SmthJedi", "tracks/uranus.wav",
    StyleStrobePtr<WHITE, Rainbow, 15, 300, 800>(),
    StyleStrobePtr<BLACK, Rainbow, 15, 300, 800>(), "strobe"}
};

And I’ll be honest I don’t understand how to use style editor website. Assuming I just use the section of code you sent, I’m guessing I put it in the presets section and replace all the StyleNormalPtr lines with that?

I’m also confused on how that line of code makes the LEDs fade in. I guess it’s in the TrFade sections, but why do we need 3 of them? And I guess these would go in the presets section (as opposed to BladeConfig) so that the effects can be specific to the sound font being played?

It can work either way, but it just makes more sense to use “White” in your presets since your LEDs are white.

What did you change?

if you want all presets to look the same, then replace all of them.
However, maybe you’ll want different presets to work differently?
That’s what presets are for…

Learning to understand style templates will take a little time, and playing around with the style editor is going to be a part of how you learn. Here is how I made this style though:

  • I used TrInOut<> which lets you use “transitions” to specify how the igniton and retraction should look.
  • for the igniton transition, I used this: TrConcat<TrFade<10>, Rgb<100,100,100>, TrFade<300>> which basically reads as "fade to 100 in 10ms, then fade from 100 to 255 in 300ms’ (TrConcat runs one transition after another, lets you specify which color to go to in between.)
  • The last TrFade<500> is actually the third argument to TrInOut<>, which specifies that the retraction is a simple 500ms fadeout.

Sorry I changed the wrong thing before… to get the blade to light up, the presets should look like this, correct:

#ifdef CONFIG_PRESETS
Preset presets[] = {
   { "TeensySF", "tracks/venus.wav",
    StyleNormalPtr<WHITE, WHITE, 300, 800>(),
    StyleNormalPtr<WHITE, WHITE, 300, 800>(), "white"},
   { "SmthJedi", "tracks/mars.wav",
    StylePtr<InOutSparkTip<EASYBLADE(WHITE, WHITE), 300, 800> >(),
    StylePtr<InOutSparkTip<EASYBLADE(WHITE, WHITE), 300, 800> >(), "white"},
   { "SmthGrey", "tracks/mercury.wav",
    StyleNormalPtr<WHITE, WHITE, 300, 800>(),
    StyleNormalPtr<WHITE, WHITE, 300, 800>(), "white"},
   { "SmthFuzz", "tracks/uranus.wav",
    StylePtr<InOutHelper<EASYBLADE(OnSpark<WHITE>, WHITE), 300, 800> >(),
    StylePtr<InOutHelper<EASYBLADE(OnSpark<WHITE>, WHITE), 300, 800> >(), "white"},
   { "RgueCmdr", "tracks/venus.wav",
    StyleNormalPtr<WHITE, WHITE, 300, 800, RED>(),
    StyleNormalPtr<WHITE, WHITE, 300, 800, RED>(), "white"},
   { "TthCrstl", "tracks/mars.wav",
    StyleNormalPtr<AudioFlicker<WHITE, WHITE>, BLUE, 300, 800>(),
    StyleNormalPtr<AudioFlicker<WHITE, WHITE>, BLUE, 300, 800>(), "white"},
   { "TeensySF", "tracks/mercury.wav",
    StylePtr<InOutSparkTip<EASYBLADE(WHITE, WHITE), 300, 800> >(),
    StylePtr<InOutSparkTip<EASYBLADE(WHITE, WHITE), 300, 800> >(), "white"},
   { "SmthJedi", "tracks/uranus.wav",
    StyleStrobePtr<WHITE, WHITE, 15, 300, 800>(),
    StyleStrobePtr<WHITE, WHITE, 15, 300, 800>(), "white"}
};

But then the blade won’t flicker on clash because it’ll flicker from white to white as opposed to white to black, so you said I should change the second “WHITE” to “BLACK:”

#ifdef CONFIG_PRESETS
Preset presets[] = {
   { "TeensySF", "tracks/venus.wav",
    StyleNormalPtr<WHITE, BLACK, 300, 800>(),
    StyleNormalPtr<WHITE, BLACK, 300, 800>(), "white"},
   { "SmthJedi", "tracks/mars.wav",
    StylePtr<InOutSparkTip<EASYBLADE(WHITE, BLACK), 300, 800> >(),
    StylePtr<InOutSparkTip<EASYBLADE(WHITE, BLACK), 300, 800> >(), "white"},
   { "SmthGrey", "tracks/mercury.wav",
    StyleNormalPtr<WHITE, BLACK, 300, 800>(),
    StyleNormalPtr<WHITE, BLACK, 300, 800>(), "white"},
   { "SmthFuzz", "tracks/uranus.wav",
    StylePtr<InOutHelper<EASYBLADE(OnSpark<WHITE>, BLACK), 300, 800> >(),
    StylePtr<InOutHelper<EASYBLADE(OnSpark<WHITE>, BLACK), 300, 800> >(), "white"},
   { "RgueCmdr", "tracks/venus.wav",
    StyleNormalPtr<WHITE, BLACK, 300, 800, RED>(),
    StyleNormalPtr<WHITE, BLACK, 300, 800, RED>(), "white"},
   { "TthCrstl", "tracks/mars.wav",
    StyleNormalPtr<AudioFlicker<WHITE, BLACK >, BLUE, 300, 800>(),
    StyleNormalPtr<AudioFlicker<WHITE, BLACK >, BLUE, 300, 800>(), "white"},
   { "TeensySF", "tracks/mercury.wav",
    StylePtr<InOutSparkTip<EASYBLADE(WHITE, BLACK), 300, 800> >(),
    StylePtr<InOutSparkTip<EASYBLADE(WHITE, BLACK), 300, 800> >(), "white"},
   { "SmthJedi", "tracks/uranus.wav",
    StyleStrobePtr<WHITE, BLACK, 15, 300, 800>(),
    StyleStrobePtr<WHITE, BLACK, 15, 300, 800>(), "white"}
}

Should the “white” in the quotes be changed as well? They were all different colors (blue, green, magenta, etc…) and I changed them to white before, but was that an error on my part?

Then, with the style you sent, the presets section would look like this (if I gave them all the same ignition effect):

#ifdef CONFIG_PRESETS
Preset presets[] = {
   { "TeensySF", "tracks/venus.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
   { "SmthJedi", "tracks/mars.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
   { "SmthGrey", "tracks/mercury.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
   { "SmthFuzz", "tracks/uranus.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
   { "RgueCmdr", "tracks/venus.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
   { "TthCrstl", "tracks/mars.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
   { "TeensySF", "tracks/mercury.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
   { "SmthJedi", "tracks/uranus.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,
100>,TrFade<300>>,TrFade<500>>>()
}

Does all that look right?
And these next questions might be answered in the CONFIG_PRESETS link you sent, but I haven’t read through that thoroughly yet…

  1. Under each sound file line, there are two StylePtr or StyleNormalPtr lines. Is the second one there because I said #define NUM_BLADES 2 at the top of the config file?
  2. What’s the difference between StylePtr, StyleNormalPtr, and the other styles?
  3. What is that word in quotes for (the “white” or “magenta” or “green” at the end of the second style line of each preset)?

That can be what ever you want. it can even be “” or missing if you also remove the previous comma. It is used for two things:

  • if you have an OLED screen, if will be displayed on it when you change between presets, that is why you shouldn’t use CAPS (not that you do) or it will display weird.
  • it is also used in serial monitor to identify which preset you are on.

Most people use it to identify the presets, so in your case that would be “teensysf”, “smthjedi” or you could do “smooth jedi” or “smooth\njedi” (\n is for next line) or “smooth\n jedi” jedi would be centered on smooth instead of aligned to the left of your OLED screen (you might need to adjust the number of “spaces”. I do not remember the max amount of characters per line on an OLED, but it is probably around 10-12ish. Of course an “m” and “w” are much wider than “i”.

It had colors names there because that was describing the colors of the different style codes.

You can also have “preset 1”, “preset 2”, …, “preset 50” as long as you like it and/or it makes sense for you.

1 Like

you are missing the closing brackets between presets. It should look like this:

#ifdef CONFIG_PRESETS
Preset presets[] = {
   { "TeensySF", "tracks/venus.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>, TrConcat<TrFade<10>, Rgb<100, 100>, TrFade<300>>, TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>, TrConcat<TrFade<10>, Rgb<100, 100>, TrFade<300>>, TrFade<500>>>(),
    "teesysf"},

   { "SmthJedi", "tracks/mars.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>, TrConcat<TrFade<10>, Rgb<100, 100>, TrFade<300>>, TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>, TrConcat<TrFade<10>, Rgb<100, 100>, TrFade<300>>, TrFade<500>>>(),
    "smthjedi"},

   { "SmthGrey", "tracks/mercury.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>, TrConcat<TrFade<10>, Rgb<100, 100>, TrFade<300>>, TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>, TrConcat<TrFade<10>, Rgb<100, 100>, TrFade<300>>, TrFade<500>>>(),
    "smthgrey"},

   { "SmthFuzz", "tracks/uranus.wav",
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,100>,TrFade<300>>,TrFade<500>>>(),
    StylePtr<InOutTr<EasyBlade<White, Black>,TrConcat<TrFade<10>, Rgb<100,100>,TrFade<300>>,TrFade<500>>>(),
    "smthfuzz"},
...
 };

Don’t forget final closing bracket “}”. Every “{” needs a corresponding “}”, same goes for “(” & “)”, “[” & “]”, “<” & “>”

And I would recommend one blade bladestyle per line and an empty line between presets. It makes for an easier reading and checking if you missed anything. (“spaces” and empty lines don’t consume memory)

1 Like

yes

they do different things

I believe I answered that 2 posts above.

you should start with that. :wink:

1 Like

That is just a name for the preset.
It’s not particularly important what you write there unless you have an OLED display.

You now have some presets that are identical (except for the “track”).
If you want them to be this similar, then you should probably clean up the duplicates.
Another thing is that you have two blades. One of them is not doing anything and you should probably clean that up at some point. (But it’s not important, so you don’t have to do it if you don’t want to.)

Please do.

yes

StyleNormalPtr<> is a macro that expands to something that uses StylePtr<>, plus some “normal” blade things, like clash, lockup, etc. You can paste a StyleNormalPtr<> style into the style editor, then press “submit” and then “expand” to see what it actually expands to.

“the other styles” is too broad a topic to explain right now…

It’s the name or “message” part of the prefix. Unless you have an OLED display it’s only used for debugging, so you can basically put whatever you like there.