![Minimum Rust: 1.75](https://img.shields.io/badge/Minimum%20Rust%20Version-1.75-green.svg) [![crates.io](https://img.shields.io/crates/v/prinThor.svg)](https://crates.io/crates/prinThor) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ![Discord Shield](https://discordapp.com/api/guilds/1169965662618259456/widget.png?style=shield)

Printhor: The highly reliable but not necessarily functional 3D printer firmware

If you are using this product or like the project, please this repository to show your support! 🤩

# Overview Printhor is a generic a hardware-agnostic firmware framework focused on FDM printers, CNC and Engravers implemented in Rust. There are many productive firmwares in the community like gbrl, marlin, reprap, etc. Each single one have a concrete approach and guidelines. This one aims to provide a research environment for not strictly productive purpose, but a reliable platform with the following goals: * Robustness. * Numerical stability. * Efficient resources utilization and close-to-preemptive multitasking. * Leverage async multitasking. * Maintain busy waits to a minimum. * Ensure leverage of DMA transfers as much as possible. * Ensure of leverage of FPU when present. * Simplicity. * Clarity and readability. Which means the principal short-term goal is not to develop a productive firmware for final user rather than providing an environment in which anyone can test and experiment any concrete approach to feed the community with good quality, state-of-the-art or innovative feature increments. ## Features * "Clean" hardware abstraction. * Vector geometry / linear algebra calculus for kinematics * High precision and deterministic kinematics and computations. * Simple, secure and efficient resource and peripherals sharing. * Clean and simple async tasks coordination/intercommunication with event based primitives. * Wide GCode standard coverage. * Native simulation for development and benchmarking. * Smooth acceleration and jerk limited motion plan. * Precise thermal control. * Many others coming. ## Overall status
FeatureStatus
SimulationFunctional
I/OFunctional
State and logicIncubation
Motion PlannerIncubation
KinematicsDraft
Thermal ControlDraft
DisplayDraft
Laser/CNCTODO
# Help wanted If you are interested in this project and want to collaborate, you are welcome. A Discord server has been created for informal discussions. Otherwise, Github Issues and Pull Requests are preferred. [![Discord Banner 4](https://discordapp.com/api/guilds/1169965662618259456/widget.png?style=banner4)](https://discord.gg/VSag6T4KS6) # Checkout ```shell git clone https://github.com/cbruiz/printhor cd printhor ``` # Build The minimal toolset required to build and run is: * Rust, in order to compile * cargo binutils, to produce the image binary that you can flash via SD card as usual. * __[Optionally]__ probe-run, if you are willing to use a SWD/Jlink debugger (https://github.com/knurling-rs/probe-run) * __[Optionally]__ cargo-bloat and cargo-size utils are great to analyze the code size. * __[Optionally]__ A Rust IDE, like VStudio Code (recommended), Jetbrains IDE (IntelliJ, CLion or RustRover (recommended)), or others ## Prerequisites: Rust and toolchain This crate requires **Rust >= 1.75**. For official guide, please see https://www.rust-lang.org/tools/install However, if your os is unix based: ```shell curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup update ``` For microcontrollers (currently few stm32 only), the specific target toolchain and cargo binutils is also needed: ```shell rustup target add thumbv7em-none-eabi rustup target add thumbv7em-none-eabihf rustup target add thumbv6m-none-eabi rustup component add llvm-tools cargo install cargo-binutils ``` Optionally, for debugging on baremetal microcontrollers (currently few stm32 only): ```shell cargo install probe-run ``` ## Native simulator backend The framework with a set of mocked peripherals (most of them without any logic). Provides a commandline GCode prompt on standard input __Note__: A SDCard image in ./data/ is required to be open if sdcard feature is enabled in native :) ```shell RUST_LOG=info cargo run --bin printhor ``` ### Integration tests Native backend has a special feature called integration-test which is used to perform "some kind of" integration tests. Still pending to be matured. ```shell RUST_LOG=info cargo run --features integration-test --bin printhor ``` Testing with GCode sender though socat ```shell RUST_LOG=info cargo build --bin printhor socat pty,link=printhor,rawer EXEC:target/debug/printhor,pty,rawer ``` ## MKS Robin Nano (Currently v3.1 only) This board (https://www.makerbase.store/pages/mks-robin-nano-v3-1-intro) is still work in progress ### Binary image production (standard with defmt) The firmware.bin file ready to be uploaded to the SD can be produced with the following commandline: ```shell DEFMT_LOG=info cargo objcopy --release --no-default-features --features mks_robin_nano --target thumbv7em-none-eabihf --bin printhor -- -O binary firmware.bin ``` Firmware size if 200kB as of now with previous settings. ### Minimal-size binary image production ```shell DEFMT_LOG=off RUST_BACKTRACE=0 cargo objcopy --profile release-opt --no-default-features --features mks_robin_nano --target thumbv7em-none-eabihf --bin printhor -- -O binary firmware.bin ``` Firmware size if 164kB as of now with previous settings. ### Run with JLink/SWD device DEFMT_LOG=info RUST_BACKTRACE=1 RUSTFLAGS='--cfg board="mks_robin_nano"' cargo run --release --no-default-features --features mks_robin_nano --target thumbv7em-none-eabihf --bin printhor ## Nucleo-64 There are two base boards supported in this category. The assumption/requirement is to use any of these generic purpose development board with the Arduino CNC Shield v3 (hat): ![alt text](datasheets/NUCLEO-L476RG_CNC_SHIELD_V3/Arduino-CNC-Shield-Pinout-V3.XX.jpeg "Arduino CNC Shield v3") In these development boards, flash and run can be directly performed with probe-rs just connecting USB as they have a built-in SWD/JTAG interface: ### nucleo-f410rb Please, note that this board is very limited in terms of flash and memory (48kB SRAM, 128kB flash). You might not assume that a firwmare not optimized for size (LTO, etc...) will fit in flash. Note: This target uses flip-link by default, requiring flip-link tool. To change this behavior please check .cargo/config.toml ```shell cargo install flip-link ``` ```shell DEFMT_LOG=info RUST_BACKTRACE=0 RUSTFLAGS='--cfg board="nucleo64-f410rb"' cargo run --release --no-default-features --features nucleo_64_arduino_cnc_hat,nucleo64-f410rb --target thumbv7em-none-eabihf --bin printhor ``` ### nucleo-l476rg This one is a bit slower but much more RAM and flash. Enough even though with non very optimized firmware and may features ```shell DEFMT_LOG=info RUST_BACKTRACE=0 RUSTFLAGS='--cfg board="nucleo64-l476rg"' cargo run --release --no-default-features --features nucleo_64_arduino_cnc_hat,nucleo64-l476rg --target thumbv7em-none-eabihf --bin printhor ``` ## SKR Mini E3 (currently v3.0 only) This board (https://biqu.equipment/collections/control-board/products/bigtreetech-skr-mini-e3-v2-0-32-bit-control-board-for-ender-3) is quite functional ### Binary image production (standard with defmt) The firmware.bin file ready to be uploaded to the SD can be produced with the following commandline: ```shell DEFMT_LOG=info cargo objcopy --release --no-default-features --features skr_mini_e3 --target thumbv6m-none-eabi --bin printhor -- -O binary firmware.bin ``` Firmware size if 196kB as of now with previous settings. ### Minimal-size binary image production ```shell DEFMT_LOG=off RUST_BACKTRACE=0 cargo objcopy --profile release-opt --no-default-features --features skr_mini_e3 --target thumbv6m-none-eabi --bin printhor -- -O binary firmware.bin ``` Firmware size if 164kB as of now with previous settings. ### Run with JLink/SWD device DEFMT_LOG=info RUST_BACKTRACE=1 RUSTFLAGS='--cfg board="skr_mini_e3"' cargo run --release --no-default-features --features skr_mini_e3 --target thumbv6m-none-eabi --bin printhor ## Extra utilery A simple stand-alone std binary to experiment with motion plan (kind of playground): ```shell cargo run --bin scurve_plot ``` Example output: ![alt text](design/motion_plan.png "Motion Plan") # TODO * Code productivization. Mostly based on https://dl.acm.org/doi/pdf/10.1145/3519941.3535075 and https://jamesmunns.com/blog/fmt-unreasonably-expensive/: * Code size reduction. * Remove unwrap/panic calls. * Remove unsafe code (a little bit, but there it is) * Remove trivial/redundant computation __but not compromising readability__. * Unit test * CoreXY support * Display * I/O control * xonxoff * Adaptative planing cost measurement to take a decision on chaining or not and how much. * There is an issue activating USB together with SPI in SKR E3 Mini v3 :( * exfat support could be great. # Customization For a single board, the high-level features (hotend, hotbed, fan, sdcard, ... ) can be activated/deactivated by cargo feature selection or directly editing the main cargo.toml In order to change pins, writing/adapting some code is required, as of now. There is not expected to be, at least in the short term any kind of configuration file. Because of that limitation (Rust makes that hard to tackle because of the strict typing), a clean code organization it's crucial and pretty straightforward to assume slight customizations by editing code. # Architecture printhor is composed by the following architectural blocks * embassy-rs, as the harware and async foundation https://github.com/embassy-rs/embassy * async-gcode, as the core of the GCode interpretation https://github.com/ithinuel/async-gcode * printhor-hwa-common (within the project), as the hardware abstraction layer contract and common utilery * A set of crates (withn the project) for each harware/board. Currently: * printhor-hwi_native : The native simulator. * printhor-hwi_skr_mini_e3_v3 : (See [Datasheets/SKR_MINI_E3-V3.0](datasheets/SKR_MINI_E3-V3.0)) * printhor-hwi_mks_robin_nano_v3_1 [WIP] : (See [Datasheets/MKS-ROBIN-NANO-V3.1](datasheets/MKS-ROBIN-NANO-V3.1)) * printhor-hwi_nucleo_64_arduino_cnc_hat [WIP] : A Nucleo-64 development board (currently L476RG or F410RB) with Arduino CNC Shield v3.x (See [Datasheets/NUCLEO-L476RG_CNC_SHIELD_V3](datasheets/NUCLEO-L476RG_CNC_SHIELD_V3)) Intentionally, traits are in general avoided when not strictly required in favour of defining a more decoupled and easy to evolve interface based on: * type aliases * module exports Diagram is Work in Progress # Similar, related software and shout-outs * https://embassy.dev/ Rust Embassy; The next-generation framework for embedded applications. The most important and core framework conforming the pillars of this project. * https://github.com/nviennot/turbo-resin Exactly the same a printhor but focused in resin printers. The Project which inspired and motivated this one. * https://github.com/marcbone/s_curve A really appreciated know-how. The current selected motion profile is based on this work, but intense reinterpretation were performed to make this project work.The book referenced by the author of s-curve is a key reading considered to conduct the goals of the motion plan. Nevertheless, our implementation is still un-mature/unproven to ask for a merge. # GCode compliancy [Draft] Gcode implementation status, as from https://reprap.org/wiki/G-code * WIP: Work In Progress * ILT: In the Long Term * TODO: To Do
M-CodeModeDescriptionStatus
M * List all supported m-codes DONE
M0 * Stop or Unconditional stop WIP
M1 * Sleep or Conditional stop WIP
M2 * Program End WIP
M3 CNC Spindle On, Clockwise WIP
LASER Laser On WIP
M4 CNC Spindle On, Counter-Clockwise WIP
LASER Laser On WIP
M5 CNC Spindle Off WIP
LASER Laser Off WIP
M6 * Tool change ILT
M7 CNC Mist Coolant On ILT
M8 CNC Flood Coolant On ILT
M9 CNC Coolant Off ILT
M10 CNC Vacuum On ILT
M11 CNC Vacuum Off ILT
M13 CNC Spindle on (clockwise rotation) and coolant on (flood) ILT
M16 CNC Expected Printer Check TODO
M17 * Enable/Power all stepper motors WIP
M18 * Disable all stepper motors WIP
M20 * List SD card WIP
M21 * Initialize SD card TODO
M22 * Release SD card TODO
M23 * Select SD file TODO
M24 * Start/resume SD print TODO
M25 * Pause SD print TODO
M26 * Set SD position ILT
M27 * Report SD print status TODO
M30 * Program Stop TODO
M31 * Output time since last M109 or SD card start to serial TODO
M32 * Select file and start SD print TODO
M33 * Get the long name for an SD card file or folder ILT
M37 * Simulation mode WIP
M73 * Set/Get build percentage TODO
M79 * Soft reset WIP
M80 * ATX Power On WIP
M81 * ATX Power Off WIP
M82 * Set extruder to absolute mode WIP
M83 * Set extruder to relative mode WIP
M92 * Set axis_steps_per_unit WIP
M104 FFF Set Hotend Temperature DONE
M105 FFF Get Hotend and/or Hotbed Temperature DONE
M106 * Fan On WIP
M107 * Fan Off WIP
M109 FFF Set Extruder Temperature and Wait WIP
M110 * Set Current Line Number WIP
M111 * Set Debug Level WIP
M112 * Full (Emergency) Stop WIP
M114 * Get Current Position DONE
M115 * Get Firmware Version and Capabilities WIP
M116 * Wait WIP
M117 * Display message WIP
M118 * Echo message on host WIP
M119 * Get Endstop Status WIP
M120 * Enable endstop detection WIP
M121 * Disable endstop detection WIP
M140 * Set hotbed Temperature (Fast) DONE
M190 * Wait for hotbed temperature DONE
M200 * Set filament diameter WIP
M201 * Set max acceleration WIP
M202 * Set max travel acceleration WIP
M203 * Set maximum feedrate WIP
M204 * Set default acceleration WIP
M205 * Advanced settings WIP
M206 * Offset axes WIP
M207 * Set retract length WIP
M208 * Set unretract length WIP
M209 FFF Enable automatic retract WIP
M210 * Set homing feedrates WIP
M211 * Disable/Enable software endstops WIP
M212 * Set Bed Level Sensor Offset WIP
M218 * Set Hotend Offset WIP
M220 * Set speed factor override percentage WIP
M221 * Set extrude factor override percentage WIP
M290 * Babystepping WIP
M302 * Allow cold extrudes WIP
M305 * Set thermistor and ADC parameters WIP
M350 * Set microstepping mode WIP
M360 * Report firmware configuration WIP
M400 * Wait for current moves to finish TODO
M401 * Deploy Z Probe TODO
M402 * Stow Z Probe TODO
M404 * Filament width and nozzle diameter WIP
M407 * Display filament diameter WIP
M410 * Quick-Stop TODO
M422 * Set a G34 Point WIP
M450 * Report Printer Mode WIP
M451 * Select FFF Printer Mode WIP
M452 * Select Laser Printer Mode WIP
M453 * Select CNC Printer Mode WIP
M500 * Store parameters in non-volatile storage TODO
M501 * Read parameters from EEPROM TODO
M502 * Restore Default Settings WIP
M503 * Report Current Settings WIP
M504 * Validate EEPROM TODO
M505 * Clear EEPROM and RESET Printer TODO
M510 * Lock Machine ILT
M511 * Unlock Machine with Passcode ILT
M512 * Set Passcode ILT
M513 * Remove Password ILT
M524 * Abort SD Printing ILT
M555 * Set compatibility ILT
M563 * Define or remove a tool ILT
M851 * Set Z-Probe Offset WIP
M862.1 * Check nozzle diameter ILT
M862.2 * Check model code ILT
M862.3 * Model name TODO
M929 * Start/stop event logging to SD card TODO
G-CodeModeDescriptionStatus
G * List all supported g-codes DONE
G0 * Rapid Move WIP
G1 * Linear Move WIP
G4 * Dwell TODO
G10 * Retract/Set coordinate system ILT
G11 * Unretract TODO
G17 * Plane Selection XY (default) TODO
G18 CNC Plane Selection ZX ILT
G19 CNC Plane Selection YZ ILT
G21 * Set Units to Millimeters WIP
G22 * Firmware Retract ILT
G23 * Firmware Recover ILT
G28 * Move to Origin (Home) TODO
G29 * Detailed Z-Probe TODO
G29.1 * Set Z probe head offset WIP
G29.2 * Set Z probe head offset calculated from toolhead position ILT
G30 * Single Z-Probe TODO
G31 * Set or Report Current Probe status TODO
G38.2 * Probe toward workpiece, stop on contact, signal error if failure ILT
G38.3 * Probe toward workpiece, stop on contact ILT
G38.4 * Probe away from workpiece, stop on loss of contact, signal error if failure ILT
G38.5 * Probe away from workpiece, stop on loss of contact ILT
G80 * Mesh-based Z probe ILT
G81 * Mesh bed leveling status ILT
G82 * Single Z probe at current location TODO
G90 * Set to Absolute Positioning DONE
G91 * Set to Relative Positioning DONE
G92 * Set Position WIP
G92.1 * Reset axis offsets (and parameters 5211-5219) to zero. (X Y Z A B C U V W) ILT
G92.2 * Reset axis offsets to zero ILT
G93 CNC Feed Rate Mode (Inverse Time Mode) ILT
G94 CNC Feed Rate Mode (Units per Minute) ILT
### 3DPrint Gcode sample M73 P0 R87 M73 Q0 S87 M201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2 M203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm / sec M204 P1250 R1250 T1500 ; sets acceleration (P, T) and retract acceleration (R), mm/sec^2 M205 X8.00 Y8.00 Z0.40 E4.50 ; sets the jerk limits, mm/sec M205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec M107 ;TYPE:Custom M862.3 P "MK3" ; printer model check M862.1 P0.4 ; nozzle diameter check G90 ; use absolute coordinates M83 ; extruder relative mode M80 ; Power on G28 W ; home all without mesh bed level G80 ; mesh bed leveling G28 X Y; Park M104 S235 ; set extruder temp M140 S60 ; set bed temp M190 S60 ; wait for bed temp M109 S235 ; wait for extruder temp G1 Z0.2 F720 G1 Y-3 F1000 ; go outside print area G92 E0 G1 X60 E9 F1000 ; intro line G1 X100 E12.5 F1000 ; intro line G92 E0 M221 S95 ; Don't change E values below. Excessive value can damage the printer. M907 E430 ; set extruder motor current G21 ; set units to millimeters G90 ; use absolute coordinates M83 ; use relative distances for extrusion ; Filament-specific start gcode M900 K0.2 M107 ;LAYER_CHANGE ;Z:0.2 ;HEIGHT:0.2 ;BEFORE_LAYER_CHANGE G92 E0.0 ;0.2 G1 E-3.1 F3000 G1 Z.4 F720 ;AFTER_LAYER_CHANGE ;0.2 G1 X76.782 Y74.538 F13200 G1 Z.2 F720 G1 E3.1 F3000 M204 P800 ;TYPE:Skirt/Brim ;WIDTH:0.42 G1 F1200 G1 X77.609 Y73.879 E.03317 G1 X90.788 Y67.532 E.45862 G1 X91.819 Y67.297 E.03317 ### Laser Gcode sample G21 G90 M206 X-45. Y-10. Z-20.; Laser offset G28; Homing G1 F3000. Z7. M107;svg#svg5 > g#layer89324 > path#rect2575 G0 X12.6508 Y109.9950 M4 S255 G1 X112.6408 Y109.9950 F3000 G1 X112.6408 Y10.0050 F3000 G1 X12.6508 Y10.0050 F3000 G1 X12.6508 Y109.9950 F3000 M5 G4