Software Buttons - Many buttons from just one hardware button #3324
Replies: 31 comments
-
Posted at 2014-07-24 by @allObjects (2 of 2) continued. Software Buttons - Many buttons from just one hardware button Constructor and methods:
Basic usage examples:
The code above creates an enabled software button. On press sequence detection it invokes the passed anonymous function with the pressed sequence as parameter value, for exmple "S" for one short press, "SS" for two, and "SL" for one short and one long press, etc. The implementation of the function writes the press sequence to the console:
You may wonder why the button's returned key value for the press sequence is not a series of dots (.) and dashes (-). The reason is simple: the key as returned can be used as valid property or function name (of an object). For example, the following code - entered into the IDE command pane after sending the SWBnt class code to the Espruine - counts how many of the various sequences have been pressed,
and entering the following code into the IDE command pane gives a report about the counted various press sequences:
To print this report and reset the counters on 'pressing' the "SSSSS" software button - 5 short presses of Btn1 - set following function on existing mySWBtn (or pass it on in a new creation).
The above example shows that the function can be set or changed on a button after its creation, and so can you also change the C(onfiguration) parameters for the timings - but remember, you will change the timing for every SWBtn - because they shard the one and only C(onfiguration). To control the RLL running led light shown in forum comment at What is LED1/A13? (addressing pins via variables),
Do disable and re-enable the button, invoke the .disable() method:
Latter is the same as:
Above is not very obvious, but still as designed: the missing boolean argument evaluates to false... ;-) A button can be created in disabled state:
This is especially helpful when other initialization processes have to happen or complete before user input can be accepted. To enable the button at desired point in time, just invoke the .disable() method:
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2014-07-24 by @gfwilliams Thanks! It's really good to have broken this out into an Object of its own... Do you think you could try packaging it up into a module? Instructions here. I guess it might be handy to rename |
Beta Was this translation helpful? Give feedback.
-
Posted at 2014-07-25 by @allObjects .d() changed to - more readable - .disable(). Certainly, I will package it up as a module. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2014-07-26 by @allObjects SWBtn hardened and commented in preparation for publishing as a module. This is a Request For Comments (RFC). Feedback for code fixes and comment/wording and functional enhancements are very much appreciated.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2014-07-26 by @allObjects Testing robustness of SWBtn's .disable() method Copy SWBtn and test code at the bottom of this post into edit pane and send it to Espruino. Basically, there will be intervals with enabled and disabled SWBtn. During and straddling those intervals you will perform press sequences. Be prepared to timely perform press sequences as instructed below while test code shows passed seconds in command window. The test code will do this:
You perform these timely sensitive press sequences:
The output you will see in the command pane should look like this (on [1v67] - at this time the most recent version):
...which means, that:
Note1: press the reset button to stop the test code's seconds to keep going on. Disconnect is not enough (After reconnect, passed seconds output shows at once). Of course, powering off does stop it too, Note2: At one time I got
For fun, extend (and post your) test that begins with a disabled button and shows that it is disabled and starts observing press sequences when enabled. Notice that when a press sequence is going on and the button is (re-)enabled, only the part that leaps into the (re-)enabled period is picked up... and if the (re-)enablement happens during a long press, this long press may be detected as a short press. So far, only software and a (external) button operator are used for the testing. Adding some hardware - such as a wire that connects an output (configured) pin with and input (configured) pin or even using another Espruino board - and creating a SWBtn on the output pin controlled input pin allows to write complete software driven testing of the SWBtn. For sure something worth to be tackled at a later point in time.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-10-03 by bigplik how to use this in some simple example with LED function? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-10-03 by @allObjects Example below assumes default button BTN1.
If you have a button on a pin - for example, A8 - use this:
More sophisticated, you can go with this:
Note: Code only partially tested. ;-) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-10-08 by bigplik thank you, I'll test it |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-11-11 by Moray @allObjects did you ever submit this as a module? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-11-11 by @gfwilliams Yes... but I posted on there twice asking if the webpage that goes with it could be fixed - no reply yet :) @allObjects would you mind fiddling with the documentation file? For now, it can be used with:
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-11-11 by @allObjects @gfwilliams, yes. My working w/ git needs a bit shoe-horning. - Thanks for the great example. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-15 by @MaBecker @allObjects - wow - this is very helpful and can be used as button extension for Puck.js I use it like this
Thanks for sharing ! |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-25 by ancienthero I was wondering how to code given behaviour: such a behaviour is often implemented for setting hours etc. I've tried this:
It works... but it's clearing other intervals. Thanks |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-25 by ClearMemory041063 You can identify an interval by naming it
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-10-05 by @allObjects @ancienthero, the idea of holding and measuring how long a button is held pressed conflicts with the idea of detecting series off short and long presses. To cover holding and holding how long beyond a short or long press has to be managed by some other module. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-23 by bigplik
could anyone explain how to change default button pin? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-23 by @allObjects @bigplik, you just pass a second argument into the constructor. The second argument is the button / pin and is optional. If absent, it is BTN1.
The constructor accepts three arguments of which latter two are optional:
If you construct the software button disabled, you can enable - as well as disable - it anytime in the code:
With application code controlled enabling/disabling of the SW Button you can ensure unambiguous UI behavior. Since SWButton (what you get from module) is a constructor, you can setup multiple SW Buttons, like:
To see the code, just open in the browser the url in the require. You will notice that it includes much more information - including inline doc and examples. SW button is quite 'open': you even can configure the (detection) timings meeting custom requirements:
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-24 by bigplik in reply to @allObjects do I need some setWatch to make it run? is this example below enough to run or there is missing part?
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-24 by @allObjects Assume, you have an Espruino Pico, and you have added a button on pin B3 to 3.3V, you proceed as follows:
PS: above example assumes also that you download / copy-paste the SWButton code from url on git into your modules folder with the name WSButton.js. You can of course keep the url in the |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-24 by bigplik i have espruino Original, and with code I placed above it is not working with button installed on board, I can call this button from IDE by BTN and BTN1 (and button works with other examples), but not with the code I placed above i also try it like this, and still doesn't work
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-24 by @allObjects @bigplik, did you add a physical button on pin B3 or B12 as shown in https://www.espruino.com/Button ? Btw, on Original Espruino board, B12 is the same as BTN1. If this is not working, have no idea (yet) why not... :\ |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-24 by @allObjects ...checking right now with an Original Board, version 1.4b, which is on 2v08... but will get most recent after doing some tests w/ this combination. I'll let you know about how it goes. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-24 by @allObjects Mystery solved... there is an issue with the How to fix (quickly)? Clone the module to local and add the TL;DR: With the test rig below I just tested the original code - no line 144 (no edge option specified) - as inline module and got this output, which indicated that the button BTN1 works just as expected, but SWBtn just does not get events in button release... Then read the doc... n-times... until reading finally the fine print. This is the test output that shows that SWBtn never fires a
After addin line 144 - incl. option
Test rig and adjusted setWatch() in code - now also fixed on github:
After upload, playing with button BTN1, tests t1() and t2() work just fine... t2() had initially NO Reference documentation added some more fine print since inception of setWatch() 7+ years ago... |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-24 by @allObjects Updated github... version at https://raw.githubusercontent.com/muet/EspruinoDocs/master/modules/SWButton.js is back to work... ;-) Lesson(s) learned: Don't trust any defaults! ...they may change and make your life a misery. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-25 by bigplik thank you so much, it works great ;) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-25 by @allObjects @bigplik, urvw, anytime... - ao |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-04-10 by @allObjects This code tried to become a module in http://espruino.com/modules a long time ago - at a time when I was not yet familiar enough to pull that thru. Even though the code is now pretty 'old', it is still in demand. Therefore, as a first step, I make a condensed version (w/ examples) that you can copy into your application to take advantage of SWButtons without having to get rid of all the noise by the comments. Second, I'll add files you can copy into your sandbox project modules folder to use the code as real module using NOTE for previous users: I switched to The example code does the following:
First, in-line module code w/ example:
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2023-10-16 by ccchan can the button be made into like receiving morse code? then you can have 26 (or more?) conditions? thanks |
Beta Was this translation helpful? Give feedback.
-
Posted at 2023-10-23 by @allObjects Sure... the challenge is syncing to the timings the emitting side uses. Some 'AI' has to detect over some time what the emitter's times are for short, long, break between 'beeps' and then characters and then words, and then apply it retrospectively. On the Web there is some code that already does this. After initial syncing, adjusting the sync has then to happen continuously. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2023-11-01 by ccchan youtube: [【只有一个键的键盘,靠输入摩斯密码来写代码,程序员都看哭了!-哔哩哔哩】 https://b23.tv/P3jlGza](【只有一个键的键盘,靠输入摩斯密码来写代码,程序员都看哭了!-哔哩哔哩】 https://b23.tv/P3jlGza) use 1 button to input morse code. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2014-07-24 by @allObjects
Update 2022.0410: see post #29
Update 2021.0524: option
edge:"both"
addedInspired by the great number of user input/output elements - BTN1 button
and LEDs LED1, LED2, and LED3 - on the Espruino board right out-of-box,
my first hands-on experience and fun was coding running led lights -
red-green-blue-... - controlled by the BTN1 button.
Light show control 'buttons' include:
For cycling through the LEDs using variable addressing vs. cascaded if then else-if,
I found related forum entry at [http://forum.espruino.com/conversations/573]
(http://forum.espruino.com/conversations/573) -
What is LED1/A13? (addressing pins via variables). Below you find the code
for the RLL Running LED Light singleton/class implementation with variable defined LED access and operations controlling buttons.
The running led light RLL implementation began as a torso that just cycled through
the LEDs on loading of the code.
In order to control the light show, following methods got added to RLL singleton/class:
Start/stop / toggling between start/stop was easy by just detecting any press -
actually release (and stay released for some time) - of the BTN1 button.
Detection of a transition from pressed to released with staying released for a
defined debouncing time is managed by a timer with ongoing setTimeout and
comparing previous versus current button BTN1 state / digitalRead(BTN1).
Inspired by the lots of timers and setTimeouts that made the running led lights and
the start/stop/toggle button work, I wanted to use them also for not just only noticing
button presses and eventually counting them, but also for detecting the duration of
the presses and sequences of such presses.
Sequences of short and long presses would allow me to create with one hardware button many software button or commands to control multiple things with one single control. The same thing did Samuel B. F. Morse - see http://en.wikipedia.org/wiki/Morse_code - tocode letters, digits, and special characters into simple sequence of short and long "on"s, send those over a (telephone) line (wire), and create short and long dashes by a pen pushed down on a moving paper stripe by a solenoid.
Mislead by an inaccurate, early publication stating that Espruino would not support the use of interrupts generated by pin state transitions, I built everything in
software using just timers / setTimout() and testing pin states w/ digitalRead().
@gfwilliams's gentle nudge - Have you seen setWatch? - made me refactor and extend the code in order to became a general purpose SWBtn software button component - which soon will be available as a module.
(1 of 2) - to be continued...
Software Buttons - Many buttons from just one hardware button
Beta Was this translation helpful? Give feedback.
All reactions