PDA

View Full Version : My code for ADC button handling, it works, but can it be slimmed down?



CuriousOne
- 2nd January 2022, 15:47
Hello,
This is my code for handling two buttons connected to ADC input.
It works fine, and what was most important, it prevents repeated key action -
user has to release the button and press it again, to call needed action again.
However, there are quite a lot of variables, and their number will double with
more buttons being added.
So maybe there is a way to make it simpler, while still maintaining
"do not repeat action" functionality?



menu: 'main loop for button handling
adcin 1, adcval 'read keys
if adcval=255 then n1=0: n2=0: left=0: right=0 'if no key, then reset both button variables
if adcval<10 then left=left+1 'detect button presses
if adcval>100 and adcval <130 then right=right+1 'detect button presses
if left>100 and n1=0 then 'if button pressed enough and it was not pressed before
left=0
n1=1
gosub action1 'button 1 tasks
endif
if right>100 and n2=0 then 'if button pressed enough and it was not pressed before
right=0
n2=1
gosub action2 'button 2 tasks
endif
pause 1 'input delay
goto menu

mpgmike
- 3rd January 2022, 19:05
adcin 1, adcval 'read keys
SELECT CASE adcval
CASE < 10 : left=left+1 'detect button presses
CASE < 100
@ NOP
CASE < 130 : right=right+1 'detect button presses
END SELECT

You might try the SELECT CASE method of parsing through. The above snippet should give you an idea.[/FONT]

CuriousOne
- 3rd January 2022, 20:01
Thanks!
My main concern is number of variables needed...

richard
- 4th January 2022, 01:10
code snippets do not provide any where near the required info to provide a meaningful answer, not even one var definition is even provided

for a meaningful answer
1 how often is routine called
2 is it called on a regular timed basis
3 how responsive does it need to be

the minimum key data necessary would be a count to detect a debounced press a bit to indicate a new press detected and a bit to indicate
the press has been acknowledged and acted on provided the right conditions exist

CuriousOne
- 4th January 2022, 05:10
1. At least 10 times per second.
2. Yes
3. As responsive as any other device, where user presses key and expects immediate feedback.

richard
- 4th January 2022, 05:34
1. At least 10 times per second
if right>100


so button has to held for ten seconds till you get a response ?


As responsive as any other device

not in my book, i doubt the thing is working after 300mS


2. Yes
like how regular how often really

CuriousOne
- 4th January 2022, 09:37
No.
I mean keyboard is polled at least 10 times per second.
This is general interactive device control, with direct feedback
like your TV remote.

Acetronics2
- 5th January 2022, 09:44
Why not use the genuine BUTTON command ?????????????????

of course, needs some "brainwork" and practise - and of course at least " read that f...... manual " ... "

but the result is worth the effort ... :rolleyes:

" Just my two cents " ...

Alain

CuriousOne
- 5th January 2022, 10:45
Read 1st post 1st :D

This is ADC input.

Acetronics2
- 6th January 2022, 07:40
Read 1st post 1st :D

This is ADC input.

ADC for ONLY two buttons and " immediate response " ( sic ) ??? ...

if it's your choice ... go on ! ( :D ) ...

Alain

richard
- 6th January 2022, 10:43
adc key reading is a good tried and tested technique and can be very responsive, the question here is can it be done
using less memory. the answer is yes of course, if done in a methodical way.
c1 has opted not to discuss or elaborate on his implementation in any meaningful way. end of story

CuriousOne
- 6th January 2022, 13:33
This is just an example for 2 buttons
for 20 buttons there should be 40 variables
I wanted to avoid that
this is why I asked
:D

HenrikOlsson
- 6th January 2022, 13:40
With 10 or 20 keys, how do you handle the event of more than one key being pressed at the same time?

CuriousOne
- 6th January 2022, 18:52
By clever selection of ADC resistors.
This had been solved long time ago, and not by me :)

mpgmike
- 7th January 2022, 00:40
Recent posts got me thinking. Are you designing something with a bunch of buttons, each with a specific functionality? Or are you trying to do something more akin to a key pad? If you're using a standard key pad there are set-ups using resistors to create a narrow voltage range with the press of any individual key. That only requires one analog input to read any key press.

