LuxLibre

LuxLibre › Documentation › Testing a flashlight

Testing a flashlight

On this page: Overview · Equipment · Bring-up of a new board · Firmware tests · Output and runtime · Intensity and beam distance · Thermal and touch temperature · Battery and charging · Flicker · Durability · Optical safety · Writing the report

This guide takes a LuxLibre light from the first power-up of a new board to the numbers you publish. Every procedure works with a small budget. Each section ends with a short note on what a professional lab does differently, so you know where your numbers stop being exact.

Rule IDs such as THM-1 point to the design rules. Numbers from standards carry their source. Numbers marked “LuxLibre rule”, “LuxLibre default” or “LuxLibre suggestion” are project choices, not standards.

Safety while testing

Read SAFETY.md before you start.

Overview

A light is tested in six stages. Stages (a) to (c) happen for every new board. Stages (d) and (e) happen for every hardware release. Stage (f) collects the results.

  1. (a) Bench bring-up of a new board: is it assembled correctly and safe to power?
  2. (b) Firmware in the simulator: does the code do what it should with this board’s settings?
  3. (c) Firmware on the board: do the gestures and protections work on real hardware?
  4. (d) Performance rating in the ANSI/PLATO FL 1 style (REQ-2): output, runtime, intensity, beam distance.
  5. (e) Safety and durability: touch temperature, battery and charging, flicker, drop, water, optical safety.
  6. (f) Release test report from templates/test-report.md.

The times below are rough LuxLibre estimates for a first pass by one person.

Test What it proves Rule IDs Equipment Time needed
Bench bring-up Board assembled right, outputs off by default, readings calibrated, standby drain known DRV-7, DRV-9, FW-1, BAT-9, BAT-6, DRV-2, REQ-4 Multimeter, current-limited supply, programmer 2-4 h
Firmware in the simulator Code and board parameters behave as intended FW-8, FW-2, FW-5 PC Minutes (CI); 1 h for a new board header
Firmware on the board Gestures and protections work on hardware FW-3, FW-6, BAT-5, BAT-7, THM-5, DRV-8 Supply, multimeter, USB console 2-3 h
Output and runtime Lumens at 30 s and 2 min, runtime to 10 %, sustained output REQ-2 Lumen tube, lux meter, reference light Half a day to a day (one full runtime per mode)
Intensity and beam distance Peak intensity (cd) and beam distance REQ-2 Lux meter, tape measure, dark corridor 1 h
Thermal and touch temperature Hottest touchable point stays within the burn limits THM-1, THM-4, THM-6 Thermocouple meter 3-4 h
Battery and charging Charge voltage and current, temperature window, USB-C, reversed cell BAT-4, BAT-5, CHG-1, CHG-2, CHG-3, CHG-6 USB power meter, multimeter, supply, cables 3-5 h (one full charge)
Flicker No visible flicker at any level LED-6, FW-4 Phone camera; photodiode + oscilloscope 1 h
Durability Survives drops, then water MEC-2, MEC-3 Concrete floor, water tube 2 h
Optical safety LED risk group known, laser class verified, interlock works LED-5, LAS-1, LAS-2, LAS-3 Datasheets; laser power meter 1-2 h
Release test report Every requirement has a result REQ-1, REQ-4, FW-8 Template 1-2 h

Equipment

Budget kit

Item Used for Notes
Multimeter with a µA range Rail resistance, voltages, LED current, standby current Note its accuracy on the voltage range: BAT-9 needs 1 %, so the meter must be better than that.
Bench power supply with current limit First power-up, LVP test, reversed-cell test Most cheap supplies cannot sink current: do not let a charger push current into them (see Battery and charging).
USB power meter (inline, USB-C) Charge current, charge energy, termination Measures on the USB side, so it includes the charger’s losses.
Thermocouple meter (type K) with thin-wire probes Touch temperature, reference for the NTC calibration Check it in ice water: it should read 0 °C.
Lux meter Lumen tube, intensity at a distance Check it against a second meter if you can.
Home-made lumen tube Relative output and runtime Calibrate it against a light with a published measured output (see Output and runtime).
Phone camera Quick flicker check, photos for the report A video at a fast shutter speed shows PWM as stripes.
Kitchen scale Weight for the spec sheet  
Tape measure, foil or polyimide tape Distances, fixing thermocouples  
Bucket or a capped tube taller than 1 m IPX7 test The lowest point of the light must be 1 m under water.
Programmer Flashing the MCU UPDI, WCH-LinkE (SWIO) or plain USB, see docs/firmware/README.md.

