Extendable and Retractable Spinning Lightsaber Proffie Control

Hi again, thank you so much for your help with the previous retractable lightsaber! I am working on the next version of the lightsaber and I had a few questions. How the new lightsaber works is:

1 linear micro servo serves as a mechanical clutch, upon activation it releases the blade (blade extends with magician’s cane propulsion)
2 motors reel in 2 LED strip spools to retract the blade
1 additional motor rotates the magician’s cane while retracting for a smoother retraction
The entire inner hilt chassis is rotated with an external motor (not controlled with Proffie)

So the components we need to control with Proffie are:
2 non-addressable LED strips
2 N20 retraction motors
1 cane rotation motor
1 linear micro servo motor

For turning on the saber, I was thinking that once the Proffie senses that it is spinning, it activates. And to turn off the saber, I was thinking that once the Proffie senses that it is spinning slower, it retracts and turns off. (I can externally control the rotation speed)

So this is the order of operations that I’m thinking:
Detect when hilt chassis is spinning = turn on saber, shift linear micro servo motor right 5mm, then after 500 milliseconds shift micro linear servo motor back left 5mm while turning on both retraction motors with PWM (SABER ON STATE)

Detect when hilt chassis spinning is slowed = turn on cane rotation motor, full PWM power to both retraction motors, after 2000 milliseconds turn off saber, current sense when stall is reached and stop retraction, OR stop retraction after _____ milliseconds (SABER OFF STATE)

A few questions I had were:

Would the above order of operations work with Proffie?

When the saber is on and spinning, I need to have the retraction motors powered a little bit, but not so much that it retracts the blade. This is because if there is no retracting force when the blade is spinning, the LED strips will look like a globe instead of a tight line. Can I do this with PWM by having the motors linked to LED pins?

Are the LED pins current sensing? To stop the retraction, is it possible to detect when it reaches the stall current of the motor and then shut it off?

Would the wait ____ milliseconds be a problem with Proffie? If I’m understanding correctly, Proffie can’t wait for things exactly, it has to do things in small quick increments.

To turn off swing, clash, and smoothswing sounds, is it just changing the CLASH_THRESHHOLD_G and others to a really high value?

I think a V3 Proffieboard can do do all of this. You would need to do some coding, essentially building your own prop file, but it doesn’t sound all that difficult to do.

Yes.
You would need to write your own prop file which checks the rotation speed and turns on and off accordingly though.

I can’t say how well this will work, but the LED* pads have very accurate PWM outputs, so if a small PWM value is all you need, then the proffieboard can deliver that.

No. They are not current sensing. You could use some resistors and analogRead() to do this, but I suspect that something that detects that the rotation has stopped would be more accurate.

It adds a small amount of code complexity, but it’s not a problem.
Basically you have to set a variable to the current time and then check it repeatedly to see if enough time has passed.

clash can be turned off by overriding a function in the prop.
turning off swings can be done in the font configuration.
Note that rotation around it’s axis does not count as “swing” in ProffieOS, so I think smoothswing should still work, even if the proffieboard is rotating around is axis.

1 Like

Thanks so much! Will start the code. Another question, is there a way to set a current limit for each LED pad? I saw a define line in the config file and was wondering what the possible range of current limiting is for the LED pads. Or is the define line just there for other calculations, not current limiting?

No, there is not.
ProffieOS has some code that can prevent overheating by estimating the current through a LED and cutting back if would be too high, but it’s all based on calculation, there is no sensing or feedback going on. So if your LED doesn’t behave like the calculations predict, then it doesn’t work.

1 Like

Oh ok, got it. Thanks!

proffie-config (3).txt (1.5 KB)
spinning-lightsaber-prop (3).txt (6.6 KB)

So this is what I have so far, I’m a little confused as to what argument to pass to CONFIGARRAY?

This config file won’t work properly, because it doesn’t have sections, like CONFIG_TOP, CONFIG_PROP, etc. (See here for more details: ProffieOS Documentation: The Config File) You’re confused about what to put in the CONFIGARRAY because you put your preset array there, and you don’t seem to have one yet. The link above can also show you how to write a preset array.

This part:

PROP_TYPE prop;

Is already in ProffiOS.ino, and should generally not go in your config file.

1 Like

Okay got it, thanks! I’ve updated the config file with the proper sections and a preset array. For the blades array, is it correct that I’m basically declaring 6 blades (2 LED strips, 2 retraction motors, 1 cane rotation motor, and 1 linear servo), 5 of which using SimpleBladePtr and the servo using ServoBladePtr?

And for the motors, I’m using a struct to declare them, but what “color” should they be? I guess in general, I’m confused as to why the motors need to be declared as blades and not just instantiated in the prop file and controlled with analogwrite().

Yes, that seems correct.

Usually you only include one prop.

You can absolutely do that.
Putting things in blades have some advantages:

  • doesn’t require programming
  • leverages style system for control
  • individual settings for each preset

