Anduril turns flashlight firmware into a finite state machine you can read
Anduril 2 Flashlight Firmware and FSM UI Toolkit
At a glance
- What is it?
- Anduril is GPL-3.0 firmware for flashlights, written with FSM, a user interface toolkit where every light behaviour is a state in a flowchart turned into executable code. It suits owners of Anduril compatible lights who want to change the interface rather than just press the button.
- Who is it for?
- Adopt Anduril if you own a light that runs Anduril or Anduril compatible firmware and want to change what the buttons do, how the brightness steps behave or what the interface looks like, and you are comfortable with an embedded C toolchain.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 33 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What FSM means and why a flashlight interface is a state machine
Anduril is described as a user interface for flashlights, written with FSM, and the project explains the acronym twice over, because both readings matter. The SM stands for Spaghetti Monster, and the F can be any F word you like, such as Flashlight. FSM also means Finite State Machine, which is the type of abstraction used for defining user interfaces, described as a flowchart turned into executable code.
That second meaning is the whole design. A flashlight interface is naturally a set of modes and transitions. Click turns it on. Hold changes brightness. The behaviour of a long press depends on which mode you are in, whether the light is on or off, and whether the battery state matters. Writing that as a state machine means each mode is a state, each gesture is a transition, and the resulting behaviour can be read as a graph rather than inferred from nested conditionals in a timer interrupt.
The user-facing consequence is described with admirable brevity. The project says Anduril has many features, but the only things a person really needs to know are that clicking toggles on and off, and holding changes brightness. Everything else, the channel switching, the modes, the lockout, the custom user interfaces, is there for the person who wants it and does not get in the way of the person who does not.
The repository layout matches the abstraction. There is an fsm/ directory holding the state machine toolkit, a ui/ directory for the user interface definitions, hw/ directories for hardware models, arch/ for architecture specific code, lib/ for libraries, bin/ for built binaries, docs/ for documentation including the user manual and a per user configuration guide, and a make script at the root. The project is GPL-3.0 licensed, is not archived, and the last push was on 2026-09-20, with dated releases in August and September 2026.
Flashing the firmware, and choosing the right adapter
Flashing is the step that decides whether you can customise your light at all, and the documentation is specific about what you need. The first requirement is a firmware hex file, and there is a separate document on how to find the right one. The second is a flashing adapter whose type depends on the MCU chip in your light. It may be a UPDI 3-pin adapter, used for the attiny1616 and newer, or an AVR ISP 6-pin adapter, used with the attiny85 and the attiny1634.
The physical difference matters because UPDI typically uses a pogo pin adapter with spring loaded pins that hold against copper pads on the driver circuit. AVR ISP typically has two parts, a USB device such as a USBASP and a physical adapter such as a pogo pin adapter or a SOIC8 clip. The documentation notes that SOIC8 is the least convenient and is mostly only used on old models with attiny85 chips.
Third, you need a flashing program. The project names avrdude, pymcuprog and ZFlasher as compatible options, and points to a guide at anduril.click for the general walkthrough. avrdude is the recommended one in most cases and installs with a single command, `sudo apt install avrdude`. pymcuprog is the one to use for 3-pin UPDI MCUs when avrdude 7.0 or newer is not available, and it needs a Python virtual environment of its own:
sudo apt install python3 python3-pip python3-venv
python3 -m venv .venv
source .venv/bin/activate
pip3 install pymcuprogThe activation lasts until the shell is closed or until you run deactivate, so you need to source the environment every time you start a fresh shell if you want to use pymcuprog. Finally, you need a computer or a phone, and the documentation is relaxed about which, saying almost any modern one will do as long as you can plug the adapter in and run a flashing program.
The one piece of advice worth repeating is the hex file selection. Anduril supports many lights and many of them look alike from outside, and flashing the wrong hex is the way people brick a light. The hw/ directories exist precisely for this, and the documentation tells you to browse into them to find your hardware model and any hardware specific documentation, and it also points out that features like the channel modes on multi channel lights differ by model.
Once flashed, the base behaviour is the click for on and off and hold for brightness, and the user manual in docs/anduril-manual.md covers the rest.
Compiling from source, with the AVR toolchain
The project encourages deep customisation by modifying the firmware and compiling your own versions, and it says so directly. The recommendation is to use a Linux computer, ideally Debian or Ubuntu, with the note that almost any distribution should work, and that virtual machines work well, with WSL inside Windows given as an example. A Docker container is mentioned as an option, though the link to it is still marked as a to-do in the documentation.
The prerequisites are three sets of packages. The AVR toolchain itself, installed with `sudo apt install gcc-avr avr-libc binutils-avr`, and then some miscellaneous tools with `sudo apt install git wget unzip bash`. And then the Atmel Device Family Packs, which the project handles for you with a small included script run as ./make dfp. That script downloads and installs the DFPs, which are the chip definitions the compiler needs, and doing it by hand is a common source of confusion for people new to AVR development.
The build itself uses a make script included in the repository rather than a conventional Makefile. Running ./make --help gives details about how to use it, and in most cases you can just run ./make by itself to compile all available build targets. You can also give it a search term to limit builds, and the documented example is ./make hank boost, which builds all firmwares for Hanklights with optional boost drivers. The compiled output goes into the hex/ directory, ready for any flashing program.
The Makefile at the repository root is a thin wrapper around that script, and its own comments explain why. It execs ./make with the arguments, and the comment at the top notes that it does not pass args in the form of a dash-prefixed flag or a variable assignment, because make does not put those into the goal list, and that the wrapper is still helpful for people who forget the ./ prefix. The all target simply runs ./make, and a catch-all pattern target passes everything else through.
Per user configuration, so your settings survive an update
This is the feature that makes the project pleasant to work with over time, and it is small enough to describe in a sentence. The build can be customised per user by placing overrides into a users/ directory named after you and letting the build script know your username. Your favourite settings then apply automatically, without modifying the original source files.
The reason this matters is the update cycle. Firmware like this moves: there were dated releases in August and September 2026, and the ChangeLog at the root tracks what changed. If your customisations were edits to the source tree, every update becomes a merge, and merges of behaviour code are exactly the kind of thing that goes wrong quietly. With per user overrides separated from the originals, an update is a pull and a rebuild, and your settings come back because they live in their own place.
The documentation is split the way you would expect from a project with this structure. There is a user manual for the in depth use of the interface, a ChangeLog for recent changes, a document on finding the right hex file for your light, and a per user configuration document. On top of those, the hw/ directories carry hardware specific documentation per model, because the channel modes on a multi channel light are not the same across models.
Contribution is handled in the usual open source ways plus one unusual one. Beyond pull requests or patches, which can be code, documentation, tools or anything useful, and bug reports, and answering questions on public forums, the project asks you to ask manufacturers to use this firmware and to support its development. There is also a Patreon site for donations, framed as helping to keep the lights on. That last request is a fair signal about the shape of the project, which is one maintainer coordinating contributions from a wide user base across many models.
Where Anduril is the wrong answer
The first limitation is that this is firmware for hardware that already supports it, and the hardware list is not full in the sense of covering everything. Anduril is a family of lights with many clones and many variants, and the support is per model. If your light runs a different firmware ecosystem, no amount of compiling will help, and the hw/ directory lookup is the gate on that. The documentation also points out that the SOIC8 clip route is mostly only used on old models with attiny85 chips, which tells you this is a project that has followed specific hardware generations rather than a general one.
The second limitation is the toolchain cost for a small task. If all you want is to change one behaviour, for example swap the brightness levels, there is a much cheaper path. Many of these lights have a companion configuration tool or a third party configurator that edits settings through the light's own menu over USB, which requires no compiler at all. The cost of Anduril is only justified when the thing you want to change is not expressible in the stock interface, or when you want to add a behaviour rather than tune an existing one.
The third is the Linux build requirement. The documentation strongly recommends a Linux computer for compiling, mentions Windows through WSL and notes a Docker container is intended, and the container link is still a to-do in the documentation. So on Windows you are relying on WSL or on building the container yourself, and on macOS you are on your own. That is a real friction point for a hobby project, though a small one for anyone already comfortable with embedded toolchains.
The realistic alternative for the same goal, if you want a firmware whose behaviour you define, is writing your own state machine in plain C for a bare metal MCU without a framework layer. Anduril gives you a battle tested framework, a large body of hardware specific work already done, and a build system that produces the right hex for many models. Hand rolling gives you total control and total responsibility for every model's quirks. The difference in approach is toolkit versus toolkit: Anduril is the flashlight equivalent of using a UI framework instead of drawing every pixel, and it wins when your hardware is on its list.
Editorial conclusion
Adopt Anduril if you own a light that runs Anduril or Anduril compatible firmware and want to change what the buttons do, how the brightness steps behave or what the interface looks like, and you are comfortable with an embedded C toolchain. Do not adopt it if you only want a better flashlight from a shop, since there is ready made firmware for that, and do not expect it to cover hardware it does not list, because the channel behaviour and supported features are model specific. Before you compile anything, read the guide to finding the right hex file and check the hw/ directory for your model, and confirm you have the right adapter type for your MCU before ordering hardware.
Frequently asked questions
What is FSM in the Anduril project?
FSM is the UI toolkit Anduril is written with, and the project gives the acronym two readings. The SM stands for Spaghetti Monster with the F being any F word, while FSM also means Finite State Machine, which is the abstraction used for the user interfaces, described as a flowchart turned into executable code.
How do I flash Anduril firmware onto a flashlight?
You need the correct firmware hex file, a flashing adapter matched to your MCU (a UPDI 3-pin adapter for the attiny1616 and newer, or an AVR ISP 6-pin adapter for the attiny85 and attiny1634), a flashing program such as avrdude, pymcuprog or ZFlasher, and a computer or phone to run it. The documentation points to a guide at anduril.click and a separate document on finding the right hex file.
How do I compile the Anduril firmware myself?
On a Linux machine, install the AVR toolchain packages with `sudo apt install gcc-avr avr-libc binutils-avr` and the other tools with `sudo apt install git wget unzip bash`, then run the included `./make dfp` script to install the Atmel Device Family Packs. Run `./make` to compile all build targets, or pass search terms such as `./make hank boost` to limit them, and the output lands in the hex/ directory.
How do I keep my custom settings when the firmware updates?
Place your overrides in a users/ directory named after you and let the build script know your username. The documentation explains the per user configuration approach in docs/per-user-config.md, and it means your settings apply automatically without editing the original source files.
Is Anduril actively developed and under what licence?
The repository is not archived and the last push was on 2026-09-20, with dated releases in August and September 2026 and a ChangeLog at the root. The firmware is GPL-3.0 licensed, and the project encourages people to ask manufacturers to use it and support its development.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/toykeeper-anduril)Was this useful?