Blade not turning off

I’m having a consistent issue where after some time, the (LED strip) blade no longer turns off but instead remains on at a very dim level. Turning on the saber brings the blade back up to full brightness and everything works as normal, but turning off the saber doesn’t turn off the LED strip. Switching to a different (new) LED pad on the proffieboard fixes it and the blade/LED strip are fine again, but eventually the same thing happens again. I’ve had it on a few boards now, any ideas on what could be causing this issue? Trying to pinpoint exactly what is happening so I can fix it for future iterations.

This sounds like the MOSFET(s) failing: staying partially (or completely) closed. This typically means you’ve “burnt out” the MOSFET.

An obvious example of this happens when you short things (high current) and results in an explosion and magic smoke, but it can be more subtle.

“A” new LED pad? It’s generally recommended to put blades on two. I don’t recall the exact specifications for what kind of LEDs you’re using for your blade (or if you ever shared them, also I assume this is the same retractable design you’ve been working on) to have an idea how much current is expected.

If the MOSFET is being pushed to the edge and overheating, it can damage it, causing the issue you describe.

1 Like

Thanks so much for your answer and oh my goodness…can’t believe I missed that LED strips are supposed to be attached to two LED pads instead of one. Is that recommendation because one MOSFET can’t typically handle the LED current so it should go through two? If the LED strip is shorted, won’t this blow both MOSFETs?

We are using LSanalogWrite to set the duty cycle of the LED strip in our prop file code, I guess this means we now need to open up both pads in the code at the same duty cycle for it to work properly?

LSanalogWrite(LED_STRIP_PIN, 25000);

LSanalogWrite(LED_STRIP_PIN_PAD_2, 25000);

And our config file now needs to change to something like this?

BladeConfig blades[] = {

{ 0,

SimpleBladePtr<myLED, NoLED, NoLED, NoLED, bladePowerPin1, bladePowerPin2, -1, -1>(),

CONFIGARRAY(presets)}

};

The LED strip we’re using is a 12V COB LED strip, it draws around an amp I believe. It is the retractable design so the LED strip curls around itself when stored in the hilt, so I was worried it’s shorting itself somehow and that’s how it’s damaging the MOSFET. But if the single MOSFET isn’t supposed to be taking the full current of the LED strip I think that may be the culprit.

Simply put, yes.

The current ratings of the MOSFETs themselves in the datasheet is 13A if I recall correctly, which no blade ever really draws (save for occasional peaks on some of the most power hungry), but it’s only half the story. Power/thermal dissipation is the more crucial bottleneck, and attributing what’s “safe” it’s somewhat nebulous for at least a few reasons.

Correct. It’s just like two strands of wire, current flows through each evenly (more or less).

To be clear though, I only gave the shorting example since it’s a common mistake (and the magic smoke even more so) for people new to sabers and electronics in general, not that that’s your issue here.

Right.

As far as code goes, I’m not quite sure what you’ve got setup here (I’m just not familiar with your history).

In the prop, where does your LED_STRIP_PIN (and 2) definition come from? Is it hardcoded?

Afaics if you’re manually writing a simple, single (or multiple, but discrete and hardcoded in any case which ignores the blade info and blade style) PWM value, you’re bypassing the SimpleBlade definition and don’t need it at all.

If you’re pushing 12V to it, so 12W, I could see that being enough to cause problems over time, if not perhaps a bit surprising. I don’t have the MOSFET data sheet in front of me to check right now though. It could also be wherever you’re sourcing your board from is cheaping out on components… pretty much all the Chinese vendors are known (well, suspected, at least, on account of generally seemingly higher failure rate and other odd issues) to do that, some with worse track records than others.

If that was the case, you’d almost certainly have a much more “exciting” spectacle than dying, from what I can tell from your description, slowly over time.

It doesn’t take very long with a short to blow things up.

Yes, it’s much more likely you’re just overloading the MOSFET.

1 Like

Got it, thank you so much for clarifying. Will connect it to two LED pads and hopefully that’ll resolve the issue.

In the prop file the definitions are hardcoded to the bladePowerPins, I found we still need the SimpleBlade definitions in the config file for the blade dimming upon retraction and when troubleshooting with the serial monitor. I think I’m just confused with the SimpleBladePtr arguments and where to specify the second LED pad that we’re now connecting the LED strip to as well.

We’re using Proffieboards from KR Sabers and Tritium Sabers, so I don’t think the components are an issue. Still I am surprised that the FETs are being overloaded with the current we are passing through them.

Actually one more question, with this code:

LSanalogWrite(LED_STRIP_PIN, 25000);
LSanalogWrite(LED_STRIP_PIN_PAD_2, 25000);

Is there a chance that the duty cycles of the two pads won’t sync up perfectly, potentially having the effect of one of the two pads always on? (and thus a higher overall duty cycle than intended for the LED strip?)

Hmm, I see. So I guess you’re “fighting” with it for control over the blade. Well, if it works, I figure you probably don’t really want to mess with things.

So then this page is probably of help, but the gist is that you want

