Note: Experimental and work in progress, documentation is incomplete and outdated.


DDPrint adds process control to FDM printer.

The process that is to be controlled is the process of extruding plastic.

This includes the feeder, a bowden tube (*) and the hotend with its heater, lets call this the extruder.

Most FDM printers have no feedback on the extruder part of the printer - they are running open loop.

That means to find the balance of printing speed (better: volumetric flow) and hotend temperature is difficult. Another problem of this open loop extrusion system is that the printer cannot react when the hotend has difficulties to deliver the current demand of flow (for example when printing the first layer or when the hotend is not hot enough yet).

To close the control loop we add a sensor to measure the performance of the extruder und use this data to control the temperature of the hotend and the speed of the printer.

The control loop is closed in two ways, an acvitve way where the speed of the printer is lowered if the hotend cannot deliver the demanded flowrate and the feeder begins to slip. The other is a feed forward way: The flowrate sensor is used to measure the characteristics of a given filament - extruder combination. The result of this measurement is a so called *material profile*.

Control of hotend temperature is called atutotemp.

Control of printer speed is done with the temperature limiter and the flowrate limiter .

(*) For the moment bowden style printers only.

Bowden style printers only?

For best results, the flowrate sensor has to be placed after the feeder. This is easy for a bowden style printer.

For direct driver printers it should be possible but it is more difficult to add the flowrate sensor into the print head (because of space requirements, heat, added weight and so on).

Auto Temp


Flowrate limiter


** Following stuff has to be reviewed **

FDM 3d printer firmware with host preprocessing and closed loop E

See last chapter in this document for a log/history.

3d printer firmware for cartesian FDM printers (ultimaker clones, atmega and stm32, like um2, ramps or jennyprinter).

This firmware is part of the ddprint printing system, which immproves a common FDM printer by a closed loop E-Axis:

Reference printer is a Ultimaker 2 with ddprint installed and some hardware modifications:, and a jennyprinter X340 now too.

Current state

Works for me.

Key features

  • Uses a incremental sensor to measure extruder flowrate at realtime to "close the loop for E". This limits the speed of the printer if feeder tends to slip.
  • Automatic measurement of feeder system caracteristics for calibration.
  • Automatic measurement of filament caracteristics to create filament profiles .
  • "Auto temperature algorithm": hotend temperature depends on the gcode-requested flowrate.
  • "Temperature-flowrate limiter": speed of printer is limited if hotend has not (yet) the right temperature for the requested flowrate.
  • Extruder pressure advance, of course ;-)

Main part is the Flowrate Sensor realized with a Bourns EMS22AFS incremental encoder:


Firmware part


  • Arduino code/libraries and avr compiler
  • Arduino-Makefile
  • SdCard library
  • Protothreads header

Install them along the checked out ddprint sources so that the directory structure looks like this:

├── ddprint
│   ├── LICENSE
│   ...
├── arduino-1.6.13
│   ├── arduino
│   ...
├── Arduino-Makefile
│   ├──
│   ...
├── SdFat-1.0.5
│   ...
│   └── src
├── protothreads-cpp
│   ├── LICENSE.txt
│   ...

The following versions are used at the moment (maybe newer versions will also work):

Arduino IDE 1.6.13, installed from downloaded archive.

Arduino-Makefile from
    commit c3fe5dcc2fbd5c895b032ca5a5a1f60af163b744
    Merge: 7a26a86 6d3d973
    Author: Simon John <>
    Date:   Thu Dec 28 18:05:18 2017 +0000

