We’ve built a mechanism for an extendable lightsaber that operates reliably.
Currently, we’re using a separate Arduino Nano to send signals that mimic the actions of the control buttons to the Proffie board to make it work.
We’d like to achieve this using only the Proffie board, so we’ve decided to ask for your advice.
Currently, we are using two photoreflector sensors to detect the extension and retraction limits of the blade,
as well as two signal lines to control a separate small motor driver
that manages the blade’s retraction and extension.
In other words, we need four signal lines.
Specifically, when the saber is turned on, I need to monitor the extension-side sensor while sending a signal to the motor driver to rotate in the extension direction.
When the saber is turned off, I need to monitor the retraction-side sensor while sending a signal to the motor driver to rotate in the retraction direction.
Which files should I modify, and what kind of code should I add?
So on a V3 proffieboard, there are lots of pins available that can be used:
Free 1, Free 2, Free 3
Data 2, Data 3, Data 4
Button 1, Button 2, Button 3
Rx, Tx
The three Free pins are meant for these sort of things, and there is a timer available if you need some sort of PWM functionality, so I would recommend using those. Then add Data 4 as the fourth wire. (Or one of the other ones if that makes things easier for some reason.)
Coding-wise, there are a lot of ways to do this, but because this is relatively simple and doesn’t seem to require a lot of configuration, we can just stick with the simplest option, which is to put a piece of code directly in your configuration file for this.
Basically, inside CONFIG_PRESET, you would put something like this:
class BladeExtender : public Looper {
public:
const int extendSensorPin = blade4Pin;
const int retractSensorPin = blade5Pin; // Free1
const int directionPin = blade5Pin; // Free2
const int motorEnablePin = blade6Pin // Free3
const char* name() override { return "BladeExtender"; }
void Setup() override {
// Setup code, like pinMode() calls go here.
pinMode(extendSensorPin, INPUT);
pinMode(retractSensorPin, INPUT);
pinMode(directionPin, OUTPUT);
pinMode(motorEnablePin, OUTPUT);
}
void Loop() override {
// This gets called over and over again, just like arduino.
// You can do anything here, but do not use delay() calls as that will
// slow down everything else.
if (Saberbase::IsOn()) {
digitalWrite(directionPin, 1);
digitailWrite(motorEnablePin, !digitalRead(extendSensorPin));
} else {
digitalWrite(directionPin, 0);
digitailWrite(motorEnablePin, !digitalRead(retractSensorPin));
}
}
private:
// Any variables you need go here.
};
// None of the above does anything until you instantiate the class like this:
BladeExtender blade_extender;
This example is untested, and may need some tweaking to work, but at least it should show you one way of doing what you want to do.
This doesn’t work well in ProffieOS.
You can’t just run a while loop, because then blade animations stop, no new sounds are started, motion events stop, etc.
Luckly, you don’t need a while loop to do what you want. Instead you use the Loop() function, which gets called very often (usually thousands of times per second) to check what the current state is, make changes, and then return. It’s really very similar to your while loop.
The code I posted is written this way. When Loop() is called, is checks if the saber is ignited or not. (SaberBase::IsOn() returns true immedately when ignition begins, and returns false as soon as retraction begins.) When the saber is ignited, it checks the sensor and runs the motor in one direction until the sensor is triggered. Once the sensor is triggered, it keeps checking it, but it doesn’t do anything. (Assuming the sensor stays triggered.) if the saber is off (meaning that the user has pressed the “retract” button, whatever that is.) then it runs the motor the other way, if, and only if, the retraction sensor hasn’t triggered yet.
Doesn’t this do pretty much exactly what you need?
(Without the while loop.)
Genereally speaking, what you need is state machine. There is lots of ways to write a state machine, and I can provide an example tomorrow. (Getting late here)
Basically, it comes down to set a variable to the current time, then check how many millis (or micros) has passed, repeatedly, and when enough time has passed, you go to the next state.
What kind of signals? Do you need to send a PWM signal at a particular frequency to make the motor go?
I want to set the global variables bool extending_ and bool retracting_ to true within functions that are called exactly once each when the blade extends and retracts.
It’s just a matter of personal preference, but even after the blade has fully extended or retracted, I was concerned about the strain of constantly monitoring the sensor, so I personally wanted to avoid it.
I’m going to try a method where the power for the reflect sensor’s LED is drawn from a separate battery used to run the motor, and the sensor itself is powered by 3.3V from the Proffie.
Yes, call EnableBooster(); from your code.
Doing this will make sure the 5v booster is on, and it will keep it on for a few seconds. Just keep calling EnableBooster(); in loop() as long as retracting_ or extending_ is true. There is no function for turning the booster off, it just turns off automatically when no code has called EnableBooster() in a while.
I’ve been trying this for dozens of hours, but the sensor (LBR-127HLD) isn’t working properly.
The sensor is powered from the 5V pin, with a 220-ohm resistor on the LED side and a 1-kOhm resistor on the sensor side.
When I run the code, it only returns zeros. Previously, when I ran the same setup on an Arduino, the reading was in the 900s when there was a reflective object present, and it exceeded 1,000 when the object was removed.
It’s a great idea, but the way our saber works is different from theirs.
Have you seen the video of our saber?
Our saber has been running stably for months now, but our goal is to remove the Arduino and run it using only Proffie, so we’d like to ask for your advice.
The current issue is that the reflect sensor isn’t working properly.