Do "held then held" button "mods" confuse ProffieOS?

Could the OS have trouble with similar events such as:
case EVENTID(BUTTON_MODE_SELECT, FIRST_HELD_LONG, MODE_ON | BUTTON_FIRE):
and the inverse
case EVENTID(BUTTON_FIRE, FIRST_HELD_LONG, MODE_ON | BUTTON_MODE_SELECT):
like getting confused or swapped up along the way to the 2nd button reaching a “HELD_LONG”?

What’s happening:
I have another “swapped behavior” issue in my lap where these buttons in this blaster are “working” 100% as far as physical contact closure and wiring, but behaving swapped in operation… sort of. Only when trying to do these combos above.

Normal single clicks, helds, even held and Clash all work fine.
Combos that also work fine are “HOLD one then single Click the other” (either way, both work.)
It seems to just be the HOLD then HOLD that’s problematic.
I don’t have any events that “hold then hold” in my saber prop, so this is the first time I’ve stumbled upon this happening.
I can confirm that entering the combo “mods” button commands in Serial Monitor like mode fire m1 do indeed execute the expected things, just the actual buttons do not.

Longer version with examples:

// holding MODE then holding FIRE is supposed to toggle ON/OFF. But instead it does destruct
      case EVENTID(BUTTON_FIRE, EVENT_FIRST_HELD_LONG, MODE_OFF | BUTTON_MODE_SELECT):
        if (!hybrid_font.PlayPolyphonic(&SFX_out)) {
          beeper.Beep(0.1, 1300);
        }
        On();
        return true;
      case EVENTID(BUTTON_FIRE, EVENT_FIRST_HELD_LONG, MODE_ON | BUTTON_MODE_SELECT):
        if (!hybrid_font.PlayPolyphonic(&SFX_in)) {
          beeper.Beep(0.1, 300);
        }
        Off();
        return true;

// holding FIRE then holding MODE is suppopsed to do destruct, but is doing ON/OFF
      case EVENTID(BUTTON_MODE_SELECT, EVENT_FIRST_HELD_LONG, MODE_ON | BUTTON_FIRE):
        selfDestruct();
        return true;

This log is starting from “On” state, just trying to power Off. I get destruct instead (which is supposed to be the inverse, Hold FIRE , then Hold MODE)

23:37:26.811 -> EVENT: MODE-Pressed#1 ON millis=49275
23:37:26.811 -> EVENT: MODE-Pressed ON millis=49275
23:37:27.103 -> EVENT: MODE-Held#1 ON millis=49576
23:37:27.103 -> EVENT: MODE-Held ON millis=49576
23:37:27.179 -> EVENT: FIRE-Pressed#1 mods MODE ON millis=49646
23:37:27.179 -> EVENT: FIRE-Pressed mods MODE ON millis=49646
23:37:27.468 -> EVENT: FIRE-Held#1 mods FIREMODE ON millis=49947
23:37:27.468 -> EVENT: FIRE-Held mods FIREMODE ON millis=49947
23:37:27.610 -> EVENT: MODE-HeldMedium#1 mods FIREMODE ON millis=50076
23:37:27.610 -> EVENT: MODE-HeldMedium mods FIREMODE ON millis=50076
23:37:27.978 -> EVENT: FIRE-HeldMedium#1 mods FIREMODE ON millis=50447
23:37:27.978 -> EVENT: FIRE-HeldMedium mods FIREMODE ON millis=50447
23:37:28.828 -> EVENT: MODE-HeldLong#1 mods FIREMODE ON millis=51276
23:37:28.828 -> unit = 0 vol = 0.50, Playing commonB/destruct/0001.wav
23:37:28.828 -> channels: 1 rate: 44100 bits: 16
23:37:30.370 -> EVENT: FIRE-Released#1 ON millis=52820
23:37:30.370 -> EVENT: FIRE-Released ON millis=52820
23:37:30.370 -> EVENT: MODE-Released#1 ON millis=52841
23:37:30.370 -> EVENT: MODE-Released ON millis=52841
23:37:37.555 -> Battery voltage: 4.20
23:37:38.830 -> unit = 2 vol = 0.50, Playing commonB/boom.wav
23:37:38.830 -> channels: 1 rate: 44100 bits: 16
23:37:38.830 -> No sounds found: blaster
23:37:38.830 -> unit = 0 vol = 0.04, No sounds found: hum
23:37:38.830 -> Audio underflows: 1
23:37:42.007 -> Amplifier off.

Ok, well now the blaster is Off all right, but it’s blown to smithereens.
Anyway, from that state, doing the same exact combo does actually turn it on:

