Clash Settings and Questions

Yo, it’s me again XD

This time I want to take a more in depth look into the changes that’ve been made to Clashes through the years. My stock saber has a relatively low clash threshold, so that phantom clashes (clashes where nothing is touching the saber) happen if you’re trying to make them happen. Now, I happen to LIKE these phantom clashes, especially where you can set them off if you’re practicing blocking movements and such. Full disclosure, I have NO idea what my stock settings are, I never got the manufacturer’s config, just a similar one that works, so I don’t know what the original settings are.

Fast Forwards to OS7, and the clash detection is WAY different. Better in some ways and worse in others (IMO! Fett and Fred are doing amazing work always :D) but I’ve messed around with all sorts of clash thresholds and top config defines, but nothing seems to be able to replicate these phantom clashes I like. I’ve noticed that there’s nearly no way to make a clash happen mid-swing, which seems very intentional, but… Is there a way to change this?

How could one go about messing with the clash detection on a more fundamental level? Any thoughts or ideas…?

Care for what you wish for, you might get it…

In the beginning, there was CLASH_THRESHOLD_G.

Originally, the clash algorithm would simply compare the new accelerometer value with the last accelerometer value, and if it was greater than CLASH_THRESHOLD_G, it would trigger a clash, like:

|Acceleration_{now} - Acceleration_{last} | > CLASH\_THRESHOLD\_G

Note that the acceleration values are vectors with X, Y and Z components, and the || takes the length of the vector. In other words, this is the same as doing:

X = XAcceleration_{now} - XAcceleration_{last}
Y = YAcceleration_{now} - ZAcceleration_{last}
Y = YAcceleration_{now} - ZAcceleration_{last}
\sqrt{X^2 + Y^2 + Z^2} > CLASH\_THRESHOLD\_G

The problem with this algorithm is that the frequency of readings changes what it does. If you get more readings per second, then the difference between each one will be smaller, so the same CLASH_THRESHOLD_G wouldn’t work. Back then, Proffieboards were new, and there were lots of Teensysabers still around, and because of differences in how they worked, they would often get different number of readings per second.

So a long long time ago, I changed this algorithm, instead of using the “last” value, I used a slow average of values instead, so the algorithm became:

| Acceleration_{now} - Acceleration_{average} | > CLASH\_THRESHOLD\_G

In ProffieOS 3, this algorithm was improved by adding the Fusor class. The Fusor uses the accelerometer and the gyro to calculate a down vector. When nothing is happening, the down vector and the accelerometer should be the same thing. But this allowed me to change the algorithm to:

| Acceleration_{now} - Down | > CLASH\_THRESHOLD\_G

So far, the improvements have been just that: improvements, however, at this point the story takes a bit of a turn… I discovered two potentially problematic things.

  1. The range for acceleration values was set to -4 to 4. Values higher than this would be truncated by the motion chip. For some reason though, many people seemed to find that they needed values around four for clash detection to work well for them. Values around 3.9 were quite common for some reason. To me, that meant that the algorithm wasn’t really working as designed. Also, it gets a little wonky, because the truncation is cube-shaped, so if you hold your saber at a 45 degree angle, then the maximum value would be \sqrt{3 * 4^2} = 6.9 and having an algorithm that works differently depending on the angle didn’t seem like a good idea.
  2. The accelerometer was set to 1600 readings per second. However, because of implementation details, we were usually only getting 800 readings per second, but sometimes it was much less, if your saber had lots of blades, OLED displays and stuff. A related problem was that OLED displays were updating slowly when the saber was on.

So I implemented an interrupt-driven i2c handler, which lets us reliably read 1600 accelerometer reading per second, and I also changed the range of values returned by the accelerometer from 4 to 16. Both of these seemed like a good idea, more and better data, right?

This turns out to not always be the case.

It turns out that when you sample the accelerometer very quickly, sound has a bigger impact on the readings. In the past, readings got smaller when I read the accelerometer more often, but this time, they got bigger, which causes more false clashes. Also, whatever fluke made the 3.9 values work well disappeared because I changed the range to 16.

