Short/long press detection

Short/long press detection with LogicMachine #

You can detect whether a short or long press was performed and implement different behaviors.

Create a resident script with 0 sleep time, modify the timeout and mapping variables as needed. Default long press time is 1 seconds.

In this example there are two input objects - 32/1/1 and 32/1/4.

If 32/1/1 is pressed and released within 1 second then 32/1/2 (short press) value is toggled. Otherwise 32/1/3 (long press) value is toggled if the button is not released within 1 second.

if not client then
  timeout = 1 -- long press in seconds

  mapping = {
    ['32/1/1'] = { short = '32/1/2', long = '32/1/3' },
    ['32/1/4'] = { short = '32/1/5', long = '32/1/6' },
  }

  timerstep = timeout / 4

  function eventhandler(event)
    local object = mapping[ event.dst ]
    if not object then
      return
    end

    local value = busdatatype.decode(event.datahex, dt.bool)
    if value then
      object.timer = timeout
    elseif object.timer then
      object.timer = nil
      grp.write(object.short, not grp.getvalue(object.short), dt.bool)
    end
  end

  client = require('localbus').new(1)
  clientfd = socket.fdmaskset(client:getfd(), 'r')
  client:sethandler('groupwrite', eventhandler)

  timer = require('timerfd').new(timerstep)
  timerfd = socket.fdmaskset(timer:getfd(), 'r')
end

res, clientstat, timerstat = socket.selectfds(10, clientfd, timerfd)

if clientstat then
  client:step()
end

if timerstat then
  timer:read()

  for addr, object in pairs(mapping) do
    if object.timer then
      object.timer = object.timer - timerstep

      if object.timer <= 0 then
        object.timer = nil
        grp.write(object.long, not grp.getvalue(object.long), dt.bool)
      end
    end
  end
end