Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Maximite 2: How to make switch trigger only once when pressed
Author | Message | ||||
Decoy Senior Member Joined: 02/08/2019 Location: DenmarkPosts: 109 |
Hi guys I finally had some time with the Maximite 2, after building a couple of them several months ago. I am recovering from my double-incision distal bicep tendon repair, so everything is done with the left hand I've managed to hook up a switch, with a cap to prevence bouncing (Arduino-style). How would I go about making the switch only register once per press, to avoid holding in the switch being seen as constant presses. I think I used the millis() function in Arduino ages ago - buw to do this on Maximite 2? Maybe a pre-made function exists? Something like: variable = 0 if button is pressed then variable = variable +1 I need the variable to count only once per press, then the switch must be depressed before pressing (and adding to variable) again. Any advice? Thanks! |
||||
jirsoft Guru Joined: 18/09/2020 Location: Czech RepublicPosts: 532 |
What about something like: 'initialisation DIM INTEGER prev = -1 and in function for key: IF button <> prev THEN prev = button IF button THEN 'BUTTON PRESSED! ELSE 'BUTTON DEPRESSED! ENDIF ENDIF Jiri Napoleon Commander and SimplEd for CMM2 (GitHub), Â CMM2.fun |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 3422 |
There is a writeup about this http://fruitoftheshed.com/MMBasic.Switch-de-bounce-uses-Ganssels-Algorithm-for-Zero-Delays.ashx PicomiteVGA PETSCII ROBOTS |
||||
Decoy Senior Member Joined: 02/08/2019 Location: DenmarkPosts: 109 |
Thanks guys A part of me is a little bit about this. I used to do it with millis() on arduino ages ago, but the last many years I have become used to GML (Gamemaker Studio 2-code) which just has a function for this. It seems like something almost everybody will need to use, whether they only do software or also hardware. If anybody has suggestions for the sleakest way to implement this, I would love to know. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5867 |
Does not qualify for "sleakest way" but it might be a start for you Use any digital pin and switch pulls input to ground. Internal pullup should be adequate but you could use external resistor to 3.3V instead. A capacitor is always advisable although the debounce timer should stop bounce triggers. The capacitor will reduce the number of calls to the sub. It assumes that you don't reset the timer anywhere in your program. OPTION EXPLICIT OPTION DEFAULT NONE CONST sw_pin = 10 const debounce = 200 DIM INTEGER sw_action SETPIN sw_pin, INTB, clicked, PULLUP DO IF sw_action = 1 THEN PRINT "clicked" sw_action = 0 ' reset the flag ENDIF LOOP SUB clicked STATIC INTEGER old_sw_state, old_time LOCAL INTEGER sw_state, new_time, interval sw_state = PIN(sw_pin) new_time = TIMER interval = new_time - old_time print "*" ' debug info to show contact bounces IF sw_state <> old_sw_state AND interval > debounce THEN old_sw_state = sw_state old_time = new_time IF sw_state = 0 THEN sw_action = 1 ' only set the flag with switch low ENDIF END SUB (I am one of the lucky ones, it's my left hand that's no use) Jim VK7JH MMedit  MMBasic Help |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3641 |
What's it called please / how does it do it? John |
||||
Decoy Senior Member Joined: 02/08/2019 Location: DenmarkPosts: 109 |
John, the normal function in GML is: Keyboard_check(key) - This will count as a press for each cycle that the key is pressed The other function is: keyboard_check_pressed(key) - this will only register once, then the key will need to be depressed before pressing it again. I have no idea what goes on behind the scenes :) The above also work for inputs from a microcontroller through a .dll. I sort of expected a high-level language such as BASIC to have an easier implementation of this than C++ or the like. Jim's example above is great, but it is as - if not more - involved, than the Arduino counterpart. . Edited 2020-12-02 03:12 by Decoy |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
In Geoff's Programming with the Colour Maximite 2 Document there is a chapter on Using a Switch as an Input on page 62. I would use an external pullup resistor because I have found that when using the internal pullup resistor, sometimes noise can trigger false inputs if the wire to the switch is too long. 100mS delay to allow for switch bounce has worked well for me. I would use an interrupt on low for the switch input pin so that, depending on what your program is doing, it wont miss a short button push. The interrupt subroutine would: disable interrupts to stop contact bounce re-triggering it. set a flag to show the switch has operated and return In the main program loop (having cleared the flag and set up the pin first) . . check the flag if it is set then pause 100mS (to de-bounce the switch) increment the variable clear the flag re-enable the interrupt on low endif . . loop That could be best done in a subroutine. I hope you're on the mend. I know from experience that paper work can be difficult left-handed. Bill Keep safe. Live long and prosper. |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3641 |
I can imagine just wrapping the MMBasic features up to provide those. Whether someone wants to bother and whether it's good to hide reality away I don't know. John |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
I don't like to hide things away. If I can read the code maybe I can understand it and learn from it. I didn't give code because I am not sure of Decoy's knowledge and it may help him learn by finding the instructions and how to use them. You could always check out Fruit-of-the-shed for examples. See this one for example. Bill Keep safe. Live long and prosper. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5867 |
Keyboard_check(key) and keyboard_check_pressed(key) sound like KEYDOWN and INKEY$, but I thought we were talking about switches, not the keyboard. My example and the others referred to hide the complexity from you if you don't want to know but allow you to fine tune them to suit special uses. That is the advantage of doing it in user functions instead of a built-in command. Jim VK7JH MMedit  MMBasic Help |
||||
Decoy Senior Member Joined: 02/08/2019 Location: DenmarkPosts: 109 |
Jim, what is the issue with your arm? If I may ask. I am getting the cast off in 10 days, then 10 years of rehabilitation Regarding my programming skills: I never recieved any training or courses in programming. I took my master's degree in biotechnology. I work in microbiology. Some years ago I decided to learn about programming - mostly due to video games. Several years ago I made the "first Danish arcade game" which was later sold to an arcade in Copenhagen. After that I made a program that calculate bacterial counts from plated dilution ranges along with count uncertainty presented in CFU and %. I recently released a game on Steam as well, and I am working on another game right now - and also a physical microcontroller-based bacterial count calculator for use directly in the lab to avoid having to write down/bring results out of the lab for later calucation. This is where I used millis() to do the button presses. My point is, I have many hobbies - and sub-hobbies. I am not afraid of the difficult stuff - I just try to find the easiest path with some projects. It would not be fair to compare my programming skills to people that are professional programmers. Unless it also goes the other way, such as "how would you make a bacteria competent and how would you introduce new DNA into the bacterial cell? By transduction, transformation or conjugation?". So, it probably was a wrong assumption to make - that BASIC had a more direct way of doing it, that would be shorter and easier than a low-level language. But I will do it the correct way Thanks guys - I love this forum and its users! Especially when they push me. Tomorrow I'll probably take it all back when I realize I was wrong. . Edited 2020-12-03 02:33 by Decoy |
||||
Tinine Guru Joined: 30/03/2016 Location: United KingdomPosts: 1646 |
If I understand the requirements, I would do something like: Do If [button input] Then Select Case DbChk Case 0 DbTmr = Timer + 100 DbChk = 1 Case 1 If Timer > DbTmr Then var = var +1 DbChk =2 End if Case 2 'let go of the button dammit End Select Else DbChk = 0 End if Loop |
||||
Decoy Senior Member Joined: 02/08/2019 Location: DenmarkPosts: 109 |
Do If [button input] Then Select Case DbChk Case 0 DbTmr = Timer + 100 DbChk = 1 Case 1 If Timer > DbTmr Then var = var +1 DbChk =2 End if Case 2 'let go of the button dammit End Select Else DbChk = 0 End if Loop I really like this switch statement approach! Thanks! . |
||||
Tinine Guru Joined: 30/03/2016 Location: United KingdomPosts: 1646 |
Still too many lines of code for my liking but I have never used the PULSIN function...Would that be an option? Edit: Hmmm, I guess that the PULSIN would hold up execution (?) which is a no-no for me. Edited 2020-12-03 11:53 by Tinine |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5867 |
Neurological so not fixable. The code used will depend on the requirements. In my joystick code, the buttons are scanned every 16mS and only interested in the current state so no de-bounce required. My water flow monitoring wouldn't like too many bounces so it needs de-bounce. I used capacitors rather than code so the MMBasic 'count' option can be used. Do you want fast response? That leaves you open to short spikes being seen but could limit the rate they are seen at. If you don't mind a slower response, de-bounce code will eliminate the stray spikes. How much delay will depend on your choices. If I want to use my fingers and cheap switches, I would need a ridiculously long de-bounce time. You might want to multipurpose the switch. Short press for one action, long press for something different. Or maybe, a repeat function. Lots of choices and MMBasic can do them all. Jim VK7JH MMedit  MMBasic Help |
||||
Decoy Senior Member Joined: 02/08/2019 Location: DenmarkPosts: 109 |
Edit: Hmmm, I guess that the PULSIN would hold up execution (?) which is a no-no for me. Well, one thing - I prefer debouncing in hardware rather than code. Or that is how I usually do it. I also do not need a very fast read. It should fit with a finger pressing a button. As Jim states above, maybe a solution would need to include a different outcome when the switch is held. . |
||||
Tinine Guru Joined: 30/03/2016 Location: United KingdomPosts: 1646 |
Not a problem with my Select Case example; any contact bounce would cause a reset of the timer and the contacts would need to remain closed for 100ms to register as a valid signal. The Case 2 is do-nothing while the input is still high and that can be used for a long press if required. |
||||
Print this page |