mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-27 16:51:12 -07:00
Fan floors from the measurement; a hunt is measured, not judged
forgectrl pin 47e4256: the airflow floors set from the bench measurement (exhaust 6400, intake 2290, air assist 6000 rpm, purge current 300, grace 15 s) and the operating-point rule: a fan is judged while the laser is armed, when a job's profile may raise it but never lower it below the run duty, or whenever it is commanded at the run duty; the service's hunts, sent with the extraction fans off, are measured and published unjudged. Catalog: cloud.mode-switch now waits out the connect-time hunt sampling /cool/status and requires no AIRFLOW, the exhaust row unjudged and the exhaust actually off; its covers gain forgectrl src/cool.* and src/airflow.*. cooling.fan-gate-trips uses an 8 s test grace (the intakes take 7 s to 90 percent and tripped under the old 2 s at the new floor) and its off leg waits for the row state as well as gates_off. fan_floor_measure.py names a reply that is not JSON and calls the purge readings idle and run (the pump is always on). Docs: COOLING 3a and the settings table, BRINGUP item 19 and a facts-bank entry with the measured fan speeds, the bench README, and a CAMPAIGN-LOG entry for the measurement, the two status-document finds, the hunt find and the hot-deployed bench runs of both tests.
This commit is contained in:
+24
-7
@@ -623,6 +623,18 @@ until `releases/v<version>/acceptance.json` is committed.
|
||||
|
||||
## Hardware facts bank (measured)
|
||||
|
||||
- **Fan speeds at the cut profile** (exhaust duty 65535, intake 43278, air
|
||||
assist 1023; sampled at 1 Hz over 120 s from idle, the exhaust duct's
|
||||
inline booster fan off): exhaust **11640 rpm** steady (spread 11444 to
|
||||
11947, 90 percent of steady in 5 s), intakes **4157 / 4158 rpm** (spread
|
||||
under 100, 7 s), air assist **11050 rpm** (spread 30, 1 s); at idle the
|
||||
exhaust and intakes read 0 / ~745 rpm and the air assist ~1900 rpm
|
||||
(idle duty 204). The purge-air fan is always on and reads **~625 counts**
|
||||
of `head/purge_air_current` (~1 when off). The airflow floors are 55
|
||||
percent of these (bands 50 to 60 percent); an inline booster fan changes
|
||||
the exhaust's back pressure and can move its reading by a few percent
|
||||
either way, well inside the margin.
|
||||
|
||||
- **DRV8825 stepper drivers wedge on 40 V rail glitches** (factory board; the
|
||||
TMC2130s belong to the upgraded OpenGlow board only). A glitch can leave the
|
||||
drivers unserviceable: SDMA playback and the position counters run normally
|
||||
@@ -1340,13 +1352,18 @@ Open items only. Anything closed is in `CAMPAIGN-LOG.md`.
|
||||
while the run profile is applied (exhaust, intakes and air assist by
|
||||
tachometer, purge by current), a spin-up grace, three ticks under the
|
||||
floor, a fault for the rest of the session (`AIRFLOW`, no resume), a
|
||||
header window only ever raising a floor; `cooling.fan-gate-trips` in
|
||||
the catalog. The shipped floors are provisional, 55 percent of one
|
||||
run-duty snapshot (exhaust 3700, intake 1800, air assist 6000 rpm,
|
||||
purge current 300, grace 15 s) until `fan_floor_measure.py` has been
|
||||
run on the bench and the numbers in `forgectrl/src/gates.c` set from
|
||||
it. The coolant critical tier and the watch-only board temperatures
|
||||
follow.
|
||||
header window only ever raising a floor. A fan is judged at the
|
||||
operating point its floor was measured at: always while armed (when a
|
||||
job's profile may raise a fan but never lower it below the run duty),
|
||||
and unarmed whenever it is commanded at the run duty; a cloud hunt,
|
||||
sent with the extraction fans off, is measured and not judged.
|
||||
`cooling.fan-gate-trips` and the hunt leg of `cloud.mode-switch` in
|
||||
the catalog. The shipped floors are 55 percent of the bench machine's
|
||||
measured steady speeds (facts bank: exhaust 6400, intake 2290, air
|
||||
assist 6000 rpm, purge current 300, grace 15 s); the bench run of the
|
||||
gate tests on an image carrying them, and the unplugged-tach drill,
|
||||
are still owed. The coolant critical tier and the watch-only board
|
||||
temperatures follow.
|
||||
|
||||
Nothing here can put energy where it was not commanded: the hardware chain
|
||||
is the emission boundary and no header field touches it, and forgectrl runs
|
||||
|
||||
@@ -3254,6 +3254,60 @@ value), and the test quoted the session's first job-limits line, a hunt's,
|
||||
where the print's is the one worth keeping (it now takes the first line
|
||||
after the print's action request).
|
||||
|
||||
## 2026-08-22: the fan floors measured, and a hunt that would have tripped them
|
||||
|
||||
`fan_floor_measure.py spinup` (bench page `fan-floor`, 120 s at the cut
|
||||
profile from idle, GRBL mode, the exhaust duct's inline booster fan off, so
|
||||
the exhaust worked against more back pressure than a normal cut):
|
||||
|
||||
| fan | steady rpm | min | max | sd | t90 |
|
||||
|---|---|---|---|---|---|
|
||||
| exhaust | 11638 | 11444 | 11947 | 103 | 5 s |
|
||||
| intake 1 | 4157 | 4102 | 4193 | 12 | 7 s |
|
||||
| intake 2 | 4158 | 4128 | 4173 | 6 | 7 s |
|
||||
| air assist | 11048 | 11029 | 11061 | 8 | 1 s |
|
||||
|
||||
Purge current 627 at idle and 625 at run duty: the engine holds purge air on
|
||||
continuously, so both are the "on" reading (the off reading, ~1, is from an
|
||||
earlier observation). The floors shipped from this: exhaust 6400, intake
|
||||
2290, air assist 6000 rpm (55 percent of steady, bands 50 to 60 percent),
|
||||
purge current 300, grace 15 s (twice the slowest time to 90 percent). The
|
||||
provisional floors had come from a snapshot at a lower exhaust speed; the
|
||||
measured margin is larger.
|
||||
|
||||
The run also sent the first `/cool/status` with the limits and the fan rows
|
||||
through a 512-byte reply buffer, and then a 160-byte limits fragment: twice
|
||||
a cut-off document, found by the measurement tool refusing to parse it.
|
||||
Both fixed in forgectrl with a host test that renders the widest legal
|
||||
document and parses it (`tests/coolfmt_test.c`).
|
||||
|
||||
Reading the measurement through cloud mode found a defect in the gates as
|
||||
first built: the service reports every action as a run, and its hunt and
|
||||
motion headers command the exhaust and the intakes off and the air assist
|
||||
at idle, so a hunt longer than the grace would have tripped `AIRFLOW` at
|
||||
any floor. Decision (operator): a fan is judged only at the operating
|
||||
point its floor was measured at: always while the laser is armed, when a
|
||||
job's profile may raise a fan but never lower it below the run duty; and
|
||||
unarmed when commanded at the run duty. A hunt is measured, published as
|
||||
`unjudged`, and not judged. `cloud.mode-switch` now watches the connect-time
|
||||
hunt's gate rows for it.
|
||||
|
||||
Both tests ran the same day on a hot-deployed forgectrl (the working tree
|
||||
cross-built and installed over dev image `20260821230723`; informational,
|
||||
not acceptance). `cloud.mode-switch` PASS: the hunt reported two run ticks
|
||||
with the exhaust off and `unjudged`, verdict `OK` throughout.
|
||||
`cooling.fan-gate-trips` FAIL first, for two reasons worth keeping: the
|
||||
run-start tick resolved the effective limits before it reloaded the
|
||||
settings, so for one tick `gates_off` named the exhaust while its row still
|
||||
carried the old floor (fixed: the session start re-resolves the limits after
|
||||
the reload, so rows, `gates_off` and the log line agree); and the test's
|
||||
2 s grace, chosen against the provisional 1800 rpm intake floor, now let
|
||||
both intakes trip at ~1850 rpm on their 7 s spin-up (the test grace is 8 s).
|
||||
Rerun PASS in 59 s: only the exhaust tripped in the exhaust leg, only the
|
||||
purge in the purge leg, the exhaust read `off` with floor 0 in the off leg,
|
||||
and the restore showed every fan `ok` at the shipped floors (exhaust 11723,
|
||||
intakes 4157 and 4162, air assist 11078 rpm, purge 628 counts).
|
||||
|
||||
## Superseded status notes
|
||||
|
||||
### Shared machine services — remaining polish, as listed 2026-08-13
|
||||
|
||||
+19
-7
@@ -145,9 +145,20 @@ floor.
|
||||
|
||||
- **The floors** are settings (§8): `cool_tach_exhaust_min_rpm`,
|
||||
`cool_tach_intake_min_rpm` (either intake), `cool_tach_air_assist_min_rpm`
|
||||
and `cool_purge_min_current`, each a fraction of what the fan reaches at
|
||||
run duty on the bench machine. A cloud job's header can raise a tach floor
|
||||
for that job, never lower it (§2).
|
||||
and `cool_purge_min_current`, each 55 percent of the steady speed the fan
|
||||
reaches at the cut profile on the bench machine (exhaust 11640, intakes
|
||||
4160, air assist 11050 rpm; the recommended bands are 50 to 60 percent).
|
||||
A cloud job's header can raise a tach floor for that job, never lower it
|
||||
(§2).
|
||||
- **A fan is judged at the operating point its floor was measured at.**
|
||||
While the laser is armed every fan is judged, and a job's own fan profile
|
||||
(a cloud header's run duties) may raise a fan above the cut profile but
|
||||
never lower it while armed. Unarmed, a fan is judged whenever it is
|
||||
commanded at or above the cut profile (a bare `M8` from a GRBL job), and a
|
||||
fan the job runs slower is measured, published as `unjudged`, and not
|
||||
judged: the factory's hunts and homing moves run with the exhaust and the
|
||||
intakes off and the air assist at idle, and nothing can fire during them.
|
||||
The purge fan has no duty (it is always on) and is judged in every run.
|
||||
- **A spin-up grace** (`cool_fan_grace_s`) runs from the moment the run
|
||||
profile is written; nothing counts inside it, because the big exhaust fan
|
||||
takes seconds to reach speed.
|
||||
@@ -164,7 +175,8 @@ floor.
|
||||
reading in a job that would have tripped the shipped default is logged.
|
||||
|
||||
`/cool/status` carries each fan's reading, floor and state (`grace`, `ok`,
|
||||
`under`, `TRIPPED`, `off`, or `idle` outside a run) as `fan_gates`.
|
||||
`under`, `TRIPPED`, `off`, `unjudged` for a fan the job runs below the cut
|
||||
profile unarmed, or `idle` outside a run) as `fan_gates`.
|
||||
|
||||
---
|
||||
|
||||
@@ -355,9 +367,9 @@ start of every run, so a change takes effect on your next job.
|
||||
| `cool_temp_resume` | 31 °C | 5 to 59 °C | 20 to 36 °C | Resume gate: below it, continue. Always kept below the ceiling. |
|
||||
| `cool_cooldown_s` | 15 s | 0 to 1800 s | | Smoke-clear phase at run duty after a job. |
|
||||
| `cool_cooldown_max_s` | 300 s | 0 to 1800 s | | Cap on the thermal cooldown phase. |
|
||||
| `cool_tach_exhaust_min_rpm` | 3700 rpm | 0 to 20000 | 2500 to 5000 | Exhaust fan floor at run duty (§3a). `0` turns the gate off. |
|
||||
| `cool_tach_intake_min_rpm` | 1800 rpm | 0 to 20000 | 1200 to 2500 | Intake fan floor, either intake (§3a). `0` turns the gate off. |
|
||||
| `cool_tach_air_assist_min_rpm` | 6000 rpm | 0 to 30000 | 4000 to 8000 | Air-assist fan floor (§3a). `0` turns the gate off. |
|
||||
| `cool_tach_exhaust_min_rpm` | 6400 rpm | 0 to 20000 | 5800 to 7000 | Exhaust fan floor at run duty (§3a). `0` turns the gate off. |
|
||||
| `cool_tach_intake_min_rpm` | 2290 rpm | 0 to 20000 | 2100 to 2500 | Intake fan floor, either intake (§3a). `0` turns the gate off. |
|
||||
| `cool_tach_air_assist_min_rpm` | 6000 rpm | 0 to 30000 | 5500 to 6600 | Air-assist fan floor (§3a). `0` turns the gate off. |
|
||||
| `cool_purge_min_current` | 300 raw | 0 to 1023 | 150 to 500 | Purge-air fan current floor (the fan has no tachometer; about 1 off, about 630 on). `0` turns the gate off. |
|
||||
| `cool_fan_grace_s` | 15 s | 0 to 120 s | 5 to 30 s | Spin-up window after the run profile is written, during which no floor counts. |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user