B4R Code Snippet Long press short press one button

This is just one solution on how to tell if a button is being long pressed or short pressed. There are plenty of other solution to do this, this is my take on it, it's simple but effective.

For this example a long press is over 1 second and a short press is under 1/2 a second. Nothing happens in between those two times, but you can easily adjust the short press time to fill in the gap, for example from 500 to 999 milliseconds.

I was thinking about how to program my ESP8266 smart switches when it suddenly dawned on me, I could use a long press of 5+ seconds to turn on the the WiFi.StartAccessPoint, thus allowing me to adjust/set the SSID and other setting in my smart switches.

I tested the code below on a WeMos D1 Mini with a button shield on top, the button shield uses 'D3' to ground the button. A short press toggles the LED On/Off, a long press does absolutely nothing.

AppStart
Short press
Short press
Short press
Long press
Short press
Long press
Long press
Long press
Long press
Short press
Short press
Short press
Long press
Short press
Short press
Short press
Short press
Short press
Long press
Long press
Short press
Short press
Short press
Short press
Short press
Short press
Short press
Long press
Long press
Short press
Long press

WeMos D1 Mini with a button shield
Untitled Sketch_bb.png


B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial

    Private RunTime As ULong
    Private BtnPin, LEDPin As Pin
    Private LastState As Boolean = True
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Delay(1500)
    Log("AppStart")

    BtnPin.Initialize(0, BtnPin.MODE_INPUT_PULLUP)     'Pin D3 on the WeMos D1 Mini
    BtnPin.AddListener("BtnState_StateChanged")

    LEDPin.Initialize(2, LEDPin.MODE_OUTPUT)           'On board LED on the WeMos D1 Mini
    LEDPin.DigitalWrite(True)
End Sub

Sub BtnState_StateChanged (State As Boolean)
    Dim LongPress As Int = 1000, ShortPress As Int = 500

    If Not(State) And LastState Then      'Button Pressed
        LastState = State
        RunTime = Millis()                'Runtime
    End If

    If State And Not(LastState) Then      'Button Released
        If ((Millis() - RunTime) <= ShortPress) And ((Millis() - RunTime) <= LongPress) Then
            LEDPin.DigitalWrite(Not(LEDPin.DigitalRead))    'Toggle LED On/Off for test purposes
            Log("Short press")            'Run some code
        End If

        If (Millis() - RunTime) > LongPress Then
            Log("Long press")             'Run some code
        End If
    End If

    LastState = State
End Sub

Enjoy...
 
Last edited:
Top