HEART Embedded Systems logoHEART

Guide 9: A HEART-Embedded 3D printer#

Reading tracks1 Basic
Basic: monitoring only, HEART Basic, A1. Which track am I?

A case study. A maker of desktop 3D printers wants its printers to be HEART-embedded systems: each printer should know when it is unwell, say so in one standard language, tell its owner, and never leak anything it should not. This guide goes step by step from day 1 to a printer that can claim HEART Basic, Autonomy Level A1, shows how an owner registers it and watches it on HEART Hub, and says what higher levels would take.

A working demo comes with it: printer3dSimulator/, one Python file that simulates a room, a printer with its firmware, and its HEART, and reports to https://heartcortex.ai.

Status. A design case study with a simulator. No real printer, heater or motor was involved. The simulator's heating, motion and protection are plausible stand-ins, not a model of any firmware, and nothing here is a safety design. Each step marks what is simulated and what a real printer would need.


Before you start: the firmware protects the printer, HEART watches#

A 3D printer heats a nozzle to over 200 Cel and a bed to 60 to 100 Cel, and moves a head with stepper motors, often for hours with nobody in the room. What keeps it from starting a fire is its firmware: the heater control loop and the thermal-runaway protection that cuts the heaters when a temperature reading stops making sense. That is the safety chain. HEART stays out of it.

