Flashing Ender3

December 2, 2018
Ender 3 Raspberry Pi

Ender 3 used in this tutorial had a 1.1.3 board. It is assumed you already have OctoPrint running on a Raspberry Pi.

Setup Arduino IDE

In my case, I am using Arduino on my main computer and will later on copy the required files to my Raspberry Pi running OctoPrint.

Download and install Arduino IDE from https://www.arduino.cc/en/Main/Software.

In the Preferences menu, under Additional Boards Manager URLs add https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json. Then go to Tools -> Boards -> Board Manager and install Sanguino package.

Because we need a specific version of u8glib package, we have to download it from https://bintray.com/olikraus/u8glib/Arduino/1.17 and install using Sketch -> Include Library -> Add .ZIP Library.

Install and configure avrdude

Flashing will be done using Raspberry Pi, so install avrdude on that system.

apt-get install avrdude

For configuration, first copy the template to your home folder.

cp /etc/avrdude.conf ~/avrdude.conf

Then open it in your editor and find the block containing:

programmer
  id = "linuxspi";
  desc = "Use Linux SPI device in /dev/spidev*";
  type = "linuxspi";
  reset = 25;
  baudrate=4000000;
;

Here, change baudrate to be that of your printer, in my case 115200 for Ender 3.

Also, at the bottom of this file add:

programmer
  id = "pi_1";
  desc = "Use the Linux sysfs interface to bitbang GPIO lines";
  type = "linuxgpio";
  reset = 17;
  sck = 24;
  mosi = 23;
  miso = 18;
;

Save and exit.

Connect Raspberry Pi to Ender 3

At this point, GPIO connections have to be made. Disconnect Ender 3 power supply as we will be powering the board via GPIO.

Ender 3 ISP pins are (looking from the front of the printer):

RST | SCK  | MISO
GND | MOSI | VCC

Use jumper cables to connect Raspberry Pi to Ender 3 in the following configuration:

3v3      => VCC
GND      => GND
GPIO 17  => RST
GPIO 18  => MISO
GPIO 23  => MOSI
GPIO 24  => SCK

To check if avrdude can talk to the printer, run:

sudo avrdude -p atmega1284p -C ~/avrdude.conf -c pi_1 -v

Flashing a bootloader

When we added Sanguino boards to Arduino, we conveniently received various bootloader .hex files. We will use the one for ATmega1284P.

# MacOS
cp ~/Library/Arduino15/packages/Sanguino/hardware/avr/1.0.2/bootloaders/optiboot/optiboot_atmega1284p.hex ~

# Linux
cp ~/.arduino15/packages/Sanguino/hardware/avr/1.0.2/bootloaders/optiboot/optiboot_atmega1284p.hex ~

Change version to match yours.

At this point, copy optiboot_atmega1284p.hex to your Raspberry Pi.

scp ~/optiboot_atmega1284p.hex pi@octopi:~/bootloader.hex

Using your Raspberry Pi, flash the bootloader by running:

cd ~
sudo avrdude -p atmega1284p -C avrdude.conf -c pi_1 -U flash:w:bootloader.hex:i

Once this is done, you can disconnect GPIO connections, and re-power Ender 3. Because we now have a bootloader, we no longer need to use GPIO to flash. We can do it using Serial over USB from now on.

Flashing Marlin firmware

Before anything else, we must fetch the latest Marlin firmware from https://github.com/MarlinFirmware/Marlin/archive/1.1.x.zip.

Extract, then from Marlin-1.1.x/Marlin/example_configurations/Creality/Ender-3 copy all files to Marlin-1.1.x/Marlin and overwrite existing files. This gives us the same configuration as we would get from stock Ender 3 firmware. In files Configuration.h and Configuration_adv.h apply changes as needed.

Make sure you have proper values for the following settings:

  • board is set to Sanguino
  • processor is set to ATmega1284 or ATmega1284P (16 Mhz)
  • programmer is set to Arduino as ISP
  • verbose output is turned on for compilation and upload (look in application preferences)

Then go to Sketch -> Verify/Compile.

If this is successful, go to Sketch -> Export Compiled Binary. After export has finished, you should see multiple files at the end of the log output. The last file in that list is .hex file (something like /var/folders/k9/119gwxs11p968dy4f21czc440000gn/T/arduino_build_343265/Marlin.ino.hex ).

Copy the compiled firmware to Raspberry Pi.

scp /var/.../Marlin.ino.hex pi@octopi:~/ender3.hex

Make sure that you have plugged Raspberry Pi to the printer using an USB cable. Then flash with:

cd ~
sudo avrdude -p atmega1284p -c arduino -P /dev/ttyUSB0 -b 115200 -U flash:w:ender3.hex:i

/dev/ttyUSB0 might be different in your case.

At this point, Ender 3 should be successfully flashed.

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9705 (probably m1284p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "ender3.hex"
avrdude: writing flash (126726 bytes):

Writing | ################################################## | 100% 23.94s

avrdude: 126726 bytes of flash written
avrdude: verifying flash memory against ender3.hex:
avrdude: load data flash data from input file ender3.hex:
avrdude: input file ender3.hex contains 126726 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 27.06s

avrdude: verifying ...
avrdude: 126726 bytes of flash verified

avrdude: safemode: Fuses OK (E:00, H:00, L:00)

avrdude done.  Thank you.

Flashing with OctoPrint

There is a wonderful plugin at https://github.com/OctoPrint/OctoPrint-FirmwareUpdater, which allows us to perform flashing using the OctoPrint web interface. Install the plugin and when asked, reboot the server.

In OctoPrint settings go to Firmware Updater under Plugins and click the wrench icon on top right corner. Add the following parameters:

  • flash method: avrdude (Atmel AVR Family)
  • AVR MCU: ATmega1284p
  • Path to avrdude: /usr/bin/avrdude
  • AVR Programmer Type: arduino
  • avrdude Baur Rate: 115200

and save.

You can now upload and flash .hex files using OctoPrint.

Bonus: getting configuration values from a running Ender 3

Using OctoPrint send a M501 command.

Send: M501
Recv: echo:V55 stored settings retrieved (655 bytes; crc 41560)
Recv: echo:  G21    ; (mm)
Recv: echo:  M149 C ; Units in Celsius
Recv: 
Recv: echo:Filament settings: Disabled
Recv: echo:  M200 D1.75
Recv: echo:  M200 D0
Recv: echo:Steps per unit:
Recv: echo:  M92 X80.00 Y80.00 Z400.00 E93.00
Recv: echo:Maximum feedrates (units/s):
Recv: echo:  M203 X500.00 Y500.00 Z5.00 E25.00
Recv: echo:Maximum Acceleration (units/s2):
Recv: echo:  M201 X500 Y500 Z100 E5000
Recv: echo:Acceleration (units/s2): P<print_accel> R<retract_accel> T<travel_accel>
Recv: echo:  M204 P500.00 R500.00 T500.00
Recv: echo:Advanced: Q<min_segment_time_us> S<min_feedrate> T<min_travel_feedrate> X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk> E<max_e_jerk>
Recv: echo:  M205 Q20000 S0.00 T0.00 X10.00 Y10.00 Z0.30 E5.00
Recv: echo:Home offset:
Recv: echo:  M206 X0.00 Y0.00 Z0.00
Recv: echo:Material heatup parameters:
Recv: echo:  M145 S0 H185 B45 F255
Recv: echo:  M145 S1 H240 B0 F255
Recv: echo:PID settings:
Recv: echo:  M301 P21.73 I1.54 D76.55
Recv: ok

Reference