SimpleBladePtr<myLED, myLED, NoLED, NoLED, [Power Pin 1], [Power Pin 2], -1, -1>()

Replacing the [] items w/ the actual pin names. That’s mostly what you had, the primary difference being the profile for Led 2 being defined (myLED instead of NoLED).

I’d recommend 2 and 3 or 4 and 5 rather than 1 and 2 or 5 and 6, since the former 2 pairs have pads which are physically next to each other, so it’s just a bit more convenient for soldering.

I’m then inclined to agree.

I just looked, the FETs are only rated for 2.2W power dissipation with 25C ambient temperature and 11.5mOhm resistance w/ 4.5V Vgate (so more for lower gate, and I frankly also don’t know enough about MOSFET construction to understand how exactly all the variables play together). That’s pretty typical. Those measurements are also done on a board w/ much more copper for heat sinking than you have available on a proffieboard, and it also doesn’t take into account loss from switching, and probably a bunch of other things I don’t know about lol. It’s perhaps then not hard to imagine how you’d be overloading things using just one. The ratings can’t quite be taken at face value (in both directions, though thinking about it more we’re disposed unfavorably in this case). Like I said, there’s a fair amount of grey.

1 Like

No, the pulses are synced in hardware. Should be the same clock driving things. It’s not like the pulses are synced to whenever your software runs. Even if that were a potential problem, you’d still be alternating the load, and thus distributing where the heat is being dumped.

For that second bit, I’m mistaken. You’re right that if they were not synced it’d be an issue, as it would potentially be as if there were no PWM or a higher duty cycle, rather than the LEDs being completely cut off, so it wouldn’t be distributed like how I claimed. But yeah, in light of things being hardware synced you don’t need to worry.

1 Like

Got it, thanks for the help on the code as well! That is a lot lower power dissipation than I thought on the FETs, it totally makes sense how we’re overloading them now. Almost makes me wonder if I should hook it up to three of the FETs instead of two lol.

Good to know the pulses/timers are synced in hardware! I hope the syncing still works with our custom prop file but it should, I didn’t touch anything with the timer definitions. Was more concerned on the LED strip side that it would effectively see an “always-on” state which could burn it out since we are technically overdriving the LED strip with a 4S LiPo battery (16.8V)

Of course :slight_smile:

Careful with the interpretation here. 2.2W isn’t referring to how much power can be moving through the MOSFET, it’s referring to how much can be dissipated when power is lost as heat due to the natural resistance of the MOSFET and other factors, so there’s some consideration to be had.

Doing the math, the theoretical loss from your system (using 16.8V @ 1A) is in the range of dozens of mW, but that doesn’t account for switching, and 1A doesn’t seem right to me…

I’m not an EE, at least not at the time of writing, so like I said I don’t fully appreciate all the factors that need considering nor much of the theory at play, but I understand that switching losses can be significant, especially depending on what the actual gate output from the mcu looks like, so w/ higher amperage and switching losses, it could go higher. Coupled with the fact that, with much lesser heat sinking, the acceptable dissipation is likely much less than 2.2W.

1 Like

It wouldn’t matter, that bit of it is actually simply a hardware-locked mechanism. The PWM clock is derived from some master clock, and both channels would be derived from the same clock. With the same dividers on each channel, an identical output would be produced.

It’s the same for normal SimpleBlade usage, or PWM usage in general.

I gotcha. Yeah, that won’t be an issue.

I updated my earlier comment since I did misrepresent things a little bit unintentionally at first, in case you didn’t see.

1 Like

I learn something new every day, thanks again for all the knowledgable help! I really appreciate it.

1 Like

Maybe this is resolved now, but there is definitely some confusion in this thread. Normally, we use two FETs to power a neopixel strip because 288 neopixel LEDs can draw up to about 10A of power, and sometimes a single FET doesn’t handle that well.

In this particular case it’s not a neopixel strip though, it’s a strip of regular LEDs, running at 12V, one amp per channel. (or, is it maybe a single channel/color?) The voltage adds no extra strain on the FET, and for a single amp, you do not need two FETs.

Actually, they are not. I synchronize them in software here:

The hardware does have a way to synchronize PWM as well, but it’s a harder to use because the link between timers is limited to a few hard-wired choices.

All the timers are synchronized this way, so if you do LSAnalogWrite on two different channels, they will operate in sync. This is intentional and meant to enable bonding channels together. It is of course important that you write the same value to the two LSAnalogWrite() calls.

For the most part. this doesn’t apply to Proffieboards. Switching loss occurs while the FET is transitioning from on to off or from off to on. However, that only takes a handful of nanoseconds. Since Proffieboard PWM runs at 833 Hz, the fraction of time spent in transition is very pretty close to zero.

You’re using LSAnalogWrite(), right? (Or are you using SimpleBlade?)
And you’re sure that you set it to zero?

With simpleblade, there is a possibility that this happens because ProffieOS turns off the output and relies on the pulldown resistor when the output is off. But I wouldn’t expect that to happen here since you call LSAnalogWrite yourself, right?

