Single/double/multiple press detection with LogicMachine #
You can detect whether a single or double press was performed and implement different behaviors.
Create a resident script with 0 sleep time,
modify the presstimeout
and mapping
variables as needed.
Default press timeout is 0.5 seconds. When the timeout occurs a
specific action that depends on the number of consecutive
presses is executed. Each consecutive press resets the timer.
In this example there are two input objects - 0/0/1
and 0/0/2
.
If 0/0/1
is pressed:
- once (single):
0/0/3
value is set to12
- twice (double):
0/0/4
value is set to55
- multiple time:
0/0/4
value is set to33
If 0/0/2
is pressed:
- once (single):
0/0/5
value is set totrue
- two or more times:
0/0/6
value is set tofalse
Multiple (three or more) press address and value are optional. If it is not set then the double press action will be executed for any press count that is larger than one.
-- maximum time between presses
presstimeout = 0.5
mapping = {
['0/0/1'] = {
-- single press
single_address = '0/0/3',
single_value = 12,
-- double press
double_address = '0/0/4',
double_value = 55,
-- multi (3+) press (optional)
multi_address = '0/0/4',
multi_value = 33,
},
['0/0/2'] = {
-- single press
single_address = '0/0/5',
single_value = true,
-- double press
double_address = '0/0/6',
double_value = false,
},
}
require('copas')
function write(map, key)
local address = map[ key .. '_address']
local value = map[ key .. '_value']
if address and value ~= nil then
grp.write(address, value)
return true
end
end
function timerthread(addr, map)
local counter = 0
local timeout = -1 -- suspend thread
while true do
copas.sleep(timeout)
if map.counter == counter then
if timeout == presstimeout then
if counter == 1 then
write(map, 'single')
elseif counter == 2 or not write(map, 'multi') then
write(map, 'double')
end
timeout = -1
counter = 0
map.counter = 0
end
else
timeout = presstimeout
counter = map.counter
end
end
end
for addr, map in pairs(mapping) do
map.counter = 0
map.thread = copas.addthread(timerthread, addr, map)
end
function eventhandler(event)
local map = mapping[ event.dst ]
if map then
map.counter = map.counter + 1
copas.wakeup(map.thread)
end
end
lb = require('localbus').new(1)
lb:sethandler('groupwrite', eventhandler)
copas.addserver(lb.sock, function()
lb.sock = copas.wrap(lb.sock)
while true do
lb:step()
end
end, 1)
copas.loop()