Repository navigation
Expand file tree
/
Copy path02_system_req.sdoc
More file actions
509 lines (431 loc) · 21 KB
/
Copy path02_system_req.sdoc
File metadata and controls
509 lines (431 loc) · 21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
[DOCUMENT]
TITLE: Safe Kiln Controller, System Requirements
UID: SAFEKILN-SYS
VERSION: 0.1 (draft)
DATE: 2026-10-08
OPTIONS:
MARKUP: Markdown
VIEW_STYLE: Table
NODE_IN_TOC: True
METADATA:
SPDX-FileCopyrightText: 2026 Bitcrush Testing
SPDX-License-Identifier: GPL-3.0-or-later
Status: For review
Project: Safe Kiln Controller, PID kiln controller
[GRAMMAR]
ELEMENTS:
- TAG: TEXT
FIELDS:
- TITLE: STATEMENT
TYPE: String
REQUIRED: True
- TAG: SECTION
PROPERTIES:
IS_COMPOSITE: True
FIELDS:
- TITLE: UID
TYPE: String
REQUIRED: False
- TITLE: TITLE
TYPE: String
REQUIRED: True
- TAG: REQUIREMENT
FIELDS:
- TITLE: UID
TYPE: String
REQUIRED: True
- TITLE: STATEMENT
TYPE: String
REQUIRED: True
- TITLE: PRIORITY
TYPE: SingleChoice(M, S, C, W)
REQUIRED: False
- TITLE: VERIFICATION
TYPE: MultipleChoice(T, A, I, D)
REQUIRED: False
- TITLE: STATUS
TYPE: SingleChoice(Active, Withdrawn, Superseded, Reversed, Resolved)
REQUIRED: False
RELATIONS:
- TYPE: Parent
- TAG: CONSTRAINT
FIELDS:
- TITLE: UID
TYPE: String
REQUIRED: True
- TITLE: STATEMENT
TYPE: String
REQUIRED: True
- TITLE: STATUS
TYPE: SingleChoice(Active, Withdrawn, Superseded, Reversed, Resolved)
REQUIRED: False
- TAG: ASSUMPTION
FIELDS:
- TITLE: UID
TYPE: String
REQUIRED: True
- TITLE: STATEMENT
TYPE: String
REQUIRED: True
- TITLE: STATUS
TYPE: SingleChoice(Active, Withdrawn, Superseded, Reversed, Resolved)
REQUIRED: False
- TAG: QUESTION
FIELDS:
- TITLE: UID
TYPE: String
REQUIRED: True
- TITLE: STATEMENT
TYPE: String
REQUIRED: True
- TITLE: STATUS
TYPE: SingleChoice(Active, Withdrawn, Superseded, Reversed, Resolved)
REQUIRED: False
[TEXT]
STATEMENT: >>>
Level 2 of the V-model (see [`v-model-process.md`](v-model-process.md)): what the
**whole system** must do, hardware and software and mechanics together, derived
from the user requirements of
[`01_user_req.sdoc`](01_user_req.sdoc) and refined by the software requirements
of [`03_software_req.sdoc`](03_software_req.sdoc). Verified by system tests.
Three groups live here, and the reason each is at system level rather than
software level is worth stating.
`SYS-HW-` are the hardware interface requirements. They constrain the board, not
a program.
`SYS-SAF-` are the four safety requirements that are **not** software behaviour.
`SYS-SAF-03` asks for an SSR in series with an electromechanical contactor, which
is a wiring diagram. `SYS-SAF-01` and `SYS-SAF-02` are properties of the system
as a whole, discharged by hardware and software together: a charge pump that
decays and a program that keeps refreshing it. `SYS-SAF-24` is about the
documentation. The remaining 27 safety requirements are software rules and sit in
`03_software_req.sdoc`.
`SYS-ASM-` are the assumptions about the environment the system is placed in.
They are not requirements on the product; they are the conditions under which its
requirements hold, which is why a wrong one is a defeated protection layer rather
than a bug.
<<<
[[SECTION]]
UID: SECT-6
TITLE: 6. Hardware interface requirements
[TEXT]
STATEMENT: >>>
> This section constrains the firmware's view of the hardware. The board design
> itself is documented in `hardware/`.
<<<
[REQUIREMENT]
UID: SYS-HW-01
STATEMENT: >>>
The controller shall be an **ESP32-S3** with at least 8 MB flash; PSRAM shall not be required.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-02
STATEMENT: >>>
Both thermocouple front ends shall be MAX31856 devices, and they shall be on **separate SPI buses belonging to different microcontrollers**:
- the **chamber** front end on the supervisor's bus ([LINK: SYS-HW-26]), read by the supervisor and by nothing else;
- the **enclosure** front end on the controller's bus, read by the controller.
**Amended 2026-10-10 with the supervisor (SWA-22).** This said "a shared SPI bus with individual chip selects", which was true when one microcontroller read both. A shared bus is now exactly what must not happen: a supervisor whose chamber reading can be disturbed by the controller's bus traffic, or whose chip select can be driven by a controller that has crashed with a pin latched, is not independent of it, and independence is the whole of what the second part buys.
One **common cause** survives any bus arrangement, and it is the chamber couple itself: both microcontrollers derive chamber temperature from the same junction, so the independence this requirement buys is independence against software and silicon, not against the sensor. It is recorded in `safety.md` section 6 and in section 9 of the supervisor's design rather than claimed away here.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-03
STATEMENT: >>>
The thermocouple front-end SPI bus shall be separate from, or arbitrated independently of, any bus shared with a peripheral that can stall it.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-04
STATEMENT: >>>
The display shall be a 128×64 monochrome OLED on I²C, at a configurable address (default 0x3C).
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-05
STATEMENT: >>>
The operator input shall be a quadrature rotary encoder with a push button, read by hardware (pulse counter unit) rather than by polling in software.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-06
STATEMENT: >>>
The heater modulation output shall drive a zero-cross-switching SSR rated for the kiln's current with a documented margin.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-07
STATEMENT: >>>
The heat-enable output shall drive the safety contactor through a circuit that requires a **periodic software refresh** to hold the contactor closed, so that a hung or crashed MCU releases it ([LINK: SYS-SAF-02]).
<<<
PRIORITY: M
VERIFICATION: I, T
[REQUIREMENT]
UID: SYS-HW-08
STATEMENT: >>>
All heater and contactor control outputs shall have external pull-downs to the de-energised state, and shall not use pins that are strapping pins or that glitch during reset or boot on the ESP32-S3.
<<<
PRIORITY: M
VERIFICATION: I, T
[REQUIREMENT]
UID: SYS-HW-09
STATEMENT: >>>
The system shall carry an **on-board** audible alarm: a 5 V active (self-driving) magnetic buzzer switched low-side from the alarm GPIO, so that annunciation needs no external component or field wiring.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-19
STATEMENT: >>>
Every test point shall be a surface pad on the **top copper layer only**, so the whole board can be probed without turning it over or removing it from its enclosure. No test point shall be placed on the bottom layer.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-20
STATEMENT: >>>
Test-point pads shall be small enough not to drive the board area, and shall carry no drilled hole. 1.5 mm square is the design value.
<<<
PRIORITY: S
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-10
STATEMENT: >>>
Pin assignments shall be defined in one place per board variant and shall not be duplicated across the codebase.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-11
STATEMENT: >>>
The design shall include a **current transformer (Stromwandler)** around one heater conductor, downstream of the safety contactor and the SSR, sized for the kiln's rated current with headroom, and preferably split-core so it can be fitted without breaking the heater wiring.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-16
STATEMENT: >>>
The current transformer shall be a **voltage-output type with an integral burden resistor**, or shall have a burden resistor permanently fitted at the board. A current-output CT whose burden can be disconnected shall not be used, because an open secondary carrying primary current develops dangerous voltages.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-17
STATEMENT: >>>
The CT input shall be conditioned for a single-supply ADC: mid-rail bias, anti-alias filtering matched to the sample rate of [LINK: SWR-CUR-03], and clamping to the ADC supply rails.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-18
STATEMENT: >>>
The CT provides the only galvanic isolation between the heater circuit and the controller electronics; its insulation rating and the creepage and clearance around its input shall be appropriate to the mains voltage in use.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-12
STATEMENT: >>>
The design shall support an optional second SSR channel for a kiln with independently switched element groups.
<<<
PRIORITY: C
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-13
STATEMENT: >>>
The installation shall include a hardware over-temperature cutout in the safety chain that operates independently of this controller.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-24
STATEMENT: >>>
**Superseded 2026-10-10 by [LINK: SYS-HW-26] and [LINK: SYS-SAF-25]. Rewritten rather than deleted, because the property it reached for is now delivered differently.**
It required the thermocouple front ends' `FAULT` outputs to interrupt the contactor coil in hardware, each through its own series switching element, so that a reported sensor fault removed the heater with no firmware taking part. What that was buying is a sensor fault that stops the kiln without trusting the controller's firmware, and it bought it with an interlock whose limits had to be documented at length: the outputs are open-drain, so an unpowered or absent front end leaves the path closed, and a MAX31856 reports an open circuit only once its fault mask is configured, which is firmware work. The chain covered faults the device actively reported and nothing else, so [LINK: SWR-SAF-04] remained the real cover for a dead or unconfigured front end.
The supervisor delivers the same property and more of it. It reads the chamber front end itself, decides on a persistent fault, and holds its own series element in the coil; a front end that is dead, absent or unconfigured is a front end that does not answer the supervisor either, and that is a trip rather than a documented limit. The discrete chain is therefore not built.
What is **kept** from this requirement:
- each `FAULT` net retains its own test point, which costs nothing and is how the front ends are diagnosed on a bench;
- the enclosure channel has no hardware interlock and never did; [LINK: SWR-SAF-11] in the controller's firmware is its cover, and that channel is deliberately outside the supervisor's remit so that an enclosure fault can never cause the supervisor's trip.
The lid's series contact of [LINK: SYS-HW-21] is **unchanged** and stays in the coil. It is the one element in the design that depends on no firmware at all.
<<<
PRIORITY: M
VERIFICATION: I, T
[REQUIREMENT]
UID: SYS-HW-21
STATEMENT: >>>
Where a door or lid interlock is fitted, its switch shall be **normally closed** and shall be wired **both** into a controller input ([LINK: SWR-SAF-31]) **and** in series with the safety contactor coil, so that opening the door de-energises the heater through hardware whether or not the firmware is working. The controller input provides annunciation, latching and logging; it is not the interlock.
<<<
PRIORITY: S
VERIFICATION: I, T
[REQUIREMENT]
UID: SYS-HW-26
STATEMENT: >>>
**The independent safety supervisor shall be a separate microcontroller** with:
- **its own clock and its own watchdog**, neither derived from nor serviced by the controller;
- **its own series interrupting element in the contactor coil path**, in addition to the elements of [LINK: SYS-SAF-03] and the lid contact of [LINK: SYS-HW-21];
- **its own chamber thermocouple front end** on its own SPI bus ([LINK: SYS-HW-02]);
- **its own programming and debug interface**, brought out to test points, so that its firmware can be reviewed, built and flashed without the controller taking part.
The permit output shall be **active high**, and the series element shall have an **external pull-down**: every GPIO is high impedance between reset and the first instruction, so without one there is a window at every supervisor reset in which the element's state is whatever the board leaks to.
It can refuse heat on its own and it cannot command heat on its own: holding one element of a series path is permission, not control. That asymmetry is the whole design, and it is why the supervisor needs no safety case for its own failure to permit -- a supervisor that fails off is a kiln that does not fire.
<<<
PRIORITY: M
VERIFICATION: I, T
[REQUIREMENT]
UID: SYS-HW-27
STATEMENT: >>>
**The link between the controller and the supervisor shall be point-to-point serial, one direction, and report only.** The supervisor transmits; it shall not act on anything received, and the controller shall have no electrical path able to change what the supervisor does.
No message shall exist that can raise the supervisor's trip threshold, lower its sensitivity, clear its latch, or suppress its reports. The threshold is compiled in ([LINK: SYS-SAF-25]) and the latch is cleared locally ([LINK: SYS-HW-28]).
The reason is the attack surface and the failure surface at once: a controller that can be compromised over the network, or that can simply crash with a transmitter stuck, must not be able to reach the part whose job is to disbelieve it. A link that only carries information out cannot carry instruction in.
<<<
PRIORITY: M
VERIFICATION: I, T
[REQUIREMENT]
UID: SYS-HW-28
STATEMENT: >>>
**The supervisor's latch shall be cleared by a local action at the panel**, by a button wired to the supervisor and to nothing else, or by a power cycle.
The button shall be edge triggered and shall require a deliberate hold, and a line stuck low shall never arm it, so that a short circuit fails towards the latch holding rather than towards it clearing.
The panel shall not imply that there is one acknowledgement. There are two and they are not the same: this one clears the supervisor, and the controller's own latched fault ([LINK: SWR-SAF-17]) is acknowledged at the display. An operator cannot see the difference, so the labelling has to make it.
<<<
PRIORITY: M
VERIFICATION: I, T
[REQUIREMENT]
UID: SYS-HW-25
STATEMENT: >>>
The contactor coil's freewheel diode shall be connected **across the coil itself**, on the kiln side of every series interrupting element of [LINK: SYS-HW-21] and [LINK: SYS-HW-26], so that opening any of them leaves the coil current a path to decay through. A freewheel path referenced to the raw supply instead would put the inductive transient across the opening contacts, eroding the lid switch and stressing the sense divider.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-14
STATEMENT: >>>
The controller electronics shall be supplied from a regulated source able to power the MCU, display and contactor coil simultaneously, and shall not rely on a USB host for operating power.
<<<
PRIORITY: M
VERIFICATION: I
[REQUIREMENT]
UID: SYS-HW-15
STATEMENT: >>>
Thermocouple inputs shall be filtered and protected at the hardware level against the electrical noise of a switching multi-kilowatt load.
<<<
PRIORITY: M
VERIFICATION: I
[[/SECTION]]
[[SECTION]]
UID: SECT-SYS-SAF
TITLE: 7. System-level safety requirements
[TEXT]
STATEMENT: >>>
The safety requirements that hardware discharges, wholly or in part. The numbering
is the original `SR-` numbering and is deliberately not compacted: these
identifiers are cited from [`safety.sdoc`](safety.sdoc), from the firmware and
from the hardware design, and renumbering them to close a gap would break every
one of those citations to no benefit.
<<<
[REQUIREMENT]
UID: SYS-SAF-01
STATEMENT: >>>
The system shall be **fail-safe**: any single failure of software, MCU, sensor, or SSR shall result in heating being de-energised, never in uncontrolled heating.
<<<
VERIFICATION: A, T
[REQUIREMENT]
UID: SYS-SAF-02
STATEMENT: >>>
Heating shall be enabled only by the *active and continuous* assertion of software; no static condition, boot state, hung task or crashed firmware shall be capable of holding heating on.
<<<
VERIFICATION: A, T
[REQUIREMENT]
UID: SYS-SAF-03
STATEMENT: >>>
The heating output stage shall consist of an SSR for modulation **in series with** an electromechanical contactor that provides an independent break, each controlled by a separate output.
<<<
VERIFICATION: I
[REQUIREMENT]
UID: SYS-SAF-25
STATEMENT: >>>
**An independent supervisor shall de-energise the heater above a hard-coded absolute chamber temperature, and on a persistent chamber thermocouple fault, independently of the controller.**
The threshold shall be **compiled into the supervisor's firmware** and shall not be reachable by configuration, by the link, or by any other means short of reflashing that part. A ceiling an operator can raise is a ceiling, not a backstop: [LINK: SWR-SAF-23]'s configurable maximum is the operator's limit, and this is the one that exists for when the controller's own rules, or the controller itself, have stopped working. The two values are stated together wherever either appears, because limits that can be edited apart eventually cross.
It supersedes the hardware fault chain of [LINK: SYS-HW-24], and it is a stronger claim than that chain could make: a front end that is dead, absent or unconfigured does not answer the supervisor, and not answering is a trip.
<<<
VERIFICATION: A, T
[REQUIREMENT]
UID: SYS-SAF-26
STATEMENT: >>>
**The supervisor's trip shall latch**, and shall be clearable only by a power cycle or the local action of [LINK: SYS-HW-28] -- never by a command over the link ([LINK: SYS-HW-27]).
A latch that the controller could clear is not a latch: the controller is the part that may have failed, and the condition that tripped the supervisor is one the controller either did not see or did not act on. Somebody has to go and look at the kiln.
The latch is **not required to survive a power cycle**, and that is deliberate rather than an omission. The supervisor holds no non-volatile state at all, so it cannot be left in a state that a reflash or a flat battery changes, and the system-level obligation to remember a fault across a power loss is met by the controller's persisted fault ([LINK: SWR-SAF-17]). Section 3 of the supervisor's design states what that leaves: a power cycle clears the supervisor's own memory of why it tripped, and the controller's record is what the operator is shown.
<<<
VERIFICATION: A, T
[REQUIREMENT]
UID: SYS-SAF-27
STATEMENT: >>>
**Chamber temperature shall be acquired by the supervisor and reported at not less than 4 Hz, and a stale report shall be treated by the controller as a sensor fault.**
The controller has no other source of chamber temperature, so the report rate is the controller's sample rate and silence on the link is indistinguishable from a dead front end -- which is why it is treated as one rather than as a communications problem to retry.
**The supervisor's own trip shall not depend on the link.** It shall act within one acquisition period of the condition arising, whether or not anything is listening. The link exists so that the controller can display a temperature and say why the kiln stopped; the protection works with the link unplugged.
<<<
VERIFICATION: A, T
[REQUIREMENT]
UID: SYS-SAF-24
STATEMENT: >>>
The documentation shall state that Safe Kiln Controller is **not** a safety-certified device, that an independent hardware over-temperature cutout is required ([LINK: SYS-HW-13]), and that mains wiring must be performed by a competent person in accordance with local regulation [R6].
<<<
VERIFICATION: I
[[/SECTION]]
[[SECTION]]
UID: SECT-9
TITLE: 9. Assumptions
[ASSUMPTION]
UID: SYS-ASM-01
STATEMENT: >>>
The kiln is a resistively heated electric kiln whose thermal response is adequately described by a first-order-plus-dead-time model over the operating range.
<<<
[ASSUMPTION]
UID: SYS-ASM-02
STATEMENT: >>>
The kiln has a single thermal zone. Multi-zone kilns are out of scope for v1.0 but the architecture shall not preclude them.
<<<
[ASSUMPTION]
UID: SYS-ASM-03
STATEMENT: >>>
The heating elements are switched by a zero-cross SSR; the controller does not perform phase-angle control.
<<<
[ASSUMPTION]
UID: SYS-ASM-04
STATEMENT: >>>
A competent person performs the mains installation, and an independent over-temperature cutout is fitted ([LINK: SYS-HW-13]).
<<<
[ASSUMPTION]
UID: SYS-ASM-05
STATEMENT: >>>
The device is on a trusted local network ([LINK: SWR-NFR-20]).
<<<
[ASSUMPTION]
UID: SYS-ASM-06
STATEMENT: >>>
The operator is present in the building during firing, as kiln manufacturers require. Unattended firing is not a design goal.
<<<
[ASSUMPTION]
UID: SYS-ASM-07
STATEMENT: >>>
Wall-clock time may be unavailable; all timing-critical behaviour uses the monotonic time base ([LINK: SWR-NET-08]).
<<<
[ASSUMPTION]
UID: SYS-ASM-08
STATEMENT: >>>
Internal flash endurance is at least 100 000 erase cycles per block.
<<<
[ASSUMPTION]
UID: SYS-ASM-09
STATEMENT: >>>
The heater load is resistive and switched as a single group, so the current in the monitored conductor is proportional to total heater power.
<<<
[ASSUMPTION]
UID: SYS-ASM-10
STATEMENT: >>>
The kiln is **single phase**. Three-phase kilns are out of scope (§12 ([LINK: SECT-12]), [LINK: OQ-06]), so there is no unmonitored phase for a fault to hide on: there is one phase and one current transformer on it ([LINK: SYS-HW-11]).
<<<
[[/SECTION]]