Stays in the firmware (Marlin, Klipper, RepRapFirmware or the maker's own)Goes to HEART
Heater control: the PID loops for hotend and bedKnowing whether the printer is doing its job (heating as it should, printing, not stopped)
Motion: steppers, homing, endstops, the plannerWatching temperatures, drivers, filament, the Wi-Fi link
Thermal protection: thermal runaway, heating watch, MINTEMP and MAXTEMPNoticing what the firmware does not check, such as a reading that stopped jittering
Pausing on filament run-out, parking the headRaising alerts with standard fault codes, and explaining them
Every G-code command, from the slicer or the screenTelling the owner, even with no internet
Answering "how is the printer?" in one standard format

This is the general rule of the standard (Part 6: HEART stays out of the safety chain and out of real-time control loops; it never bypasses an interlock). This HEART has no commands at all. Every change request is refused with 403 capability-not-allowed. When the firmware's thermal-runaway protection fires, the heaters are already off before HEART notices: HEART only reports it, clearly, to the right person.

If HEART crashes or is removed, the printer must keep printing and its protection must keep working. That is the test (Part 2, ALL-2).


Step 1: Decide where HEART runs#

The firmware runs on a microcontroller with hard real-time loops and no spare room. Most networked printers already have a second computer beside it:

mainboard (firmware) ──(USB serial or UART)──► host (print server) ──(Wi-Fi)──► owner's phone and HEART Hub
 heating, motion, protection                     HEART runs here
PartWhat it doesHEART's place
MainboardRuns the firmware: heaters, steppers, protection, run-out sensorNone. Read only, through the reports it already sends (M105 or M155 temperature reports, halt messages, driver status)
Host (a Raspberry Pi with OctoPrint or Klipper and Moonraker, or the printer's own Linux board)Sends jobs, shows progress, serves the web pageRuns the HEART (the Python template, the bridge helper or heartd)
Owner's phone or browserStarts jobs, watchesReads the HEART API; receives escalations

So the HEART-embedded system is the pair: the printer, as seen by its host. HEART reads what the host already receives and adds no new path into the firmware.

In the simulator, Printer and PID stand for the mainboard and firmware, and Heart for the code on the host.


Step 2: Give the printer an identity#

The host's HEART serves a Card at /.well-known/heart-card.json:

{ "system": { "id": "com.example.printers.mk3", "name": "Example desktop printer", "version": "1.0.0" },
  "level": "basic", "bindings": ["http-server"], "pulse": { "intervalSec": 30 },
  "modules": ["properties"], "shares": { "pulse": "public", "arrhythmia": "public", "property": "private" },
  "autonomy": { "level": 1 }, "template": "heart/embeddedstandard/python/v1.2611.2" }

The Card lists no capabilities. The system ID names the product model, never the owner. The device ID used by HEART Hub (Step 8) is random, and nothing links it to a person except the owner's own registration. The simulator uses org.heartaispec.demo.printer-3d and the template heart/embeddedstandard/printer3d-simulator/v1.2611.2.


Step 3: List what the printer knows, and how private each item is#

Decide every value's privacy level before writing code. A printer seems harmless, but its job names and history are not: file names often carry a person's name, a gift, a medical part, a key copy.

ValueSourcePrivacyWhy
Healthy or not; open fault codesDerived by HEARTpublicThe only things HEART Hub ever receives (Step 8)
Printer state: idle, heating, printing, paused, haltedFirmware and print serverpublicLike the light on the front of the printer
Hotend temperature and targetFirmwareinternalFor the owner and whoever looks after the printer
Bed temperature and targetFirmwareinternal
Part fan speedFirmwareinternal
Job progress, layer, layers in the job, print timePrint serverinternalShow how the printer is used, not who uses it
Filament remainingSpool weight or the print server's estimateinternal
Stepper driver temperatureDrivers (or a sensor on their heatsink)internal
Room temperatureHost sensorinternal
Wi-Fi linkHostinternal
Job namePrint serverprivateFile names can be personal
Job history and events (what was printed and when)Print serverprivateA timeline of the household
The G-code and model files themselvesPrint servernot a signalHEART never reads them
Owner's name, address, accountMaker's cloud, if anynot on the HEARTIt does not need them, so it never has them

Note what is not an alert: a job finishing, a job being cancelled by its owner, a long print. Those are events, kept in the private job history. Only problems of the system become alerts.


Step 4: Say what "doing its main job" means#

The main job of a 3D printer is: when a job is started, heat to the job's temperatures and print it to the end. The host's HEART checks this from what it already reads:

def check_main_function():
    """CHANGE: return (state, "what is wrong, in plain words"): ok, degraded or lost."""
    p = printer.latest()
    if p.state == "halted":
        return "lost", f"The firmware has shut the heaters down ({p.halt_reason}). Check before resetting."
    if p.state == "paused" and p.runout:
        return "lost", "Filament has run out: the print is paused. Load a new spool."
    if p.state == "heating" and p.heat_secs > 120 and p.hotend < p.hotend_target - 5:
        return "degraded", "The hotend is heating far more slowly than normal."
    return "ok", ""

A condition must hold for 5 seconds before it is raised, because one odd reading is not a fault.

Why a run-out is "main function lost". Part 3 has no area for consumables, and a code must be a standard one when one fits (Part 3, 5.3). While the spool is empty the printer cannot print, and the job waits for a person: that is the meaning of system.main-function-lost. Its severity is error, not critical, because nothing is unsafe: the firmware has paused and parked. storage.* was considered and rejected: in HEART, storage means disks, cards and databases, not filament.


Step 5: The faults it recognises#

Every alert carries a fault code from Part 3 (each code below is in Part 3, Section 5.4), so the host, the owner's phone and any monitor site read it the same way. Two rules may share a code; each keeps its own alert.

What happensFault codeSeverityStatusWho acts
The firmware's thermal-runaway protection (or its heating watch, or MAXTEMP) has cut the heaters and haltedsystem.main-function-lostcriticalfailingThe firmware already has. HEART reports; a person checks and resets
Filament has run out; the run-out sensor paused the jobsystem.main-function-losterrordegradedThe firmware paused; a person loads a spool and resumes
The hotend takes far longer than normal to heat (a weak cartridge, a loose connection, a missing silicone sock)system.main-function-degradedwarningdegradedA person
A thermistor reading has stopped changing (frozen at one value for 30 s while heating is on)sensors.stuckerrordegradedA person. The firmware cannot see this if the frozen value is near the target
A thermistor reading is impossible (open circuit, about -38 Cel; or a short)sensors.out-of-rangeerrordegradedThe firmware refuses to heat; a person checks the connector
A layer shift: the drivers report stalls and current spikes, the head skipped stepsactuators.position-mismatcherrordegradedA person checks the print, belts and pulleys
The hotend went more than 15 Cel past its target while heating up to itperformance.overshootwarningdegradedA person re-tunes the PID
A stepper driver heatsink is above 80 Cel (its fan stopped)performance.too-hotwarningdegradedA person
The printer's Wi-Fi link is downconnectivity.link-lostwarningdegradedNobody needs to: the printer keeps printing. Shown when it is back
The printer silent for three Pulse intervalssystem.flatlineRaised by HEART Hub

Why a layer shift is actuators.position-mismatch. The evidence is noisy motor current, but the readings are not the fault: the current sensor is fine. The fault is that the head ended up somewhere other than where it was told to go, which is exactly the meaning of actuators.position-mismatch in Part 3. sensors.noisy would wrongly send the owner to check a sensor; system.main-function-degraded would be true but less useful. The rule fires on the drivers' stall reports (for example TMC StallGuard) during printing; a real product could add an accelerometer.

Why a stuck reading matters even with good firmware. Thermal-runaway protection checks that the reading stays near the target. A reading frozen at the target passes that check, while the real bed drifts. A live thermistor always jitters by a few hundredths of a degree, so a reading that has not changed at all for 30 seconds is a fault the firmware cannot see and HEART can.

The thresholds here are illustrations. A real product takes them from its own design: its normal heat-up time, its drivers' limits, its thermistor's range.

In the simulator, every row except the overshoot and the firmware's heating-watch and MAXTEMP halts can be staged with --scenario (Step 9).


Step 6: No commands, and why that is right for A1#

The HEART has no capabilities: the Card lists none, and every PUT, POST, PATCH or DELETE, on any path and even with the owner key, is refused with 403 capability-not-allowed. Heating, moving, pausing and resuming stay with the firmware and the print server, where the owner already does them.

How a later version could add a command. The standard has a worked example of mapping one firmware command: spec/examples/custom/gcode-printer-set_nozzle.json. It maps a capability to G-code M104 S{tempCel} on the serial line, with an input range of 0 to 260 Cel, guards (only in states idle or printing, at most 60 an hour), physical: true and callers limited to a human. Heating is physical, so even a person's own request would need proof of presence at the printer (Part 6, Section 2), and the firmware's own MAXTEMP and thermal protection would still apply. This simulator does not implement it, on purpose: a first HEART should prove it can notice and explain before it is given anything to do.

The standard requires a Stop control only from Autonomy Level A3 up, because A1 and A2 take no action and so have nothing to stop. The printer's own Stop (the screen, the print server, the power switch) is unchanged.


Step 7: Tell a person#

Autonomy Level A1 needs an escalation route. For a printer, three, from nearest to farthest:

  1. At the printer, with no internet: a message on its screen and a beep, so whoever is in the room knows.
  2. The owner's phone, through the print server's own notifications (it already has them for "print finished").
  3. HEART Hub (Step 8), which also emails when the printer goes silent.

Each alert says what happened and what to do, in plain words. For example, the thermal-runaway alert:

The printer's firmware cut the heaters by itself (its thermal-runaway protection: the hotend reading stayed below target while the heater ran at full power. The thermistor may have come loose from the heater block). The job was aborted. HEART only reports this: check the hotend before resetting the printer.

Change escalate() to use the screen, the buzzer and the phone.


Step 8: Register and watch it on HEART Hub#

HEART Hub lets an owner see the printer's health from anywhere, on a private page.

  1. First start. The host makes a random device ID, claim code and key, keeps them, and shows the claim code only to the person holding the printer: on a label on the printer, or on its screen.
  2. Sign in. The owner opens https://heartcortex.ai/login and enters an email address. A 6-digit code arrives; there are no passwords.
  3. Register. At https://heartcortex.ai/register?id=<device ID> (a QR code on the label can open it), the owner enters the claim code. Holding the printer is the proof of ownership.
  4. Watch. The device's page, https://heartcortex.ai/device/<device ID>, shows its status and open alerts, private to the owner until they share it. Their list of devices is at https://heartcortex.ai/devices.
  5. Silence. If no report arrives for three Pulse intervals (the printer is off, or its Wi-Fi is down), the page shows a Flatline and the owner gets one email.

Only the public Pulse and public alerts are sent, and the site keeps only the status, timing and fault codes: never a temperature, a job name or a layer. A printer farm or a maker with many customers can run its own monitor site (the code is open, in heart-monitor/).


Step 9: Try it with the simulator#

python3 printer3dSimulator/printer3dSimulator.py --scenario all

It prints a device ID and claim code; register them as in Step 8 and watch the page while it stages each fault in turn on one print job: a slow first heat-up, a hot stepper driver, a frozen bed reading, a lost Wi-Fi link (and so a gap in reports), a layer shift, a filament run-out, a thermal-runaway shutdown by the firmware, and an impossible hotend reading. Each fault is "fixed by a person" a minute or two later, so you can watch alerts open, escalate and resolve. Details and every option are in printer3dSimulator/README.md.

What is simulated: the room, the printer, its firmware and every reading. What a real printer needs instead: a reader for the firmware's reports and the print server's status (README, Section 7), the maker's own thresholds, and a real escalation route.


Step 10: Test it, rate it and claim only what passed#

  1. Run the HEART-Rating client (heart-rating/client/heart_rating.py) against the host, and the hands-on tests of Part 9: cause each fault in the table of Step 5 on a test printer (unplug a thermistor with the heaters off, block the driver fan, run a spool out), cut the internet, and kill the HEART while printing: the print and the firmware's protection must carry on.
  2. Publish a Declaration with every result.
  3. Claim HEART Basic, Autonomy Level A1.
LevelWhat it would mean for a printerWhat it needs (Part 2, Section 8)
A1 (notices and tells a person)This guideBasic, and an escalation route
A2 (says why, with a confidence)"The hotend reading fell from 215 to 170 Cel in 20 s while the heater ran at full power: the thermistor has likely come loose from the block, confidence high." The evidence points to the readings and the firmware's halt eventHEART Connected (Rhythm events as evidence), and cause and confidence on alerts
A3 (suggests a fix, a person approves)After a slow heat-up: "re-run PID tuning (M303) for the hotend at 210 Cel?" The owner approves at the printer. Tuning heats, so it is physical and needs proof of presenceHEART Full: approval and the Stop control
A4 (fixes known problems by itself, by an adopted rule)A Playbook could pause the job when filament runs out, on a printer with no run-out switch, where the host estimates the spool from its weight and the slicer's usage. Pausing parks the head, so it is physical: the person adopting the Playbook adopts it as physical, with proof of presence, and puts the pause action on the allowlist for rule. That is acceptable because pausing is a safe, lowering action: it stops motion and starts no new heating, and the firmware's own limits still apply. Resuming needs a person: someone must load the filament, check the print and clear the nozzle, and resuming starts motion again. A Playbook must never resume or reset after a thermal shutdownHEART Full, at least one adopted Playbook in the area, and an allowlist entry for rule for its action
A5 (works out new fixes)An AI could notice a new pattern (shifts always on tall prints at high speed) and propose a slower profile as a proposed Playbook for a person to adopt. Anything that heats or moves would still ask firstThe ai and evolving modules

HEART conformance says nothing about electrical or fire safety. The printer still needs its own (for example IEC 62368-1 or IEC 60335-1 for the product, and the firmware's thermal protection enabled and tested).


What the case study shows#

  • The firmware is the safety chain, HEART is the witness. Thermal-runaway protection must work with HEART stopped. HEART's value is to say clearly what the firmware did and why, to the right person, in a standard way.
  • HEART can see what a safety check cannot. A reading frozen at its target passes thermal-runaway protection; a HEART that knows live readings always jitter notices it.
  • Pick the honest fault code. A layer shift is an actuator ending up in the wrong place, not a noisy sensor; a run-out is the main job lost, not storage. The right code sends the owner to the right part.
  • A harmless-looking device can still leak. Temperatures are dull, but job names and print history describe a household. Only status and fault codes leave the printer.
  • Stopping is easy, starting needs a person. At A4 a rule may pause a print; only a person may resume it.