Better tools

Tool What it adds
µA logger (source-measure unit or power profiler) Standby current with its wake-up spikes, without burden-voltage problems; a source-measure unit can also replace the cell and sink charge current.
Integrating sphere Absolute lumens instead of relative tube readings.
Photodiode + oscilloscope Flicker waveform, frequency and modulation depth.
Laser power meter The real laser output for the class check (LAS-3).
Thermal camera Finds the hottest touchable point in one look.
Climate chamber A controlled 25 °C for thermal tests; cold and hot tests of the charge window.

Bring-up of a new board

Do these steps in order. Stop at the first failure and fix it before you go on.

  1. Visual inspection. Under a magnifier, check solder bridges (especially on fine-pitch ICs and USB-C pins), part rotation and polarity (LED, diodes, cell connector, MCU pin 1), and missing parts. Compare with the assembly drawing.
  2. Resistance checks. With nothing connected, measure from each supply rail (battery +, VBUS, the MCU supply) to ground. A reading near 0 Ω means a short. A reading that climbs slowly is normal: the capacitors are charging from the meter. Compare with a known-good board when you have one.
  3. First power from a current-limited supply. Set the supply to the nominal cell voltage and the current limit low: LuxLibre suggests 100 mA. Why low: a solder bridge or a reversed part then only gets warm instead of burning, and an unprogrammed board with all outputs off should draw far less than that. If the supply sits at its current limit, switch off and look for the short. Touch-check (carefully) for parts that warm up.
  4. Default-off check (DRV-7, FW-1). With a blank MCU, and again while you hold the MCU in reset (for example during programming), measure the LED driver enable and the laser gate at the pins: both must be low, and the LED must be dark. On laser boards do this with the interlock armed, because that is the worst case. A status LED may blink at boot (on the FlashKa, the red LED shares the ESP32-C3 boot-log pin); that is not a main output.
  5. Program the MCU over UPDI, SWIO or USB as described in docs/firmware/README.md. Raise the current limit step by step now that the firmware controls the outputs.
  6. Read ver and status on boards with a console. ver must print the firmware version and the board name, for example LuxLibre 0.5.0 / FlashKa Keychain v0.6 (REQ-4). Write it into the report.
  7. Battery voltage calibration (BAT-9). Measure the voltage at the cell terminals with the multimeter at the same moment you read cell_mV from status, with the light off. Set BAT_CAL to the current value plus (multimeter - cell_mV) and save. Repeat at a low and a high voltage (for example 3.0 V and 4.2 V from the supply) to see whether the error is only an offset. Pass: within 1 % at both ends.
  8. Standby current (BAT-6, DRV-3). See the procedure below.
  9. LED current per level (DRV-2). Use level N for a set of levels (for example 1, 30, 60, 90, 120, 150) and measure the LED current. For low levels put the meter’s mA range in series with the LED. For high levels measure the voltage across the sense resistor at its test point and divide by its value: a series ammeter adds resistance and changes the result. Compare with the table in docs/firmware/user-interface.md and your board header (LX_MAIN_MAX_MA, LX_OUT_MIN_Q16). Keep high levels short when the LED is not yet in its housing: a bare LED board overheats in seconds.

On boards where the console runs over USB (the FlashKa), the USB cable is also a charger connection. While it is plugged in the main LED is limited to CHG_MAXLVL (CHG-6) and the light does not sleep. For the LED current test, set CHG_MAXLVL 150 temporarily and put it back afterwards. Do not power such a board from a bench supply in place of the cell while USB is connected unless the supply can sink current: the charger would push current into it.

Measuring standby current without resetting the MCU

A multimeter on its µA range puts a shunt resistor in series. The voltage across it (the burden voltage) is shunt resistance times current. When the MCU wakes up, the current jumps, the burden voltage jumps with it, and the MCU can brown out and reset. The trick is to bypass the meter while the current is high.

  1. Disconnect USB. The firmware does not sleep while USB is present or within 30 s of the last console input.
  2. Put the meter in series with the negative cell lead, at the cell side so that the protection circuit and charger leakage are included. Put a jumper wire or a switch across the meter.
  3. Power up with the jumper closed. Switch the light off (and, as a second case, lock it) and wait at least a minute.
  4. Open the jumper and read. If the light blinks, the reading jumps or the MCU resets, the burden is too high: use the next higher range, or a shunt resistor with a mV reading (100 Ω gives 1 mV per 10 µA). Close the jumper before you press the button again.
  5. The MCU wakes up briefly from time to time, so the meter shows an average that wanders. Write down the typical value. A µA logger shows the spikes and gives the true average.