23:37:46.168 -> EVENT: MODE-Pressed#1 millis=68618
23:37:46.168 -> EVENT: MODE-Pressed millis=68618
23:37:46.383 -> EVENT: FIRE-Pressed#1 mods MODE millis=68857
23:37:46.383 -> EVENT: FIRE-Pressed mods MODE millis=68857
23:37:46.458 -> EVENT: MODE-Held#1 mods FIREMODE millis=68919
23:37:46.458 -> EVENT: MODE-Held mods FIREMODE millis=68919
23:37:46.713 -> EVENT: FIRE-Held#1 mods FIREMODE millis=69158
23:37:46.713 -> EVENT: FIRE-Held mods FIREMODE millis=69158
23:37:46.957 -> EVENT: MODE-HeldMedium#1 mods FIREMODE millis=69419
23:37:46.957 -> EVENT: MODE-HeldMedium mods FIREMODE millis=69419
23:37:47.215 -> EVENT: FIRE-HeldMedium#1 mods FIREMODE millis=69658
23:37:47.215 -> EVENT: FIRE-HeldMedium mods FIREMODE millis=69658
23:37:48.150 -> EVENT: MODE-HeldLong#1 mods FIREMODE millis=70619
23:37:48.150 -> EVENT: MODE-HeldLong mods FIREMODE millis=70619
23:37:48.408 -> EVENT: FIRE-HeldLong#1 mods FIREMODE millis=70858
23:37:48.408 -> unit = 0 vol = 0.50, Playing commonB/out.wav
23:37:48.408 -> channels: 1 rate: 44100 bits: 16
23:37:48.408 -> Ignition.
23:37:48.408 -> No sounds found: hum
23:37:48.408 -> unit = 1 vol = 0.00, MAKING out killable.
23:37:48.408 -> unit = 2 vol = 0.50, Playing commonB/out.wav
23:37:48.408 -> No sounds found: hum
23:37:48.442 -> channels: 1 rate: 44100 bits: 16
23:37:48.442 -> HumDelay: 200
23:37:48.811 -> EVENT: FIRE-Released#1 ON millis=71285
23:37:48.811 -> EVENT: FIRE-Released ON millis=71285
23:37:48.849 -> EVENT: MODE-Released#1 ON millis=71322
23:37:48.849 -> EVENT: MODE-Released ON millis=71322
23:37:49.350 -> Amplifier off.

side note for later - why are out and in.wavs playing twice?

Ok now it’s ON, so to confirm. I repeated: Hold MODE, then Hold FIRE. It did Destruct again.

So now it’s Off again, so I decided from the Off state to try the opposite (the actual destruct combo, Hold FIRE, then Hold MODE) and lo and behold the blaster powered on?!


23:44:38.856 -> EVENT: FIRE-Pressed#1 millis=481292
23:44:38.856 -> EVENT: FIRE-Pressed millis=481292
23:44:39.144 -> EVENT: MODE-Pressed#1 mods FIRE millis=481588
23:44:39.144 -> EVENT: MODE-Pressed mods FIRE millis=481588
23:44:39.144 -> EVENT: FIRE-Held#1 mods FIREMODE millis=481593
23:44:39.144 -> EVENT: FIRE-Held mods FIREMODE millis=481593
23:44:39.426 -> EVENT: MODE-Held#1 mods FIREMODE millis=481889
23:44:39.426 -> EVENT: MODE-Held mods FIREMODE millis=481889
23:44:39.639 -> EVENT: FIRE-HeldMedium#1 mods FIREMODE millis=482093
23:44:39.639 -> EVENT: FIRE-HeldMedium mods FIREMODE millis=482093
23:44:39.932 -> EVENT: MODE-HeldMedium#1 mods FIREMODE millis=482389
23:44:39.932 -> EVENT: MODE-HeldMedium mods FIREMODE millis=482389
23:44:40.850 -> EVENT: FIRE-HeldLong#1 mods FIREMODE millis=483293
23:44:40.850 -> unit = 0 vol = 0.50, Playing commonB/out.wav
23:44:40.850 -> channels: 1 rate: 44100 bits: 16
23:44:40.850 -> Ignition.
23:44:40.850 -> No sounds found: hum
23:44:40.850 -> unit = 1 vol = 0.00, unit = 2 vol = 0.50, Playing commonB/out.wav
23:44:40.850 -> No sounds found: hum
23:44:40.887 -> channels: 1 rate: 44100 bits: 16
23:44:40.887 -> HumDelay: 200
23:44:41.286 -> EVENT: MODE-Released#1 ON millis=483754
23:44:41.286 -> EVENT: MODE-Released ON millis=483754
23:44:41.286 -> EVENT: FIRE-Released#1 ON millis=483757
23:44:41.324 -> EVENT: FIRE-Released ON millis=483757
23:44:41.794 -> Amplifier off.

