I really appreciate your help and your time. I’ll let you know how it goes!
One more question in regards to the controlling the cob strip using the LED pins. Can i control when the blade turns on and off? Meaning, the retraction process can take up to 2 - 3 seconds. I want the cob strip to stay lit until i tell it to turn off. I have a motor that controls the blade extension and retraction and i use an encoder to detect how many pulses the motor has made. when it reaches its target pulse count, the motor stops. Currently, with my MOSFET module, once the motor reaches its target pulses, i turn the cob strip off by setting a flag in the loop. Can that be done using the LED pins?
Sounds like you want RetractionDelay:
No, i need to actually be able to turn it on and off. I cant use time, i need to trigger the cob on and off when the target pulses are met and the motor stops . Here’s the code i’m using currently to turn off the MOSFET module when the blade is fully retracted in the hilt.
// Retract blade when saber is turned OFF
if (!motor_running && saberIsActive && pulse_count < target_pulses) {
Serial.println("Saber is OFF: Retracting blade.");
startMotor(false);
}
else if (motor_running && pulse_count >= target_pulses) {
//Serial.println("Blade fully retracted while saber is OFF.");
saberIsActive = false;
stopMotor();
SaberOff(); // Turn off blade lighting
//Only turn off the flicker AFTER the blade is fully retracted
digitalWrite(MOSFET_CONTROL_PIN, LOW);
}
else if (motor_running && pulse_count >= target_pulses - brakeThreshold) {
slowDownMotorPWM(false);
}
There are literally infinite number of ways to do this.
- You can do it with digitalWrite(), that will still work.
- You can do it with LSAnalogSetup() / LSAnlogWrite() (or PWMPin), which will let you specify how bright you want it.
- You can use the new APIs in 8.x that lets you turn blades on/on individually, although it may play sounds you don’t want.
- You can use a small custom style template that lets you set the value, (0-32768) then use that in your style.
Using 3 or 4 gives you access to the ProffieOS style library, which gives you lots of flickering and blinking functions you can use.
Let me know which one sounds best and I can help you with it if you want to.
#4 sounds like the best option as i do plan on upgrading my cob strip to WS2812B individually addressable.
So i need a blade flicker with random intervals around 3-10 millis or something close. I also need control over turning the blade on and off. That’s really it. If you could kindly show me how to toggle the blade on or off using the function i provided in the last post, id appreciate it.
Or maybe a combo? You said i could still use the digitalWrite method, could i use it to set the LED pins to high and low? That way i could use the custom style template to set the flicker then use the digitalWrite to toggle the cob on and off?
If so, please provide an example of where in the code i would set the custom style. At your convenience of course.
I appreciate your time and help.
So what you would need would be something like this:
#ifndef CONFIG_STYLES
class CobF {
CobF() { value_ = 0; }
void run(BladeBase* blade) {}
int getInteger(int led) { return value_; }
void set(int v) { value_ = v; }
private:
static int value_ = 0;
};
#endif
(that goes in your config file.)
Now you can use this in your presets, perhaps like this:
StylePtr<Mix<CobF, Black, White>>()
Or, if you want some flickering, you can replace “White” with something that will flicker, for instance:
StylePtr<Mix<CobF, Black, AudioFlicker<White, Black>>()
In your prop, you can then use these to turn things on/off:
CobF::set(0); // off
CobF::set(32768); // on
CobF::set(16384); // half on/off
Thanks, i’ll work on this and let you know how it goes!
here is how i set up my config file
#define COB_LED_PIN 24 //LED 5 pad
#ifndef CONFIG_STYLES
class CobF {
public:
CobF() { value_ = 0; }
void run(BladeBase* blade) {}
int getInteger(int led) { return value_; }
static void set(int v) { value_ = v; }
private:
static int value_;
};
int CobF::value_ = 0;
#endif
//counter clockwise drive gear reels in the blade
Preset presets[] = {
{ "Kenobi", "",
StylePtr<Mix<CobF, Black, AudioFlicker<White, Black>>>()
}
};
BladeConfig blades[] = {
{ 0,
COB_LED_PIN, SimpleBladePtr<CobF, NoLED, NoLED, NoLED>(), CONFIGARRAY(presets) },
};
But im this getting an error when compiling it
So im not setting the led pin pad correctly. Could you show me the correct way to set up the blade config?
In file included from C:\Users\vicya\Documents\Arduino\ProffieOS\ProffieOS.ino:621:
C:\Users\vicya\Documents\Arduino\ProffieOS\config\proffie_retractable_saber_config.h:101:21: error: invalid conversion from 'int' to 'BladeBase*' [-fpermissive]
101 | #define COB_LED_PIN 4
| ^
| |
| int
C:\Users\vicya\Documents\Arduino\ProffieOS\config\proffie_retractable_saber_config.h:129:2: note: in expansion of macro 'COB_LED_PIN'
129 | COB_LED_PIN, SimpleBladePtr<CobF, NoLED, NoLED, NoLED>(), CONFIGARRAY(presets) },
| ^~~~~~~~~~~
This is not right.
- COB_LED_PIN isn’t a blade pointer, so it cant do by itself in the blades array.
- CobF is not a LED struct, so it can’t go be an argument to SimpleBladePtr.
I think what you want is this:
BladeConfig blades[] = {
{ 0, SimpleBladePtr<CH1LED, NoLED, NoLED, NoLED, COB_LED_PIN>(), CONFIGARRAY(presets) },
};
For more information, read these:
Your presets array looks reasonable, and uses CobF, so once you fix the blades array, it might work.
so i updated to this
BladeConfig blades[] = {
{
0,
SimpleBladePtr<CH1LED, NoLED, NoLED, NoLED, COB_LED_PIN>(),
CONFIGARRAY(presets)
},
};
and my presets is this
Preset presets[] = {
{ "Kenobi", "",
StylePtr<Mix<CobF, Black, AudioFlicker<White, Black>>>()
}
};
Is CH1LED suppose to be defined my me? Or is that an internal mapping.
Im now getting this error
In file included from C:\Users\vicya\Documents\Arduino\ProffieOS\ProffieOS.ino:591:
C:\Users\vicya\Documents\Arduino\ProffieOS\config\proffie_retractable_saber_config.h:130:16: error: cannot convert 'Preset*' to 'BladeBase*' in initialization
130 | CONFIGARRAY(presets)
| ^~~~~~~
| |
| Preset*
I read through the docs but i can’t seem to pinpoint the issue. Let me know if you need my entire config file.
It’s provided by ProffieOS.
Looks like NUM_BLADES might be wrong. (should be 1)
If that’s not the case, then please post the full config.
Yep, number of blades was still set to 2 because i previously had the battery indicator setup. Thanks for the suggestion and all the help! I’ll test it out on my strip tomorrow. I’ll let you know how it goes! But at least it’s compiling now.
So i tested my setup using the LED 5 pad. I Ignited the saber and the bladed turned on and had a really nice flicker effect. i kept it on for a little bit and it worked great, however, when i went to switch off the saber, my 12v 2a step up converter im using blew up and started smoking. I checked to make sure there was no short at the cob or anywhere else. Everything looked fine which leads me to believe that there was some kind of voltage spike. Do these FET pins have flyback protection (voltage spike). My external MOSFET was able to run the blade without issue using that step up converter, but it was a 15a (30a max) 400w pwm switch.
Also, i tested the LED 5 pin to see if it was destroyed and i ohm tested it, when off it had no continuity to gnd and when the saber was on it had continuity but only a very low buzzing sound from the multimeter and the reading fluctuate fast around 312.50 roughly, i assume that’s due to the pwm signal. Does that sound right? Or should that reading be different when the pin is switched on?
Yes. (Unless the manufacturer did an unsupported substitution.)
Might have to do with the frequency. ProffieOS uses 813hz by default, which might put higher load on the power supply.
Instead of testing for continuity, I recommend testing FETs with a small load. A resistor or small LED will work. FETs just act kind of weird without a load, and it might confuse the meter.
I ordered a better step up converter from robot shop. hopefully it was just an issue with the cheap converter i was using. This one has voltage spike protection.
I have a question about the button press. Currently, when i press the button to run the motor, the button can be pressed again while the motor is running which leads to confusion within the program and in some cases it will cause the motor to stop and run in the opposite direction. I need to be able to disable button presses while the motor is running. I have a motor_running
flag that is set to true
when its running. Is there a way to disable button presses while the flag is true
? Is there a function call or something?
The normal way to do things like that is just to put code in Event2 which checks if the variable is true and ignores any or all button presses in that case.
case EVENTID(...whatever button event here...):
if (motor_running) return false;
... Code to start motor here...
Thank you both. I was able to get it working by adding a check here like this
case EVENTID(BUTTON_POWER, EVENT_FIRST_SAVED_CLICK_SHORT, MODE_OFF):
if (motor_running) return false; // Ignore button press if motor is running
As I test my device, im seeing weird behavior when the motor is running while im turning off the saber, the button press no longer triggers the re-ignition of the saber while the motor is running which is great however, on random occasions, i’m not sure if its vibration or what but the saber will turn back on while the motor is running. i currently do not have the proffileboard secured to the housing as im still testing. The device only vibrates a little as the motor runs, it does not move around or twist. I edited the saber_fett263_button.h
but are there any other files i need to edit as well? Is there anywhere else that the saber ignition is called?
These are the area’s i edited within the file by adding motor_running condition:
saber_fett263_button.h
void DoInteractivePreon() {
if (CheckInteractivePreon()) {
SaberBase::DoEffect(EFFECT_INTERACTIVE_PREON, 0);
} else {
if (!motor_running)
{
DoIgnition();
}
}
}
// EVENT_SWING - Swing On gesture control to allow fine tuning of speed needed to ignite
if (menu_ || millis() - saber_off_time_millis_ < MOTION_TIMEOUT) {
if (!motor_running)
{
SaberBase::RequestMotion();
}
if (swinging_ && fusor.swing_speed() < 90) {
swinging_ = false;
}
if (!swinging_ && fusor.swing_speed() > saved_gesture_control.swingonspeed) {
swinging_ = true;
Event(BUTTON_NONE, EVENT_SWING);
}
#ifndef FETT263_MOTION_WAKE_POWER_BUTTON
case EVENTID(BUTTON_POWER, EVENT_PRESSED, MODE_OFF):
if (!motor_running)
{
SaberBase::RequestMotion();
}
saber_off_time_millis_ = millis();
power_pressed_ = true;
power_press_millis_ = millis();
return true;
#endif
if (menu_ || millis() - saber_off_time_millis_ < MOTION_TIMEOUT) {
if (!motor_running)
{
SaberBase::RequestMotion();
}
if (swinging_ && fusor.swing_speed() < 90) {
swinging_ = false;
}
if (!swinging_ && fusor.swing_speed() > saved_gesture_control.swingonspeed) {
swinging_ = true;
Event(BUTTON_NONE, EVENT_SWING);
}
case EVENTID(BUTTON_POWER, EVENT_PRESSED, MODE_OFF):
if (!motor_running)
{
SaberBase::RequestMotion();
}
saber_off_time_millis_ = millis();
power_pressed_ = true;
power_press_millis_ = millis();
return true;
case EVENTID(BUTTON_POWER, EVENT_FIRST_SAVED_CLICK_SHORT, MODE_OFF):
if (motor_running) return false; // Ignore button press if motor is running
if (menu_) {
MenuChoice();
return true;
#ifdef FETT263_MOTION_WAKE_POWER_BUTTON
} else if (!SaberBase::MotionRequested()) {
if (!motor_running)
{
SaberBase::RequestMotion();
}
saber_off_time_millis_ = millis();
if (SFX_boot) {
hybrid_font.PlayPolyphonic(&SFX_boot);
} else {
sound_library_.SayUp();
}
return true;
#endif
} else {
if (!motor_running)
{
DoInteractivePreon();
}
}
return true;
// 2 Button Controls
case EVENTID(BUTTON_AUX, EVENT_PRESSED, MODE_OFF):
if (!motor_running)
{
SaberBase::RequestMotion();
}
saber_off_time_millis_ = millis();
return true;
case EVENTID(BUTTON_POWER, EVENT_LATCH_ON, MODE_OFF):
case EVENTID(BUTTON_AUX, EVENT_LATCH_ON, MODE_OFF):
case EVENTID(BUTTON_AUX2, EVENT_LATCH_ON, MODE_OFF):
case EVENTID(BUTTON_POWER, EVENT_CLICK_SHORT, MODE_OFF):
if (menu_) {
MenuChoice();
return true;
#ifdef FETT263_MOTION_WAKE_POWER_BUTTON
} else if (!SaberBase::MotionRequested()) {
if (!motor_running)
{
SaberBase::RequestMotion();
}
saber_off_time_millis_ = millis();
if (SFX_boot) {
hybrid_font.PlayPolyphonic(&SFX_boot);
} else {
sound_library_.SayUp();
}
return true;
#endif
} else {
if (!motor_running)
{
DoInteractivePreon();
}
}
return true;