Compare with BAT-6: at most 3 % of the capacity per month, which is 33 µA for 800 mAh and 123 µA for 3000 mAh (a month is about 730 h). For reference, the ESP32-C3-MINI-1 module alone needs 5 µA in deep sleep (Espressif), so the rest of the board has to stay well below the limit as well.

What a lab does differently: an X-ray of leadless parts instead of a visual check, a source-measure unit for standby current, and a calibrated reference for voltage.

Firmware tests

In CI and in the simulator

make test in firmware/ runs the unit and behaviour tests on the PC. Every change must pass it in CI (FW-8). The behaviour tests cover lockout across a reboot, the stuck button, LVP, thermal regulation without flicker, sensor faults and the charge window.

A new board header (FW-2) is first checked in the simulator. Run the scenarios from docs/firmware/simulator.md with the board’s limits, for example:

cd firmware
make sim
build/luxsim --preset 18650 --set THM_LIMIT=50 --csv turbo.csv "2C W600000"

Check that thermal regulation settles, turbo steps down after TURBO_S, and LVP ends in a cut-off.

On the board: gesture checklist

The button map is in docs/firmware/user-interface.md. Use the layout your board sets with UI_STYLE.

Gesture Expected Rule
1C from off, 1C again On at the remembered level, then off FW-3
Hold from off Moon, then brighter (ramp layout) or the next mode (modes layout) FW-3
2C Turbo; steps down to TURBO_DOWN after TURBO_S; 2C again returns to the previous level FW-3
3C Battery voltage as blinks (3.8 V = 3 blinks, pause, 8 blinks); compare with the multimeter FW-3
4C Lockout (3 blinks of the main LED, or the lock colour on boards with an indicator LED). Clicks give only a short flash; hold gives moon only if LOCK_MOON = 1. 4C unlocks. BAT-7
4C, then remove the cell (or reboot, or switch off the supply), reconnect Still locked FW-6
9C 5 blinks of the main LED (or the reset colour on boards with an indicator LED); all parameters back to defaults except the calibration (BAT_CAL, THM_OFFSET) FW-5
Laser gesture (click, then click-and-hold) in lockout No laser LAS-2

The factory reset keeps the calibration values BAT_CAL and THM_OFFSET; they are also stored in their own block, so they survive a firmware update that changes the parameter list. The console command defaults all clears them as well.

On the board: protections

What a lab does differently: automated button actuators and a programmable supply run the same sequences hundreds of times and log every transition.

Output and runtime

REQ-2 asks for ratings in the ANSI/PLATO FL 1 way. FL 1 measures the output in an integrating sphere between 30 s and 2 min after switch-on, and the runtime from the 30 s value until the output falls to 10 % of it (Lupine, Streamlight). LuxLibre adds the sustained output after 10 min.

Why the 30 s value matters

Many lights start bright and step down within seconds. Measured examples from 1Lumen:

Light Claimed (lm) At switch-on (lm) At 30 s (lm) 30 s as % of claim
TS10 1400 1454 129 9 %
SC31T Pro 2210 1581 886 40 %
TS25 (50 °C limit) 4000 3616 701 18 %

A rating at switch-on hides this. Always publish the 30 s value.

The 2025 edition of FL 1 adds a test for short-duration elevated brightness (turbo), dust ratings and a stopwatch icon, and widens the scope to area lights and spotlights (Business Wire). The details of the turbo test are not public. Until they are, LuxLibre suggests publishing the output at switch-on and the time until turbo steps down, clearly labelled as not the FL 1 method.

Lumen tube method