Last test was to intentionally again do the destruct combo now that it’s On and guess what. It powered Off.

Summary: HELD and HELD mod button combos seem to get swapped. Is it me?

This seems perfectly natural to me.
Let’s say you have two buttons A and B.
Hold A, click B generates an EVENT(A, CLICK, MODE_OFF | B) event.
Hold A, hold B will generate EVENT(A, HELD, MODE_OFF | B) event, however since you have to press B first, it will generate an EVENT(B, HELD, MODE_OFF | A) before that, which is what you’re experiencing here I think.

Now, it may be possible to change this by checking the “current_modifiers” at the time the button is pressed, rather than when the event is generated, as it is done now. I don’t think there would be any weird side effects from doing that…

Although doing that wouldn’t remove the first event, it would just become EVENT(B, HELD, MODE_OFF); which might be worse…

I’m not sure that makes anything clearer really.
Are you saying itss expected behavior to be the inverse of the way everything else behaves?
And if so, do we code around it (swapping EVENTIDs to the inverse of “typical” for calls to functions) or do you have an idea to try but might break something in the process? (the latter is always the case I know)

Also (maybe another thread for this but seems related enough)>
Are buttons for Blasters handeld “less” when Saberbase is ON as far as “short click” and “saved clicks” are concerned?

When OFF, FIRE does
00:42:01.306 → EVENT: FIRE-Pressed#1 millis=64191
00:42:01.306 → EVENT: FIRE-Pressed millis=64191
00:42:01.521 → EVENT: FIRE-Released#1 millis=64382
00:42:01.521 → EVENT: FIRE-Released millis=64382
00:42:01.521 → EVENT: FIRE-Shortclick#1 millis=64382
00:42:01.521 → EVENT: FIRE-Shortclick millis=64382
00:42:01.815 → EVENT: FIRE-SavedShortclick#1 millis=64692
00:42:01.815 → EVENT: FIRE-SavedShortclick millis=64692

but when ON, as FIRE only does
00:18:31.170 → EVENT: FIRE-Pressed#1 ON millis=14378
00:18:31.170 → EVENT: FIRE-Pressed ON millis=14378
00:18:31.280 → EVENT: FIRE-Released#1 ON millis=14516
00:18:31.280 → EVENT: FIRE-Released ON millis=14516

HELD events are timed.
If you press A, then B, the HELD event for A will be fired first.
Not sure if changing that is a good idea or not, even if it leads to surprising behavior.

It’s because EVENT(BUTTON_FIRE, EVENT_PRESSED, MODE_ON) returns true, so the rest of the code counts the events as already handled and does not trigger any more events.

Ok so that aligns with what I was thinking is happening…I think.
So like, FIRE gets pressed and held - the timer starts running for it’s held condition.
MEanwhile, MODE is also pressed and held.
So, but the time the timer gets to the FIRE button’s LONG timeout, because MODE is held at that time, it triggers “BUTTON_FIRE, EVENT_FIRST_HELD_LONG, MODE_OFF | BUTTON_MODE_SELECT” because that’s what it seems to be at that juncture.

I guess the “solution” is not to try to use double HOLDs in both directions for different things.

Ok next weird thing:

Makes sense, however I changed the
case EVENTID( BUTTON_FIRE, EVENT_PRESSED, MODE ON) in the prop to be
case EVENTID(BUTTON_FIRE, EVENT_FIRST_CLICK_SHORT, MODE_ON) instead, and it’s still doing just

01:17:11.990 -> EVENT: FIRE-Pressed#1 ON millis=500480
01:17:11.990 -> EVENT: FIRE-Pressed ON millis=500480
01:17:12.025 -> EVENT: FIRE-Released#1 ON millis=500505
01:17:12.025 -> EVENT: FIRE-Released ON millis=500505