https://aws1.discourse-cdn.com/arduino/optimized/4X/2/5/d/25de6b9b349e735c7bb26c3dfc99e8af5fa9dd5a_2_542x500 .jpeg

richard
- 7th January 2022, 02:30
12 buttons is ok with 8 bit adc . with 16 the last row gets down to 2 or 3 counts separation , a bit close for comfort in my view

CuriousOne
- 7th January 2022, 13:20
At current stage, I'm looking for more efficient and small code
for ADC key handling.

Ioannis
- 7th January 2022, 20:07
Doesn't post#2 with the use of Select Case do what you want with the least code/var usage?

Ioannis

CuriousOne
- 7th January 2022, 20:22
No it does not.
It does not do "do not repeat action until user releases and pushes key again"

Ioannis
- 7th January 2022, 20:38
if !flag then
adcin 1, adcval 'read keys
SELECT CASE adcval
CASE < 10 : left=left+1:flag=1 'detect button presses
CASE < 100
@ NOP
CASE < 130 : right=right+1 :flag=1'detect button presses
END SELECT
endif


Something like that then?

Ioannis

CuriousOne
- 7th January 2022, 20:44
Yes and we again will have extra "left" and "right" variables, one per each button - what I wanted to avoid :)

Ioannis
- 7th January 2022, 20:47
maybe I am a bit slow.. But how you can have 40 buttons but not 40 variables to distinct between them?

Ioannis

CuriousOne
- 9th January 2022, 09:59
ADCIN X,ADVAL
IF ADVAL=20 then Gosub Y1
IF ADVAL=10 then GOSUB Y2
IF ADVAL=30 then GOSUB Y3

and so on.

Ioannis
- 10th January 2022, 14:32
So at any given moment you will not know which button was hit and will have to scan again.

But even so, a flag for each button pressed is needed to keep it from regarding it as new press.

Ioannis

mpgmike
- 10th January 2022, 17:07
Regarding flags, here is a trick I use:


ButtonA VAR WORD
Button1 VAR ButtonA.0
Button2 VAR ButtonA.1
......
Button16 VAR ButtonA.15

This creates bit flags. To use them:


Button4 = PORTC.3

HenrikOlsson
- 10th January 2022, 20:08
If you have many inputs scattered around various ports and you want to "gather them" in one consecutive block so you can iterate over them using a loop then sure, why not. Otherwise I must say I don't see the point of doing that. You might as well simply alias the bit variable directly to the port bit/pin and be done (after all, the Port registers is just another byte in memory - right).

Button4 VAR PortC.3
You'll save RAM, FLASH and processor cycles by not first copying the value of one bit variable (PortC.3) to another (Button4) only to then evaluate the state of Button4 variable.

But, I might be missing the point alltogether, in which case I apologise.

/Henrik,

Ioannis
- 10th January 2022, 20:32
Here there are not ports... Only a ADVAL from ADC since the buttons are read as analog voltage.

Ioannis

richard
- 10th January 2022, 23:05
its a fairly simple process , 10 bits per button is easy , 8 bits with a bit of effort
providing the button check is called in a loop at a relatively consistent rate.
the program structure matters , spaghetti code won't get good results
sudo method

b1cnt var byte
newb1 var bit
b1dun var bit
b2cnt var byte
newb2 var bit
b2dun var bit
osc=8
t1con=$01;32mS
main
if pir1.0
pir1.0=0
gosub getkey
if newb1 gosub dob1
if newb2 gosub dob2
endif


goto main




getkey:
read adc
b1cnt = b1cnt<<1
b2cnt = b2cnt<<1
if adc in b1 range
b1cnt = b1cnt+1
elseif if adc in b2 range
b2cnt = b2cnt+1
endif
if !b1dun
if b1cnt=255 then newb1=1 ;32*8mS
else
if b1cnt=0 then b1dun=0
endif


if !b2dun
if b2cnt=255 then newb2=1
else
if b2cnt=0 then b2dun=0
endif


return


dob1:
b1dun=1
newb1=0
do b1 stuff
return


dob2:
b2dun=1
newb1=0
do b2 stuff
return