However, if you don’t need or want that, you can just use analogWrite (or PWMPin) to drive your motor(s).

1 Like

Oh I see! So if I just wanted to use analogWrite() to drive the motors, I would only need the 2 LED strips declared as blades in the config, and the rest of the motors I can drive through the prop file?

Also for the pin definitions in the prop file, I should use the bladePowerPins instead of the bladePins right?

And can I check that the way I implemented setting a variable to the current time and then checking it repeatedly to see if enough time has passed is correct in the prop file?

Sorry for all the questions :sob:

Bumping these questions in case it got lost in the forum - apologies if I am being overly cautious about the code but it is definitely not my area of expertise.

Sure. This is true for anything, you can drive it “the proffieOS way”, or you can drive it from some code you write yourself, either works.

Uhm, salty or sweet?
I mean, you use bladePowerPins for the LED* pads and bladePins for data pads.
If you’re driving a motor, you probably want the power pins.

This would be a lot easier if you pointed out exactly what stuff you’re talking about.
I’m going to assume you’re talking about the servo_return_time_ which looks mostly right, but needs some touchup to make it work at the time when millis() flips around.

1 Like

Got it, thanks for the reply! Sorry for being unclear about the code section.
I Just realized that the normal Arduino servo library isn’t compatible with the Proffieboard since the Proffie uses the STM32L4 instead of the STM32F4. If I use ServoBladePtr instead to control the servo, what function do I need to use to change between the white color outputs of the servo “blade” in the prop file? While I get that the RGB output would map to the servo positions, I’m confused on how to call and change that position in the prop file. Would it be LSanalogWrite(ServoPin, 0-255 value)?

Driving servos, three ways:

  1. use analogWriteFrequency to set up the frequency, then use analogWrite to drive it. This is simple and very much the same as any other arduino project. However, analogWrite has a bug which resets the waveform every time you call it, so if you call it too often the waveform will be messed up and it won’t work properly. Caveat Emptor.
  2. Use LSanalogWrite, which is very similar, but is a part of ProffieOS. You’ll need to do a setup call, like this: LSanalogWriteSetup(ServoPin, PWM_USECASE::SERVO); this will set the cycle time to 50 Hz, and will print out a warning if it cannot do that. After that, you can use LSanalogWrite(ServoPin, 0-32768) to set the duty cycle. Note that servoes does not usually use the full range, so you may need to calibrate the range you use. Maybe 2k to 30k or so…
  3. Use blades. In this case you put ServoBladePtr<ServoPin>() in your blades[] array, and you use styles to control the servo. This means that your prop doesn’t get directly involved with controlling the servo, instead it sends signals like EVENT_CLASH, “Turn On”, “Lockup on”, “lockup off”, etc. and the styles react to these signals to decide what to do. It is possible to write styles that can be directly controlled by code (example here) but styles are really meant to give end users controls over how things look and work, without programming. If you want programmatic control, you probably don’t want ServoBladePtr. If you do use ServoBladePtr, you should be using “White” as a way to turn the servo one way, and “Black” to turn it the other, again, you might not want to use the full range.

In your case, I would probably recommend (2).

1 Like

Ah got it, thank you so much!! Will calibrate and test this weekend!

Am using LSanalogWriteSetup and LSanalogWrite, but I’m getting very jittery responses from the servo motor, and it seems like no matter what value I put in LSanalogWrite, I can’t set a position that’s not to the extreme right or left. Have also tested with other servos I had lying around, and am facing a similar jittery problem. I tested the servos independently with a servo checker, and the servos themselves work fine. From the servo documentation, it’s expecting a 1000 - 2000 microsecond pulse, but I’m not sure how exactly that maps to the PWM value that LSanalogWrite sends. Is there something I’m missing here?

Hmm, for some reason I thought servos used a larger range of values.

Try using these:

typedef Rgb16<1638,1638,1638> ServoLeft;
typedef Rgb16<3277,3277,3277> ServoRight;

If they work well I can add them to ProffieOS to make it easier to use servos.
Alternatively, I can modify ServoPtr<> to automatically limit the range.

EDIT: Brainfart, you’re just using LSanalogWrite, but the numbers should still be right: 1638 to 3277…

Tried the new values with LSanalogWrite but still running into the same issue. Trying to figure out why it isn’t working. After looking more into LSanalogWriteSetup and LSanalogWrite, is it possible the timer values and/or frequency is not being passed correctly?

Also noticed that pwm_pin.h has an include for #include <stm32l4_timer.h>, but I don’t think the stm32l4_timer.h file exists?

I don’t suppose you have a logic analyzer?
Even something cheap for $20 should be able to analyze this.

Sure. Lots of things could go wrong.

It exists:

1 Like

Oh I had not seen this! I noticed there’s also a Servo library in here, is there any reason using that wouldn’t work?

Will also try and find a logic analyzer.