Pico: strange behaviour with setWatch on BTN1 #5353
Replies: 1 comment
-
Posted at 2016-04-28 by @gfwilliams What board are you using? Looks like it's not an Espruino one given you're using the falling edge? Some other boards have really cheap buttons that don't always work, and some may not have pullup/down resistors, which would mean than when not pressed the signal would 'float' Posted at 2016-04-28 by @gfwilliams Sorry just read the title - this is on a Pico? To detect a button press, you probably want Are you using an up to date firmware? I know some earlier ones had issues with debouncing. Also, is that the only code you're running? Could be be that the pin state on Posted at 2016-04-28 by Marc Yes, it's a pico. Posted at 2016-04-29 by @gfwilliams If it keeps happening, maybe you could get the code down to something that you're happy sharing, and could post it up so I can see if I can reproduce it? Posted at 2016-05-07 by dwallersv I see similar "sensitive" behavior with the button on my pico, and just assumed it was a defective button. Since i don't really use it, it's not an issue. However, same thing: Seems sometimes I just need to get my finger near the button for it to activate. Odd, since the expected tactile "snap" of the button when you actually press it is there. Yet, it seems to take just the lightest of contact -- no actual push -- to activate it. This is on the canned demo LED lighting watch that is preloaded with the IDE. Posted at 2016-05-08 by dwallersv Played with it a bit more and, at least in my case, it's definitely some static sensitivity. If I rest my finger on the button, then it takes a positive, tactile-feedback press -- every time -- to activate the button. If I simply bring my finger over to to the board at random time to "press" the button, it will activate often at my finger just touches, without any force, the top of the button. Posted at 2016-05-09 by DrAzzy Could the pin be floating, instead of being pulled up or down? I forget which way the button is wired (ie if it goes to vcc or gnd when pressed) - set the pin to be pulled up or down as appropriate. If it's just an input, it will float when button isn't pressed, and the voltage measured on the pin will depend on ambient electromagnetic fields. That definitely sounds like a floating pin. Posted at 2016-05-09 by @gfwilliams Maybe check As @drazzy says, if it were just floating then it would cause the kinds of issues you're reporting Posted at 2016-06-11 by GeekBot Hello, var ledjaunestate = false; It's on Pico with firmware : espruino_1v85.506_pico_1r3_wiznet.bin Thanks a lot Posted at 2016-06-11 by @allObjects @marc, is your strange phenomenon still well and alive? Could you share your @Geekbot, what does your volt meter say when the Button is pressed? From your code - What kind of button do you have? What's the cleanness of the contacts? No insult here, but buttons come with all kinds of behavior. For the debounce, 5ms is a bit short, most people use 50..100ms. Sometimes it is just some electro-mechanical issue... lousy breadboard connectivity... Posted at 2016-06-11 by Marc It's exactly the same as dwallersv reported in #7. Best wishes, Posted at 2016-06-11 by @allObjects @marc, can you share a pic of the button? Does your screw driver have an insulating handle? It sound to me as if the button part that you touch has some conductivity and connects 'you' with the pin. Depending on the 'electro smog' you are in, this make the pin to sense edges and triggers by Furthermore, I was reading your post #4 where you describe vaguely what else is going on. Do you know the power drawn by these number of outputs? I'm going on a goose chase here, but it could well be that in addition to the button issue, there is a power issue going on. Even though the chip can source/drain 20mA with guaranteed levels per pin, there is a total of power that can be sourced and that is max 120mA - p59 of STM32F401xD datasheet. Posted at 2016-06-13 by GeekBot Thank you for your questions/answers. I did some tests and measurements so, here are my answers :
Posted at 2016-06-13 by @allObjects Test with - external -different pullup resistors: 10K, 4.7K 1K 470R... If this does not help, I don't know what to say... Or - if possible with the overall setup - make the switches connect to 3.3V (or 5V). Pico inputs are 5V tolerant. If it's not working with built in "input_pulldown", use same external resistors... Posted at 2016-06-15 by @gfwilliams @marc @dwallersv does the Pico look ok around where the button is? Maybe try cleaning around the sides of it with some board/contact cleaner and a small brush? The internal pullup resistor is around 40k, so I guess it's possible that if the contacts on the side of the button got dirty they'd get conductive and would start to pull the voltage on the input up - and then when you got your finger close, electrical noise might just be enough to set it off. @Geekbot The underlying hardware detects changes in the input, but not whether it is rising or falling. If the input changes state really fast it can go down to 0v, triggering the IRQ, but can then rise back up by the time the IRQ has fired so a 1 is read, and can then fall again. Espruino then thinks the button is in the raised state, and doesn't call your callback. There's actually very little that can be done about that internally... You could try adding a small capacitor across the button to stop it happening. Or one simple way might be to just detect the press, without a debounce?
Posted at 2016-06-16 by GeekBot Thank you Gordon Posted at 2016-06-16 by @gfwilliams When you specify debounce it doesn't call your function until the button has stayed in the new state for the given number of milliseconds. The idea is to stop the function being called multiple times from one press - however because of the way the underlying hardware works, with very noisy buttons you can sometimes (although it's unlikely) get into the state where the button is pressed but during the last interrupt Espruino received, it was read as having been released. ... however, if you only care about whether the button has changed state then you don't have to care about that. You can effectively do your own debouncing by doing something when the button first changes state and then ignoring any extra changes for a fraction of a second. Posted at 2016-06-16 by @allObjects @gfwilliams's code implements an state machine with two states and dynamic behavior: A very first 'spike' transitions from false to true, executes the application function (invert and apply LED state), AND becomes unresponsive - ignores any pin state changes - for the next 100ms and then flips automatically back to state false. Returning to state false puts it back into responsive state. 'Unfortunately', it implements only half of 'the world'. With this setup of repeat: true, holding the switch for longer than 100ms AND THEN releasing it, creates another trigger of the application function: invert and apply LED state. This means that a press longer than 100ms switches twice the LED. (Yellow(?) LED goes either on for the pressed time or off. To verify this - I assume - unintended behavior with - PICO or Legacy - on-board components BTN1 and LED1, load and run this code... and you notice: it is difficult to toggle LED1 (ledrougestate... ;-) ). You have press the button for less than 100ms, which is more like a 'gentle hitting' / tapping:
The code has some more (inherent) flaws: press the button for more than 100ms, then release it for less than 100ms with - finally - pressing it for A) more or B) less than 100ms, you get a toggle or a double toggle. Not necessarily the expected UX. To (partially) complete the state machine, setting of
A cleaned up version of the code (for BTN1):
Note the edge: "rising" option. No need for both... Even though the button test is added, there is still a 'window of opportunity' for a jitter: when the button is released about the time of the pin test, a bouncing may be experienced... Furthermore, there are still inherent flaws: between the repeated testing of the button state, the user can have - after some decent press time - released, pressed very briefly, and released the button again, and that action gets lost. Since by experience mechanical button presses are usually longer than 100ms, choosing shorter interval makes it work... something between the (button's typical) bouncing (time) and the 100ms. If it is shorter than the (button's typical) bouncing (time), unpredictable behavior creeps in again. Therefore, only making the state machine switching symmetrical makes it more predictable... It boils down to the UX specifications: Presses and releases of a switch have to be pressMs and releaseMS* in order to reliably detect and execute a toggle. Debouncing is not a simple task... and buttons with consistent and short bouncing avoid to make it worse... (the buttons picked - as described in post #14 - seem to be decent... except you got a 'lemon' or 'monday' or 'friday late' lot version...) PS: Looks like a toggle module could come in handy to take the tedious work off of the hand of the application... |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2016-04-28 by Marc
Hey Gordon,
I have a strange phenomenon with setWatch. The Code:
clearWatch();
setWatch(demo, BTN1, {repeat:true, edge:'falling', debounce:50 });
The demo() function just does some LED blinking.
When pressing the button the watchfunction runs once most times, but sometimes twice and in rare cases it even loops forever without stopping.
Sometimes i only have to move my finger on the button without pressing it and the demo function runs.
I tried all kinds of parameter combinations, but did not find one that works once every time the button is pressed.
Any idea?
Thanks in advance,
Marc
Beta Was this translation helpful? Give feedback.
All reactions