In order to figure out what was going on, I added some defines to control the speed and range of accelerometer readouts:


This one can be set to 2, 4, 8 or 16, and specifies the range of values measured by the accelerometer. Higher values means less precision, but we don’t really need high precision, so it doesn’t really matter. However, if you want the 3.9-value-fluke, you should set this to 4.


This define controls how often we read the accelerometer. I don’t remember exactly what all the valid values are, but the interesting ones are basically 800 and 1600. The default is 1600, 800 is basically what ProffieOS 5 and below would get.

Once we started figuring out what was going on. We also added some potential solutions to the problem. In ProffieOS 6 there were two changes meant to solve this problem. The first one is a filter that averages the clash values over a short period of time to try to get rid of the high values that sometimes comes from sound. This filter is controlled by this define:


The default is 800, and the code just creates a box filter of size (PROFFIEOS_MOTION_FREQUENCY / ACCCEL_MEASUREMENTS_PER_SECOND = 2) to do the averaging. Setting this define to the same value as PROFFIEOS_MOTION_FREQUENCY (1600) means that no filtering will occur. Setting it to a lower value is also valid, but will cause some (very minor) latency in clash detection.

The other solution is:


This define checks the volume of sound currently being emitted and increases the CLASH_THRESHOLD_G accordingly. Higher values means more suppression when the volumes goes up, but that also means it’s more difficult to actually make a clash happen.

Together these two things worked fairly well, but some people still had problems, and lots of people found that their old CLASH_THRESHOLD_G values were too low, and had to increase them to 5-7 for things to actually work. This wasn’t really my intention, but that’s what happened.

At some point after releasing ProffieOS 6, Fett263 told me that he used the gyro to detect clashes in his blade code. I’m like you do what? Here I had been using the accelerometer for years, and it turns out there is different way…

So I did a bunch of experimentation, and I found that the gyro values tends to spike when a clash occurs. This makes sense, because there is a change in rotation when the blade hits something. However, I found that the type of clash would affect the size of the gyro spike quite a bit, making it not always reliable. However, if I used both the gyro and the accelerometer, I got a clash detector that seemed to work much better than either one individually.

The formula is basically:

| accel - down |/2+ | \Delta gyro|/2 > CLASH\_THRESHOLD\_G

For many people, this formula works really well, and it helps filter out most of the false clashes. However, for some people, this formula seems to be the opposite of helpful, forcing them to increase their clash threshold and make clashes harder to trigger. I’m not sure why that is though, but somehow the clash spike and the acceleration spike must not arrive at the same time.

Anyways, I made a define for disabling this new formula and use the previous one:


For some people the old formula works better, and they need this define.

That’s it.

There is one detail I left out, because I don’t remember when I added it, and there is no define to control it. (It was a long time ago though.)

There is a piece of code in there that checks the swing speed, and increases the clash threshold accordingly. Before I added this, false clashes during swings were very very common. That code lives here:

If you wish, you could change the 200 .0 to something higher to make it do less suppression based on swing speed, since that seems to be what you want.


This is amazing Prof. :pray: :clap: :muscle: I’m going to include a link to this page with every config file so that if a particular install exhibits unusual or quirky clash issues, myself or other users can get under the hood with all the tools available and an explanation of how each one works so we can fine tune the hilt to behave exactly as we want it to. A fantastic resource. Thank you. :pray:

I think we need this reply pinned (somehow) or as it’s own POD page. Very informative and helpful.


I’ve updated my Config Helper tool with a new section to select and add these defines. More info here:

1 Like

Made a POD page out of it:


glad to see this thread took off XD
I’m gonna take a looksie under the hood whenever i have time, but this info is all amazing! thanks a million man!

Just wanted to pop in & say thank you for being this detailed. I am late as usual, but recently I finally swapped to OS7.14 & my clash settings seemed to be entirely different. I found this post pretty quick, which I would call a wealth of knowledge. I ended up changing Audio Suppression to #1 and it works better than it did before. Awesome community.