SdFat-1.0.5, installed from downloaded zip archive (,
apply ddprint/patches/SdFat-1.0.5.patch.

Protothreads from
    commit 984aa540dd4325b7e23dc76135ca28a36526f0c6
    Author: Ben Hoyt <>
    Date:   Tue Dec 4 16:48:52 2018 -0500

    Apply ddprint/patches/protothreads-cpp.patch

Build and upload firmware

Note:keep a backup of your previous firmware in case you want to go back.
Note:ddPrint does not use EEProm.

For a ultimaker UM2 do:

make -f Makefile.fw
make -f Makefile.fw do_upload

For a ramps based printer do:

make -f Makefile.ramps
make -f Makefile.ramps do_upload
Todo:Add info about configuration.

Host part


  • apt-get install python python-serial
  • pip install npyscreen vor the TUI (

No installation procedure yet, checkout the repository and run or from the ddprint/host subdirectory.


Parts of printer configuration hardcoded in firmware, parts come from printer profile at runtime.

Todo:describe configuration.

Only one setting stored in printer: the printer name.

Todo:describe printer name setting.

Gcode input

Easier slicing, simple gcode

Note:Simplify3d is used as of this writing.

Use mostly plain gcode with ddprint, many of the advanced features of the slicers (i call it slicer hacks) are not needed, see

The (automatically measured) material profile gives a picture of the hotend melting capacity for a given machine/filament combination. This eases the determination of a good printing speed.

Simplify3d example slicer settings in

Usage, Commandline Interface

Machine setup and calibration


Store printer name in printer's runtime config (on mass storage device):

./ setPrinterName UM2-1

See also: getprintername command.


Get current endstop state.

./ getEndstops


Machine setup and calibration: Automatically determine extruder e-steps value for printer profile:

./ calibrateesteps

Example screencast:


Machine setup and calibration: Automatically determine flowrate sensor calibration value for printer profile:

./ calibratefilsensor

Example screencast:


Test e-steps and flowrate sensor calibration:

./ testFilSensor UM2-2 100

Autotune hotend PID, autoTune

Run PID autotune to determine the hotend PID parameters:

./ autoTune petg_1.75mm
cd pid_tune
PYTHONPATH=.. ./ ../autotune.raw.json


Todo:describe command

Material measurment

Measure material profile, measureTempFlowrateCurve

Extrude some filament into air and measure the material properties (melting capacity, temperatures) of this machine/filament combination.

./ measureTempFlowrateCurve nozzle80 petg_1.75mm 2.5



./ home


Heat hotend and start filament insertion process.

./ removeFilament petg_1.75mm


Heat hotend and pull back/remove filament.

./ removeFilament petg_1.75mm

Preprocess gcode file, pre

Preprocess a gcode file, this parses the given gcode file and runs all processing steps without actually sending anything to the printer. Used for development, debugging and to check if a given gcode file can be processed by ddprint.

./  -smat esun_petg_transparent-orange-6-922572-263079 pre UM2-1 nozzle80 petg_1.75mm quader_10x20.gcode

Misc commands


Switch off stepper current, printer no longer homed after that.

./ disableSteppers

Manual movement, moverel

Move axis relative to current position.

./ moverel X 100

Manual movement, moveabs

Move axis to absolute position.

./ moveabs X 0


Todo:describe command


Get current position of filament sensor

./ getFilSensor


Get current printer free memory.

./ getFreeMem


Get current printer positions.

./ getpos

Read printer name from printer, getPrinterName

Read printer name from printer, stored on mass storage device (sdcard, usbmemory).

./ getprintername


Get bed- and hotend temperatures from printer.

./ getTemps


./ getStatus

Usage, Userinterface (TUI)

Print a gcode file with the TUI:

./  -smat esun_petg_transparent-orange-6-922572-263079 nozzle80 petg quader_10x20.gcode

Some implementation notes

Host side preprocessing and stepgeneration

The software is split into two main parts:

  • The host part where the cpu intensive work (gcode preprocessing, path planning, lookahead, acceleration, advance...) is done. The host part is written in Python.
  • And the firmware part that runs on the ATMega Controller in the printer. This part executes the move commands from the host and does other things like the temperature control of the printer.
  • Host software and printer firmware are connected through the usual atmega rs232 USB emulation.

Use printers SD card as a swap device

To overcome the limited memory of the atmega, the unused SD card is converted to something like a swap device: It buffers the received data. This decouples the USB transfer and actual use of the received data, too. The SD card is used in 'raw/blockwise mode' without a filesystem on it.

Working SD cards

Not all cards are working in SPI mode, some fail to initialize, some freeze after some time. See, also.

Some working ones:

  • The ones that come with your printer should work.
  • SandDisk, 2Gb, SD
  • SandDisk, 2Gb, Micro-SD
  • SandDisk, 4Gb, SDHC, Class 2
  • SandDisk, 4Gb, SDHC, Class 4

Not working ones:

  • MediaRange, 4Gb, SDHC, Class 10


AutoTemp algorithm: the hotend temperature is increased for parts of the model where high printing speeds are reached and vice-versa.


The firmware part is implemented using the great protothreads library:, thanks for this work.


  • Look ahead path planning with linear acceleration ramps.
  • Hardened USB communication using COBS encoding and CCITT checksums in BOTH directions.
  • Simulator mode for testing/development: Firmware runs as a host-program with serial communication over a ptty device.
  • Debugging: plot/display generated acceleration ramps

Things todo, nice to have

  • Improve documentation, examples, videos.
  • Cleanup and stabilisation, make binary releases.
  • Python3 port (currently python 2.7).
  • Other convenient things like automatic bedleveling and so on.


Thanks to all open/free software people that make this all possible.


Fri Oct 15 18:32:30 CEST 2021

Merged *next branch* into master with the following changes:

Porting ddprint to Ender5 (pro):

  * Changes for the Creality melzi board (atmega1284p based).
  * Added thermistor table for epcos 100k ntc.
  * Declared IO-pins in firmware/pins_ender3.h
  * Rework homing:
    + use feedrate and direction for homing from printerprofile.
    + Move away from nozzle after z is homed (for printers that
      home at z=0. This is to avoid scratching over the bed when
      homing X and Y.
    + Homing: added "4 point mode" for ender.
  * Added new script ** to generate thermistor
    tables (c-code).

Other changes:

  * Host: rework *getstatus* and *mon* commands.
  * Host: filament profile measurement:
    + measure2: increase printing speed with fixed
      temperature while monitoring feeder grip.
    + measure2: changes to reduce heating effect of
      heated bed, start measurement on fifth layer.
    + specify minimum grip value on commandline (instead of
      hardcoded value).
    + write measured material profile to ./mat-profile2.add.
  * Host, *removefilament* command: changed feeding
    sequence to avoid filament plug.
  * Host, Experimental: added *reconnect* command.
    To reconnect to a running printer, works after
    download is complete, but not if disconnected
    while downloading stepper data.
  * Host: Added *ddprint version* command.

  * Firmware: cleanup flowrate measurement,
    measure short moves, too.
  * Firmware: added CmdGetVersion command.
  * Firmware, Makefile: new target *make gitversion.cpp*
  * Firmware: set printer state to idle if steppers are
    disabled (cmd *disablesteppers*).
  * Firmware: Update to SdFat-1.1.4 library (USE_SD_CRC enabled).
  * Firmware: Rework mass storage erase: new commands CmdGetCardSize
    and CmdErase. Call erase before printing.
  * Firmware: Sd card init: retry up to 5 times.

  * Many smaller fixes/improvements

Fri Oct 15 13:18:01 CEST 2021

Reworked flowrate sensor housing:

 * Rotated design to shorten filament path between
   feeder gear wheel and rotary encoder for better response.
 * Made it i bit more compact.

STL files are here:
See some images here:

Fri Jun 25 09:49:51 CEST 2021

Merged *next* branch into master, changes are:

* Flowrate/grip measurement:
* Added a experimental reprap usbserial interface using a pseudo-tty to use OctoPrint
  as a frontend for ddPrint. Not much functionality yet: display temperatures and some
  SD card commands (stubs).
* Flowrate limiter: max. slowdown now four times instead of 16.

Wed Jun 16 23:47:01 CEST 2021

Current development (cleanup, minor fixes, documentation) is done on *next* branch.
Adding asciinema screencast to show how to use ddPrint.

Wed Jun  9 21:17:22 CEST 2021

Merged *fix-avr* branch into master.

Tue Jun  8 14:41:41 CEST 2021

Pushed fix-avr branch to github. The JennyPrinter port made the avr/atmega side to slow.
Changes are:

* Integer math instead of floating point.
* Reworked usb-serial interface: store 512byte blocks.
* Removed compression with zlib, the avr has not enough cpu cycles.
* Experiment: auto-baudrate. Switch between 1000000, 500000 and 250000 baud.
* SDReader: double-buffering.
* Many other improvements and cleanup.

So for now, fix-avr is the branch to use for avr/atmega based printers and master is for
the stm32 JennyPrinter. Branch fix-avr has will be merged into master.