Vanilla Marlin Firmware configured for Ender 3 + BLTouch


Please check the new article for Marlin 2 and BLTouch up to 3.x on Ender 3 although be aware that the version I recommend for 8-bit boards is the 1.1.9.


This is the 1.1.9 version of vanilla Marlin Firmware pre-configured for Creality Ender 3 printers with the original or generic BL Touch sensors. The standard configuration file from Marlin distribution was carefully reviewed to include the latest Ender 3 specific settings from the official Creality firmware.

I made avaliable the 2.x versions of Marlin for the same board and printer but I recommend using the 1.1.9.x because it is much more stable and has more features. The 2.x versions of Marlin are too big for the board memory and several features had to be removed in order to fit the firmware.


  • Official Marlin firmware with all hardware settings from Creality latest official firmware (March 2020).
  • BLTouch original/generic up to 3.x. enabled by default.
  • No need to remove any capacitors from the board.
  • Installs from the original Arduino IDE (smaller download and frequent updates from Arduino team).
  • Source code was modified to prevent releasing the BLTouch sensor during "beep" events triggered by LCD menus.
  • Thermal runway protection enabled.
  • Does not reset the bed level settings after the G28 (Home) command.
  • Custom menu with maintenance mode, emergency mode and full auto bed leveling sequence (warmup, wait, home, level and then save settings).
  • Ultra-precise bilinerar bed leveling algorithm with 25 probing points and slow probing (takes around 5 minutes to complete, 10 including the bed heating).
  • Run and toggle the bed level and BLTouch tools from LCD menus.
  • Slim menus enabled.
  • Baby steps enabled and configured for the "Magic Numbers".
  • All changes from the original Marlin config file were marked with the comment tag "Customized DBP"


  • BLTouch installed on pin 27
  • Z stop switch removed (it can block the Z axis movement)
  • IMPORTANT! BLTouch tip height must be adjusted according to the official instruction manuals. There are different BLTouch sensors and the YouTube videos tips are most of the times wrong
  • Bootloader installed
  • Arduino IDE
  • About 10 minutes of your life


    1. Quit any software that could try to access the printer from the USB port (Cura, Serial Monitor, OctoPrint, etc...).
    2. Configure the Arduino IDE to download the Sanguino board. Add the following URL to the board manager (File->Preferences->Additional boards manager):


    3. Install the following libraries/boards in the Arduino IDE:
      • U8Glib
      • Sanguino
    4. With all requirements in place unpack this entire Marlin distribution to a folder and open the "Marlin.ino" file from the Arduino IDE.
    5. Look for the configuration.h file and change the following lines to the relative coordinates of your BLTouch mount to the Nozzle. The actual settings are for this mount. If you don't have the measurements now you can configure it later with the M851 GCode (see instructions below).


    6. Compile and upload the firmware. Make sure you are using the following settings.
      • Board configuration: ATMega 1284P 16Mhz
      • Programmer configuration: AVRISP MKII
      • COM Port: Depends of your computer. Usually only one is available for selection.
    7. Follow the post-installation instructions below.

    Installing the pre-compiled HEX

    The pre-compiled firmware is also available here. You can simply burn the compiled HEX file directly to your Ender3 board without installing the Arduino IDE.

    To upload the pre-compiled firmware you will need the AVRDUDE 6.3 tool. For your convenience I included the Windows version of this tool in the zip file that contains the HEX firmware but the tool is also shipped with the Arduino IDE. The upload command in Windows PowerShell should look like this:

    ./avrdude -p atmega1284p -c arduino -P COM3 -b 115200 -v -U flash:w:firmware.hex:i 

    The serial port is something between COM1 and COM8, depending on where the USB driver is pointing to, and firmware.hex is the file you are uploading. If you are using other operating system like Linux the port address will be somehting like this /dev/ttyUSB0.

    After initializing the board with the new firmware don't forget to reconfigure the probe offsets running the following command from any serial terminal. Replace the default offset values in the command (-42, -5, 0) with the ones for your probe mount.

    M851 X-42 Y-5 Z0

    Finally, follow the post-installation instructions below.

    Post-installation configuration

    1. Manually pre-level the bed! This is important because the BLTouch has limited max/min detection ranges and the print quality can be affected if the Z-Axis moves too much.
      1. Cool down the bed and the nozzle. Heating should have little to no effect on this specific procedure.
      2. Disable stepper motors using the LCD menu command.
      3. Place a credit card on one the bed, the thickness of the card will be used as a reference distance.
      4. Turn the Z axis with your hand until the nozzle hits the credit card.
      5. Move hot end to several positions of the bed, starting from the 4 corners. For each position, adjust the bed level knobs to keep the nozzle at the credit card thickness distance from the nozzle. This is what you would do in manual calibration but instead of using a paper you will use the card for convenience. The card thickness does not matter because the BLTouch probe will redefine the Z reference.
    2. Heat the bed to the printing temperature and run the bed level command from the LCD (Prepare -> Bed Leveling -> Level bed)  or using the G29 gcode or using the Heat and Level command from the custom menu (recommended). Note that the Heat and Level command waits 2 minutes after the bed is hot to allow the mounted surfaces to expand/contract properly.
    3. Save the settings using the LCD menu or the M500 gcode (if you used the Heat and Level custom command, they will be automatically saved).
    4. Add the following gcode to the startup code of you slicer, right after the line of the G28 command to load the bed level configuration from the memory before every print:
      M420 S1

    5. After enabling the bed level, print something large and flat to adjust the Z offset. The nozzle will always be far from the bed until you adjust the offset to a negative value (LCD -> Prepare -> Bed Leveling -> Z Offset). Don't forget to save the settings after the print to keep the offset in the memory, you can use the LCD or the M500 GCode for this.
    Arduino IDE
    File size
    4.7 MB
    File 1 SHA256: 4E3FB25F95412351B474F860D8FD24EC1CD0E7B910B27FFE3903B73CAB3E682A
    File 2 SHA256: 1696E8C2ACBFC454FA459EE5A67D53C868B3CE9AFE0DD787BBCFDCFBDCAA01D7
    File 3 SHA256: A2E68888DDDFCE599A8AE0DFD8891F65FF914F9CFA8FED91D6FEEB0390D9F51F

    Post Categories


    Submitted by Bias on Thu, 04/02/2020 Permalink


    I flashed your version for my Ender 3 today but my BLTouch isn't working.

    The Selftest and so on is working well, but if I start the autoleveling, the process starts but sometimes the BLTouch starts blinking red, while the Z-Axis is moving higher and higher.

    I already tried another cable, another BLtouch and also another adapter for the display port on the mainboard.

    Do you have any idea why it's not working for me?



    Submitted by CF on Fri, 01/17/2020 Permalink



    Thanks for the detailed conf. Seems as a perfect starting point for a noob like me usinf marlin and bltouch.

    Could you give a short advice what to change for bltouch 3.1?




    Submitted by Anonymous on Tue, 12/17/2019 Permalink

    Here I have a small list of errors with this sketch.

    ultralcd.cpp:3869:156: error: unterminated argument list invoking macro "_UxGT"

                 MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM, &planner.filament_size[0], 1.5f, 3.25f, planner.calculate_volumetric_multipliers);

    In file included from sketch\ultralcd.cpp:98:0:


    sketch\ultralcd.cpp:3869:57: note: in expansion of macro 'MSG_FILAMENT_DIAM'

                 MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM, &planner.filament_size[0], 1.5f, 3.25f, planner.calculate_volumetric_multipliers);

    exit status 1
    unterminated argument list invoking macro "_UxGT"

    Any Idea how to fix? Some of the "language" errors I can fix easely but all the rest? No idea. I'm thankful for any help on this.

    Submitted by Anonymous on Thu, 12/12/2019 Permalink


    in Make Magazin Germany they used your firmware (bugfix, configuration) for use with BL Touch ( Whats the background, why this firmware will not work with BLTouch 3.x ? In the article is nothing mentioned, regarding this issue?



    Submitted by Celso Rossi on Mon, 12/02/2019 Permalink

    Excellent job!

    I installed on ender 3 and it was perfect!


    Do you have these settings for Marlin 2.0 with bug fixes?

    I am still figuring out what features from Marlin 2 I will port to this custom Ender 3 compilation. The problem is that due memory size restrictions, we get more features with 1.1.9 than with the 2.0.

    EDIT: The Marlin 2.x version with BLTouch up to 3.1 is now available for download.

    LATEST EDIT: The Marlin now support the BLTouch 3.x.

    Submitted by Tobias on Wed, 05/29/2019 Permalink

    hi! just want to say thankyou for this. helped me get bltouch working and functioning properly!

    Submitted by mattes on Mon, 04/29/2019 Permalink


    i get this error, when compiling your firmware for Ender3


    unterminated argument list invoking macro "_UxGT"

    what can i do ?


    Do you have more details about this error? Did you modified any file or translation?

    This error appears when the files are corrupted or some expression was left open.


    Downloaded the package, rebuilt and recompiled from zero. No problems found!

    Just to make sure, here are the library versions I used used:

    • Sanguino 1.0.3
    • U8Glib 1.19.1
    • Arduino IDE 1.8.9 on Windows 10

    And here is the compilation stats:

    Sketch uses 129176 bytes (99%) of program storage space. Maximum is 130048 bytes.
    Global variables use 6657 bytes (40%) of dynamic memory, leaving 9727 bytes for local variables. Maximum is 16384 bytes.