PanelDu debouncing ideas
-
I have a clone PanelDu 7
connected to a Duet2 wifi
running RRF 3.5I'm having occasions where it seems like I'm getting multiple instances of a macro running on a single intended touch of the screen. It's like the touch property is not getting de-bounced. I've only noticed on macros I've written but I haven't tried to test other buttons.
I have a couple of questions.
-
Is there any user control of de-bouncing that happens with PanelDu touches? I assume PanelDu uses sw de-bouncing, not HW.
-
Are there any recommendations for de-bouncing in macro launches? I've been thinking I might test and set a global variable at the beginning of the macro (I'd create it at machine startup). Something like
if global.this_macro_already_running M99 set global.this_macro_already_running = true ; rest of macro
Then as the last command I'd set the value to false
set global.this_macro_already_running = false
What I don't understand is how multiple macros are queued and started in RRF. Is it possible that a second instance of the same macro initiated from PanelDu would either start before I get the global set from the first instance? And is it possible the second instance could start before the last command resets the variable in the object model? Should I insert a short pause (say 200msec) after the last command?
Or maybe there are other better ways to handle this?
-
-
@mikeabuilder bouncing is not normally a problem with PanelDue so perhaps something is wrong with the touch membrane. Maybe your enclosure is pressing against it enough to increase its sensitivity but it enough to cause a permanent trigger.
BTW the most precise way to touch the PanelDue buttons is to use the tip of your fingernail, not the pad of your finger.
The buttons auto-repeat if you maintain the pressure.
-
@dc42 - thanks for the info. Leaning on the button is certainly a possibility here.
I was curious about how fast a macro could repeat so I did a quick test with a macro that appends state.upTime to a file, then kept my finger on the touch screen button. I got 10 entries per second, so I'll assume the touch does a 100msec debounce - or that's the round trip time to read and execute the macro.
Then I wrote a macro with my logic above and again held down the macro button. I proved to myself that the slow-finger would end up with the macro queued multiple times, not run simultaneously. Nothing surprising to you, but I'm happy to prove it to myself.
To avoid my problem of the slow-finger, I now have a global variable holding state.upTime that I set when the macro ends. At the start of the macro, I test whether the current upTime is "long enough" after the saved upTime (I picked 5 seconds for my case), and only proceed with the rest of the macro if it's been long enough.
-
@dc42 - Following up on this issue. I've implemented trace logging through all my macros and yesterday I had another incidence of the same issue that started me looking at debouncing on PanelDu. The symptom is that I get this Error in my event log:
2025-04-29 10:25:15 [warn] Error: Push(): stack overflow on AuxI still suspect multiple starts on one attempted PanelDu touch (fingernail only), but there are a couple of odd things I'm hoping to understand.
The macro called from the PanelDu touch is 0:/macros/Load or Unload Filament.g and I post a message via M118 at the beginning of the macro. Then the macro asks the user to select whether to Load, Unload, or Cancel, using
M291 S4 T0 P"FILAMENT - Load, Unload, or Cancel" K{"Load", "Unload", "Cancel"}Here is the event log just before the error. You can see that the macro is starting multiple times and the M291 is being logged each time. After these n=messages, the M292 acks are logged. If the user replies to the M291 with "unload", then another macro ( 0:/macros/load_unload_filaments/unload_current_filament.g) is called. Thar macro has a start message then posts a message with the current tool and filament. Then my stack overflow happens.
2025-04-29 10:24:47 [info] starting 0:/macros/Load or Unload Flament.g 2025-04-29 10:24:47 [info] M291: - [no title] - FILAMENT - Load, Unload, or Cancel 2025-04-29 10:24:49 [info] starting 0:/macros/Load or Unload Flament.g 2025-04-29 10:24:49 [info] M291: - [no title] - FILAMENT - Load, Unload, or Cancel 2025-04-29 10:24:49 [info] starting 0:/macros/Load or Unload Flament.g 2025-04-29 10:24:49 [info] M291: - [no title] - FILAMENT - Load, Unload, or Cancel 2025-04-29 10:24:50 [info] starting 0:/macros/Load or Unload Flament.g 2025-04-29 10:24:50 [info] M291: - [no title] - FILAMENT - Load, Unload, or Cancel 2025-04-29 10:24:51 [info] starting 0:/macros/Load or Unload Flament.g 2025-04-29 10:24:51 [info] M291: - [no title] - FILAMENT - Load, Unload, or Cancel 2025-04-29 10:24:53 [info] M292: cancelled=false shouldAbort=true 2025-04-29 10:25:00 [info] M292: cancelled=false shouldAbort=true 2025-04-29 10:25:03 [info] M292: cancelled=false shouldAbort=true 2025-04-29 10:25:10 [info] M292: cancelled=false shouldAbort=true 2025-04-29 10:25:15 [info] M292: cancelled=false shouldAbort=true 2025-04-29 10:25:15 [info] starting 0:/macros/load_unload_filaments/unload_current_filament.g 2025-04-29 10:25:15 [info] M291: - [no title] - Current Tool Number: 1 Current filament: PLA 2025-04-29 10:25:15 [warn] Error: Push(): stack overflow on Aux 2025-04-29 10:25:20 [info] M292: cancelled=false shouldAbort=true
One question I had is "which of the M291's in the 5 macro starts was responded to by the user?" The T0 parameter on the M291 means it will not time out, but I do not think this makes it blocking. So each of the first 4 M291 messages is lost. Are those macro starts left at a paused execution state? Are they taking up "open file" slots and pushing me towards my stack overflow?
Is there a an easy (meaning via object model or gcode) for me to see how many files are open?My trace data (below) confirms that the last of the 5 repeated opens is the one that was responded to. In my tracing, at the start of every macro, a global variable is incremented and that number assigned as the trace-number for that instance of that file being run. I also log the start time of the macro and these correspond to the times in even log. And on line 6, you can see that the trace number 225 (the last instance of "load or unload Filament") is logging that it's calling the next macro.
221 , 2025-04-29T10:24:47 , 2522 , 0:/macros/load_unload_filaments/Load or Unload Filament.g , Starting Macro 222 , 2025-04-29T10:24:49 , 2524 , 0:/macros/load_unload_filaments/Load or Unload Filament.g , Starting Macro 223 , 2025-04-29T10:24:49 , 2524 , 0:/macros/load_unload_filaments/Load or Unload Filament.g , Starting Macro 224 , 2025-04-29T10:24:50 , 2524 , 0:/macros/load_unload_filaments/Load or Unload Filament.g , Starting Macro 225 , 2025-04-29T10:24:51 , 2525 , 0:/macros/load_unload_filaments/Load or Unload Filament.g , Starting Macro 225 , 2025-04-29T10:25:15 , 2550 , 0:/macros/load_unload_filaments/Load or Unload Filament.g , About to call: 0:/macros/load_unload_filaments/unload_current_filament.g 226 , 2025-04-29T10:25:15 , 2550 , 0:/macros/macros/load_unload_filaments/unload_current_filament.g , Starting Macro
So, as we used to say, "a lotta crap to read, what do we do?" I'm writing a debouncer into the start of the macro to not let it start too quickly after the last time it started. I'm picking 5 seconds.
Does all my analysis and plan seem reasonable?
I don't think these are needed, but here's my M122 output (m122 output.txt ), my full trace (trace_12.txt ) and the load and unload filament macro (pre start time debouncer) (Load or Unload Filament.g )