Prove the dose curve and the recorder; document S-means-light

The stream harness gains rule 19: with the bench-default curve in force
a ladder of S rungs renders the curve's densities exactly (half light
lands near 80 percent density), monotonic, floored and ceiled by
$35/$36; every other session pins laser_dose_curve = off so its
S-to-level arithmetic stays exact, and the arm-report checks carry the
curve name. The lifecycle harness asserts the published state file
names the curve in force. The catalog's forgectrl.panel-serves asserts
the curve field in the grbl report, /curve/status and the ladder
G-code, and its covers name the recorder.

BRINGUP describes S-commands-light through the measured curve and the
owner recorder; the MOTION table gains laser_dose_curve; LIGHTBURN
tells the operator power now means light and how to record their own
tube's curve from the panel.
This commit is contained in:
ScottW514
2026-08-30 20:19:24 -04:00
parent 557ed02590
commit 0b941fd743
6 changed files with 187 additions and 21 deletions
+20 -10
View File
@@ -238,16 +238,26 @@ spot. The arm report names it (`laser armed (density, floor 10 %)`), and
a floor of 0 is honored with a note (the ladders run that way). The
cooling report carries the model with the job state.
**Measured dose response (this bench, 2026-08-30, by the head thermopile,
the tube current and the operator's eye on Thick Draftboard and acrylic).**
Density delivers about half of the CW light at 80 % density, a third at
60 %, a fifth at 45 % and a fourteenth at 30 %: the curve is the tube's
(pulsed against CW), not the sensor's, and it is the same physics behind
the factory's 18.9 to 79.5 % mapping with Full Power kept apart. An S
correction from that curve (E4 in the working file) is the open item that
follows. Rasters hold their tonality down to ~14 pulse slots per pixel
(508 DPI at 6000 mm/min): the dither accumulator's cross-pixel averaging
recovers the levels, with no visible dither pattern.
**S commands light, through the measured curve.** The tube's output is
convex in pulse density (this bench, 2026-08-30, by the head thermopile,
the tube current and the operator's eye: 80 % density delivers about
half the CW light, 60 % a third, 45 % a fifth, 30 % a fourteenth - the
same physics behind the factory's 18.9 to 79.5 % mapping with Full
Power kept apart). So the driver maps the commanded fraction through
the measured curve's inverse onto the density that delivers it:
`laser_dose_curve` in the machine config holds density:light percent
pairs, ships with the bench-measured default compiled in, accepts
`off` for the identity, falls back loudly on a bad value, and is
reloaded at every precompute with the arm naming it (`laser armed
(density, floor 10 %, curve bench-default)`). `$35`/`$36` still floor
and ceil the result. An owner measures their own curve from the panel:
the dose-curve recorder hands them a ladder G-code to run from their
sender - every arm gate stands, forgectrl records the tube current and
the head thermopile passively, fits the rungs, and Apply writes the
result (`forgectrl/docs/SERVICES.md`). Rasters hold their tonality down
to ~14 pulse slots per pixel (508 DPI at 6000 mm/min): the dither
accumulator's cross-pixel averaging recovers the levels, with no
visible dither pattern.
An S word takes effect whether or not motion is in progress. Per-segment
updates carry the level inside a laser block, but an S executed between
+10 -6
View File
@@ -152,12 +152,16 @@ restart the controller with the head re-parked.)
The controller drives the tube the way the factory does: every pulse
fires at full power, and the power setting decides how many ticks of
each 710 us period fire. Every power level marks, low levels included,
because no pulse is ever too weak to strike. The response is not linear:
on this machine 80 % gives about half the light of 100 %, 60 % about a
third, 30 % about a fourteenth - so pick engrave power by test card, and
prefer setting darkness with speed. Grayscale images fade cleanly into
the shadows (a low level becomes sparse full-power pulses), and 254 to
508 DPI rasters hold their tonal steps.
because no pulse is ever too weak to strike. The raw response is not
linear - 80 % of the pulses deliver about half the light - so the
controller maps your power setting through a measured dose curve: 50 %
commands half the light, not half the pulses. The machine ships with
the bench-measured curve; record your own tube's from the control
panel (GRBL tab, "Dose-curve recorder": download the ladder file, press
Record, run the file from LightBurn on scrap, press the button, Apply
the fit). Grayscale images fade cleanly into the shadows (a low level
becomes sparse full-power pulses), and 254 to 508 DPI rasters hold
their tonal steps.
`$35`, the power floor, is set by the controller from the machine config
(the control panel's GRBL tab, "Laser dose"): do not type it, it is
+1
View File
@@ -427,6 +427,7 @@ only be changed while the machine is idle.
| `laser_button_timeout_s` | 300 | How long the machine waits at the button prompt. |
| `laser_disarm_s` | 60 | Spindle-off grace before the armed window closes. |
| `laser_floor_density` | 10 | The S-range floor, percent of full: the lowest pulse density that still marks. Loaded into `$35` at every spindle precompute; `$35` is derived, never typed. |
| `laser_dose_curve` | (bench default) | The measured dose curve as density:light percent pairs; S commands a light fraction and the driver maps it onto the density that delivers it. `off` = identity; a bad value falls back to the default. The panel's recorder measures and applies a machine's own. |
| `laser_pulse_ticks` | 20 | Density base period in machine ticks (35.5 us each). |
| `laser_pulse_min_ticks` | 3 | Shortest density pulse in ticks; below it a period is skipped and its debt carried. |
| `rail_settle_s` | 2.5 | Motor-rail off period when a controller takes the device standalone. |