A flashlight finite state machine

January 24, 2026

I’ve muddled around with this off and on for years,
without really finishing it; but my friend Robert started playing with an AI formal requirements tool, and I needed a test case. Imagine we have a flashlight. It has a simple on-off button, that latches in the on position but can be momentarily pressed. This allows the user to do all sorts of things, such as set modes, check battery level, etc.

I have a couple of flashlights that work more or less like this. However, they tend to have rather inscrutable modes of operation, and the documentation is at best unclear.

Shouldn’t there be a better way to use the flashlight? Or, at the very least, a straightforward diagram that shows how it works?

The diagram and associated requirements list below, illustrate how complicated even a “simple” flashlight can be!

This is all very notional, and just a test case anyway, so don’t expect accuracy or completeness at this point. I’m dropping it in here to the blog mostly so I can find it later. I might update progress if anything changes or improves.

stateDiagram
  direction TB
  [*] --> On:button latched
  state On {
      state Light {
        [*] --> State1
        State1 --> State2:button short press
        State2 --> State3:button short press
        State3 --> State1:button short press
        State1 --> setS1Brightness:button long press
        setS1Brightness --> State1
        State2 --> setS2Brightness:button long press
        setS2Brightness --> State2
        State3 --> setS3Brightness:button long press
        setS3Brightness --> State3
      }
      --
      Strobe --> [*]:button press
      state Strobe {
        [*] --> SetMaxBrightness:three button presses
        SetMaxBrightness --> SetMinBrightness
        SetMinBrightness --> SetMaxBrightness
      }
      --
      state BSoC {
        [*] --> GetBSoC:two button presses
        GetBSoC --> Flash:n += 1
        Flash --> n=bsoc?
        state ifState <<choice>>
        n=bsoc? --> ifState
        ifState --> True:n == bsoc
        ifState --> False:n < bsoc
        False --> Flash
        True --> [*]
      }
      --
      state Bmon {
        state "GetBSoC" as GetBSoC2
        [*] --> GetBSoC2
        GetBSoC2 --> bsoc<=1?
        state blev <<choice>>
        bsoc<=1? --> blev
        state "True" as T
        state "False" as F
        blev --> T : bsoc <= 1
        blev --> F : bsoc > 1
        T --> setBrightnessMin
        setBrightnessMin --> blink3times
        blink3times --> [*]
      }
      --
      state BtnCheck {
        [*] --> getBtnState
        getBtnState --> debounce
        debounce --> isPressed?
        state pState <<choice>>
        isPressed? --> pState
        state "True" as T2
        state "False" as F2
        pState --> T2 : pressed
        pState --> F2 : not pressed
        T2 --> timer
        timer --> getBtnState
        timer --> longPress
        timer --> shortPress
        longPress --> [*]
        shortPress --> [*]
      }
  }

  On --> [*]:button unlatched
sequenceDiagram
     actor User

    participant On

    box Aqua Flashlight On
    participant Strobe
    participant BSoc
    participant Bmon
    participant BtnCheck
    end
    box Orange Light Modes
    participant State1
    participant State2
    participant State3
    end
    
    participant Off

    User->>On : switch on
    On->>State1 :

    User->>BtnCheck : short press
    BtnCheck ->> State1 : shortPress = true

    User->>BtnCheck : short press
    BtnCheck->>State2 : shortPress = true

    User->>BtnCheck : short press
    User->>BtnCheck : short press
    User->>BtnCheck : short press
    BtnCheck->>Strobe : 3xShortPress = true

    User->>BtnCheck : short press
    BtnCheck->>Strobe : shortPress = true
    Strobe->>State2 :

    User->>"Off" : switch off

Requirements:

A flashlight finite state machine - January 24, 2026 - chad r. frost