As others have pointed out, there is a possibility that the FET itself is damaged, in which case just using a different channel would fix it.

1 Like

Ah okay, thanks for clarifying! For the single LED strip we’re using, maybe it is drawing more than an amp when it is coiled up because of lack of heat dissipation.

The prop file uses both I believe since we call SaberBase::TurnOn(); and SaberBase::TurnOff(SaberBase::OFF_NORMAL); but also use LSanalogWrite() to set the LED duty cycle specifically. We set it to zero using LSanalogWrite() in the code for the turnoff sequence, but the timing for the turnoff sequence sometimes coincides with the timing of SaberBase::TurnOff(SaberBase::OFF_NORMAL); could that be messing things up with the pulldown resistor and leaving the blade slightly on? However when I use the serial monitor to send off commands the LED strip still doesn’t turn off, which leads me to believe the FET has been fried?

I’m not sure if hot LEDs draw more or less power.
Check the data sheets maybe?

SaberBase::TurnOn() just sends a signal to whatever blade(s) you have. If no blade definition is specified for this blade, than TurnOn will not touch it.

I don’t think so.

When in doubt, measure. :slight_smile:

In your case, the voltage on the input pin is particularly interesting.
If it’s not low enough, or if it has a non-zero PWM duty cycle, then the problem is in the CPU, either a software problem, or something wrong with the output. If the input pin has zero voltage, but the FET is still letting current through, then there is something wrong with the FET.

It’s easier to just move the connection to another FET, update the code and see if it works better though.

Note that different board manufacturers might actually use different FETs, and the performance might be different.

Now the fact that this starts to happen after a while might be a vital clue. Maybe it’s because something is getting warm? Is it the same amount of time every time? If so it’s almost certainly a software issue.

1 Like

So it seems I have a code issue…LSanalogWrite() isn’t actually setting the duty cycle for the LED strip, I believe SaberBase::TurnOn() is which is supplying the blade the full power of the battery and makes a lot more sense as to how we’re overloading the FET. Just tried to reduce the duty cycle to 1000/32768 with LSanalogWrite(LED_STRIP_PIN, 1000) and it still lit up at full brightness. I’ve tried searching for where SaberBase::TurnOn() sets the PWM value in the ProffieOS documentation but I can’t find it, is there a way I can set the PWM directly/override SaberBase?

What does your blades[] array look like?
Do you have a SimpleBladePtr() or WS281XBladePtr() that refers to the same pin as your LSAnalogWrite() ?

By default ProffieOS does nothing with any of the FET pins, it only activates them if they are mentioned in your blades[] array.

Looks like this:

BladeConfig blades[] = {
{ 0,
DimBlade(10.0, SimpleBladePtr<myLED, NoLED, NoLED, NoLED, bladePowerPin4, -1, -1, -1>()),
CONFIGARRAY(presets)}
};

Yes the blades array refers to the same pin as our LSanalogWrite(). DimBlade has no effect strangely and the pin is still on at full brightness.

Well, if you want to use LSAnalogWrite, then you need to remove the SimpbleBladePtr (or turn it into a “dummy” blade by using all NoLED), otherwise it will be fighting you and call LSAnlogWrite() many times per second.

To test this, you can simply do:

BladeConfig blades[] = {
{ 0,
SimpleBladePtr<NoLED, NoLED, NoLED, NoLED, -1, -1, -1, -1>()),
CONFIGARRAY(presets)}
};

Does your code call LSAnalogWriteSetup()?
If not, you’ll need to add that since SimpleBladePtr() won’t be doing it for you.

It’s odd that dimblade doesn’t work though. Is that your code doing that?
What does myLED look like?
What style are you using?
(These last questions don’t really matter if you get rid of SimpleBladePtr)

This is our config code setup currently:

Preset presets[] = {
  {"Skywalker", "tracks/venus.wav", 
  StyleNormalPtr<CYAN, WHITE, 800, 800>(), "Ignition" }
};

struct myLED {
    static constexpr float MaxAmps = 1.5;
    static constexpr float MaxVolts = 18.0;
    static constexpr float P2Amps= 0.75;
    static constexpr float P2Volts = 9;
    static constexpr float R = 10000;
    static const int Red = 0;
    static const int Green = 0;
    static const int Blue = 255;
};

BladeConfig blades[] = {
 { 0, 
DimBlade(50.0, SimpleBladePtr<myLED, myLED, NoLED, NoLED, bladePowerPin4, bladePowerPin2, -1, -1>()),
 CONFIGARRAY(presets)}
};

I do like how the blade dims upon retraction which is why we kept the SimpleBladePtr. We do call LSanalogWriteSetup() in our code for all the LED pins.

If possible I’d like to get dimblade working as that seems like the best way to get both PWM control and the lighting effects, but I’m confused as to why it’s not. We do call LSanalogWrite in our prop file but it is at a much lower duty cycle which is why I’m confused it seems to be defaulting to the SimpleBladePtr, but at full brightness instead of dimmed.