```
 I'm overriding Event2, so it can't be coming from the parent class. 
hmmm.

You probably have to change EVENT_RELEASED too.

wow this is killing me. should be straight forward now i have nothiing. Something still affecting it and no shortclicks when ON
I’m just going to have to choose different events or come back to this. Unless the next issue is related (likely).

That said, is being in a mode any different for buttons?
I have a function being triggered by every button event (pressed, held, released) and even when the other button is used!?
I have this in mode_Event2:
case EVENTID(BUTTON_MODE_SELECT, EVENT_FIRST_HELD_MEDIUM, 0):.
Yet even clicking FIRE the code inside runs on Pressed.
If i keep holding FIRE, it triggers again with the Held event.
When I release the button, it triggers on Release as well.
It’s not even that button! No idea.
I think I’m a mess tonight. Was going so well, then weird button stuff.

This code:


  void QuickMinVolume() {
PVLOG_NORMAL << "** ********* QuickMinVolume called - calling SayChoreographyBegin\n";
    dynamic_mixer.set_volume(min_volume_);
    PVLOG_NORMAL << "** Minimum Volume\n";
    // mode::getSL<SPEC>()->SayMinimumVolume();
    mode::getSL<SPEC>()->SayChoreographyBegin();
  }

  bool mode_Event2(enum BUTTON button, EVENT event, uint32_t modifiers) override {
    switch (EVENTID(button, event, 0)) {
      case EVENTID(BUTTON_FIRE, EVENT_FIRST_HELD_MEDIUM, 0):  // fire m1
        QuickMaxVolume();
        return true;

      case EVENTID(BUTTON_MODE_SELECT, EVENT_FIRST_HELD_MEDIUM, 0):  // mode m1
        QuickMinVolume();
        return true;
      case EVENTID(BUTTON_FIRE, EVENT_FIRST_SAVED_CLICK_SHORT, 0):  // fire s1
        select();
        return true;

      case EVENTID(BUTTON_MODE_SELECT, EVENT_FIRST_SAVED_CLICK_SHORT, 0):  // mode s1
        exit();
        return true;
    }
  }

but yet I get this:

02:15:50.337 -> EVENT: FIRE-Pressed#1 millis=382871
02:15:50.337 -> ** ********* QuickMinVolume called - calling SayChoreographyBegin
02:15:50.337 -> ** Minimum Volume
02:15:50.337 -> Playing chreobgn.wav, channels: 1 rate: 44100 bits: 16
02:15:50.511 -> EVENT: FIRE-Released#1 millis=383027
02:15:50.511 -> ** ********* QuickMinVolume called - calling SayChoreographyBegin
02:15:50.511 -> ** Minimum Volume
02:15:51.602 -> Playing chreobgn.wav, channels: 1 rate: 44100 bits: 16
02:15:52.840 -> Amplifier off.
02:15:53.832 -> Unmounting SD Card.
02:15:57.103 -> EVENT: FIRE-Pressed#1 millis=389626
02:15:57.103 -> ** ********* QuickMinVolume called - calling SayChoreographyBegin
02:15:57.103 -> ** Minimum Volume
02:15:57.103 -> Playing chreobgn.wav, channels: 1 rate: 44100 bits: 16
02:15:57.392 -> EVENT: FIRE-Held#1 millis=389927
02:15:57.392 -> ** ********* QuickMinVolume called - calling SayChoreographyBegin
02:15:57.392 -> ** Minimum Volume
02:15:58.361 -> Playing chreobgn.wav, channels: 1 rate: 44100 bits: 16
02:15:59.591 -> Amplifier off.
02:16:00.019 -> EVENT: FIRE-Released#1 millis=392541
02:16:00.019 -> ** ********* QuickMinVolume called - calling SayChoreographyBegin
02:16:00.019 -> ** Minimum Volume
02:16:00.019 -> Playing chreobgn.wav, channels: 1 rate: 44100 bits: 16
02:16:01.299 -> Amplifier off.
02:16:02.251 -> Unmounting SD Card.
02:16:07.513 -> Battery voltage: 4.26
02:16:07.571 -> EVENT: MODE-Pressed#1 millis=400077
02:16:07.571 -> ** ********* QuickMinVolume called - calling SayChoreographyBegin
02:16:07.571 -> ** Minimum Volume
02:16:07.571 -> Playing chreobgn.wav, channels: 1 rate: 44100 bits: 16
02:16:07.846 -> EVENT: MODE-Held#1 millis=400378
02:16:07.846 -> ** ********* QuickMinVolume called - calling SayChoreographyBegin
02:16:07.846 -> ** Minimum Volume
02:16:08.805 -> Playing chreobgn.wav, channels: 1 rate: 44100 bits: 16
02:16:10.040 -> Amplifier off.
02:16:10.335 -> EVENT: MODE-Released#1 millis=402844
02:16:10.335 -> ** ********* QuickMinVolume called - calling SayChoreographyBegin
02:16:10.335 -> ** Minimum Volume
02:16:10.335 -> Playing chreobgn.wav, channels: 1 rate: 44100 bits: 16
02:16:11.582 -> Amplifier off.

Any idea why FIRE would have anything to do with anything?
(I changed the saying temporarily because I got real tired of “Minimum Volume” over and over)

Maybe it’s selectCancelMode

Sorry sorry . It was SelectCancelMode.
I didn’t go back to it after these custom button events and it was mayhem.
Had to just add return SPEC::SelectCancelMode::mode_Event2(button, event, modifiers);
ok progress. thanks. sorry to spaz.

No worries, glad you figured it out.
(Not sure if there was something I should still answer, let me know if there is…)