A lumen tube is a light-tight tube, white inside, with a diffuser and a lux meter sensor at a fixed port. The lux reading is proportional to the light that enters the tube.

  1. Calibrate with a reference light that has a published measured output (sphere measurement, not the maker’s claim), in the same state as in the measurement (fully charged cell, same mode, read at 30 s). Factor k = published lumens / tube lux.
  2. Use a reference with a similar beam and colour temperature to your light, because the tube and the lux meter respond differently to different beams and spectra. Check k with a second reference light if you have one.
  3. Uncertainty. The result is relative to the reference. With careful calibration, expect roughly 10-20 % (a rough LuxLibre estimate, not a measured value).
  4. Measure each mode with a fully charged cell at 25 °C ambient (LuxLibre choice, the same as the thermal test): switch on, read at 30 s and at 2 min, then log every 30 s until the output is below 10 % of the 30 s value or the light switches off. Record runtime from the 30 s point.
  5. Write the log as CSV with the columns t_s,lumens,T_sensor_C. Fill T_sensor_C with temp_dC / 10 from status, or, without a console, with a thermocouple reading on the head (and say so in the report). Then plot it next to the simulator prediction with firmware/tools/plot_sim.py (--title and --xlabel change the labels for other kinds of runs):
cd firmware
build/luxsim --preset 18650 --csv sim.csv "2C W7200000"
python3 tools/plot_sim.py turbo.png measured.csv:"Measured" sim.csv:"Simulator" --limit 50

A large difference between measurement and simulator means the thermal model or the board header is wrong (THM-3); fix the model before you publish.

What a lab does differently: an integrating sphere calibrated with standard lamps, a spectroradiometer for colour temperature and CRI, a controlled 25 °C, and several samples per model.

Intensity and beam distance

Peak intensity is the light per solid angle in the brightest part of the beam, in candela (cd). FL 1 measures the illuminance (lux) at 2, 10 or 30 m and computes cd = lux × d²; the beam distance is the distance at which the illuminance falls to 0.25 lx, which is 2 √cd metres (Lupine).

  1. Use a dark corridor or a field at night. Measure at 5 m or more (LuxLibre suggestion for a home setup; the beam must have formed).
  2. Fix the light, switch on, wait 30 s (same rule as output), and move the lux meter until you find the highest reading.
  3. Subtract the reading with the light off (stray light).
  4. Compute cd = lux × d² and beam distance = 2 √cd. Example: 50 lx at 5 m gives 1250 cd and a beam distance of about 71 m. tools/lux_calc.py throw does this arithmetic; run it with --help for its arguments.

What a lab does differently: a goniophotometer measures the whole beam pattern, not only the peak, at the distances the standard sets.

Thermal and touch temperature

This section verifies THM-1 with the procedure of THM-6 and calibrates the sensor (THM-4).

Burn thresholds

ISO 13732-1 burn thresholds for touching a hot surface, in °C:

Contact time Metal Plastic
1 s 65 85
10 s 55 70
1 min 51 60
10 min 48 48
8 h 43 43

Sources: 1 min to 8 h from CENELEC Guide 29 Table A.1 (CENELEC); 1 s and 10 s from EN 13202 via IEEE PSTC slides (IEEE PSTC).

Pass criteria (THM-1): the hottest touchable surface stays at or below 48 °C in continuous use and never exceeds 51 °C (metal).

Setup

Procedure

  1. Calibrate THM_OFFSET. Leave the light off (and not charging) for 1 h next to the reference thermocouple so that everything is at room temperature. set THM_OFFSET 0, read temp_dC, then set THM_OFFSET to the reference minus temp_dC / 10, rounded, and save. The charge window uses the same reading, so the offset must make the sensor read the true temperature.
  2. Each mode for 10 min, starting cold each time. Record the highest surface value.
  3. Turbo until regulated: run turbo (with set TURBO_S 0 if you want to see the thermal regulator alone) until the level and temperatures are steady.
  4. Set THM_LIMIT. At steady state, the sensor reads hotter than the surface by a difference Δ = sensor - surface. Take the smallest Δ you measured and set THM_LIMIT to 48 + Δ, rounded down (allowed range 30-70 °C). Repeat step 3 and check that the surface stays at or below 48 °C and never above 51 °C, including the overshoot when turbo starts.
  5. Put TURBO_S back to its board default and save.

What a lab does differently: a climate chamber at exactly 25 °C, several thermocouples logged at once, a thermal camera with a known emissivity setting, and the measurement conditions of the product safety standard.

Battery and charging

Never charge a light that failed the water test or has a damaged cell.

What a lab does differently: a battery cycler logs charge and discharge curves over many cycles, and a climate chamber tests the charge window at the real limits, cold and hot.

Flicker

Flicker is the periodic change of light output, for example from PWM (pulse-width modulation: switching the LED on and off fast). LED-6 and FW-4 require constant current or PWM at 3 kHz or more (LuxLibre rule).

  1. Quick check with a phone camera. Film the lit wall at a fast shutter speed (or use the slow-motion mode). Dark stripes rolling through the picture mean PWM. No stripes is only a hint, not a proof.
  2. Photodiode and oscilloscope. Point the light at a photodiode with a load resistor (keep it out of saturation) and record the waveform. Read the frequency f and the maximum and minimum, Lmax and Lmin.
  3. Compute the modulation depth: Mod% = 100 (Lmax - Lmin) / (Lmax + Lmin).
  4. Test at the lowest level, a middle level, the highest level, and during thermal regulation (the level changes in small steps; it must not flicker, FW-4). The lowest level is often the worst case.
  5. Compare with IEEE 1789-2015 (table below). Pass for LuxLibre: inside the NOEL region at every tested level.

IEEE 1789-2015 limits (standard copy), f = flicker frequency in Hz:

Region Below 90 Hz From 90 Hz up to the limit No limit from
Low risk Mod% < 0.025 f Mod% < 0.08 f (up to 1250 Hz) 1250 Hz
No observable effect (NOEL) Mod% < 0.01 f Mod% < 0.0333 f (up to 3000 Hz) 3000 Hz

Example: at 1000 Hz, NOEL allows Mod% < 33.3 %. IEEE has listed 1789 as “Inactive-Reserved” since 26 March 2026 (IEEE): it is no longer maintained, but it remains the common reference, and LuxLibre keeps its NOEL region as the target (LuxLibre choice).

What a lab does differently: a calibrated flicker meter that also reports the flicker index and stroboscopic visibility measures.

Durability

Do the drop test first and the water test after it, as FL 1 requires (Lupine).

What a lab does differently: a drop rig with a defined release and orientation, a pressure chamber for IPX8, and dust tests for the new FL 1 dust ratings.

Optical safety

LED (LED-5)

IEC 62471 sorts light sources by blue-light hazard: Exempt (no hazard within 10 000 s), RG1 (no hazard within 100 s), RG2 (no hazard within 0.25 s, the eye’s aversion response), RG3 (hazardous even for a momentary exposure). Flashlights are not general lighting and are assessed at 200 mm. IEC TR 62778 gives a threshold distance; above RG1 at 200 mm, the hazard distance is marked on the product. IEC 62471-7:2023 is the newer part for visible products. (Secondary source; check the standard text before you claim a group.)

Without a lab, a maker can:

Laser (LAS-1 to LAS-3)

IEC 60825-1 classes for visible lasers: Class 2 ≤ 1 mW continuous; Class 3R ≤ 5 mW; EN 50689 allows only Class 1, 2 or restricted 3R in consumer products, and only Class 1 in products that appeal to children (UK government, UL).

  1. Never look into the beam. Remove watches and rings, keep mirrors and shiny tools away, aim only at the power meter sensor or a matte wall, and wear laser safety glasses rated for the wavelength.
  2. Measure the power (LAS-3). Put the whole beam on the sensor of a laser power meter set to the laser’s wavelength. Measure with a full cell, at the start and at the end of a LASER_S emission. The seller’s label is not a measurement. The whole-beam value is at least as high as the value under the aperture conditions of IEC 60825-1, so it is a conservative check.
  3. Interlock (LAS-2). With the hardware interlock open (on the FlashKa, the slide switch S2), do the laser gesture: the MCU laser pin goes high (measure it) but there must be no emission. With the interlock armed: emission only with the deliberate gesture, the emission indicator lights, and the firmware refuses in lockout, above LASER_TMAX and below LASER_VMIN, and stops after LASER_S.
  4. Labels. Class label and warning per IEC 60825-1 on the product and in the manual.

What a lab does differently: a spectroradiometer and imaging radiometer for IEC 62471, and laser power and beam measurements under the exact IEC 60825-1 conditions.

Writing the report

  1. Copy templates/test-report.md and fill it in.
  2. Record the firmware version from ver, the board header (for example firmware/boards/flashka-keychain-v05/board.h), the git commit, the hardware revision on the silkscreen (REQ-4), and every parameter you changed from the default (list prints them all).
  3. Keep the raw data with the report: CSV logs, oscilloscope screenshots, photos, and the calibration values (BAT_CAL, THM_OFFSET, the lumen tube factor and its reference).
  4. Link the report from the hardware folder README, for example hardware/flashka-keychain-v05/README.md.
  5. A release is tested when every requirement in the requirement sheet (templates/requirements.md, REQ-1) has a result: pass, fail, or not tested with the reason. Every board release needs this report (FW-8).