I am using Marlin 2.0 to control my 3D printers, I like to be in full control so I compile my own firmware, adding my own tweaks. Most people probably use the Arduino IDE to compile and install the firmware – I am more to vi and Makefile
This post will cover how I set up my system so I can compile Marlin for multiple mainboards , while sharing the same source-code-tree, the boards/printers covered here are:
- MKS GEN v1.3 using atmega2560 as used on Tevo Tarantula
- Melzi 2.0 using atmega1284p as used on Tronxy X1
Marlin has a Makefile which with a little tweaking can compile the firmware, but there is no provision to have a common source-tree to compile for different boards/cpu’s. Let us change that.
The goal is to have a subdir per board which contains the configuration files, and object-files used during compilation. Here is how I would compile new firmware for the two printers :
$ cd Marlin-2.0.x-git/Marlin/ $ ls -l . Tarantula Tronxy_X1 -rw-r--r-- 1 peter peter 124938 Mar 19 21:32 Configuration_adv.h -rw-r--r-- 1 peter peter 82430 Mar 19 21:34 Configuration.h drwxr-xr-x 2 peter peter 3 Feb 27 2019 lib -rw-r--r-- 1 peter peter 30323 Mar 20 11:39 Makefile -rw-r--r-- 1 peter peter 1922 Mar 11 19:12 Marlin.ino drwxr-xr-x 12 peter peter 15 Mar 19 21:31 src drwxr-xr-x 3 peter peter 7 Mar 20 13:12 Tarantula drwxr-xr-x 2 peter peter 5 Mar 20 13:13 Tronxy_X1 -rw-r--r-- 1 peter peter 2535 Mar 11 19:12 Version.h Tarantula: -rw-r--r-- 1 peter peter 124225 Mar 20 11:34 Configuration_adv.h -rw-r--r-- 1 peter peter 97284 Mar 20 12:19 Configuration.h -rw-r--r-- 1 peter peter 1272 Mar 20 12:52 Makefile Tronxy_X1: -rw-r--r-- 1 peter peter 124934 Mar 19 20:12 Configuration_adv.h -rw-r--r-- 1 peter peter 84251 Mar 20 09:59 Configuration.h -rw-r--r-- 1 peter peter 1614 Mar 20 12:53 Makefile $ cd Tarantula; make ... text data bss dec hex filename 162226 370 4331 166927 28c0f objs/Tarantula.elf $ cd ../Tronxy_X1; make ... text data bss dec hex filename 129920 396 3835 134151 20c07 objs/Tronxy_X1.elf
The per board Makefiles I created are quite small, it includes the standard Makefile which contains the bulk of the rules, The Configuration files typically comes from github.com/MarlinFirmware/Configurations/archive/bugfix-2.0.x.zip and the Marlin source is from github.com/MarlinFirmware/Marlin
Makefile for Tevo Tarantula
# Makefile for Tevo Tarantula ARDUINO_INSTALL_DIR = $(HOME)/Arduino-1.8.12-x86_64 HARDWARE_MOTHERBOARD = 1110 # MKS v1.3 MCU = atmega2560 HARDWARE_VARIANT = arduino VPATH += . VPATH += .. VPATH += objs SRC_DIR = ../src BUILD_DIR = objs # Note no space allowed before comment # LIQUID_CRYSTAL ?= 1# DEFAULT 6 io-pins directly control U8GLIB ?= 0# we use a character LCD TMC ?= 0# not using Trinamic TMCStepper AVRDUDE_CONF = /etc/avrdude.conf UPLOAD_RATE = 115200 include ../Makefile
Makefile for Tronxy X1, LCD via i2c
For my Tronxy X1 the Makefile is a bit more complicated, mostly because I have modded the hardware, The Tronxy X1 is using an atmeaga1284p as CPU, the little sister to the atmega2560 with less pins and half as much FLASH. I needed an extra io-pin for a filament sensor, but there is no unused inputs, so I converted the LCD to be accessed via i2c, which uses 2 io-pins instead of 6. Marlin has support to use a 20×4 character lcd connected via i2c and a pcf8574 so the change is not complicated, but FLASH is limited, so I had to replace the i2c-driver with a leaner one.
# Makefile for Tronxy X1 # with LCD via I2C ARDUINO_INSTALL_DIR = $(HOME)/Arduino-1.8.12-x86_64 HARDWARE_MOTHERBOARD = 1502 # Melzi MCU = atmega1284p HARDWARE_VARIANT = Sanguino HARDWARE_SUB_VARIANT = sanguino VPATH += . VPATH += .. VPATH += objs MightyCore = $(HOME)/MightyCore VPATH += $(MightyCore)/avr/cores/MCUdude_corefiles VPATH += $(MightyCore)/avr/variants/sanguino VPATH += $(MightyCore)/avr/libraries/SPI/src SRC_DIR = ../src BUILD_DIR = objs # Note no space allowed before comment # LIQUID_CRYSTAL ?= 0# 6 io-pins directly controlling the LCD LIQUID_CRYSTAL_I2C ?= 0# LCD connected vi i2c pcf8574 LIQUID_CRYSTAL_I2C_TINY ?= 1# as above saves text=642 data=18 bss=182 U8GLIB ?= 0# we use character LCD TMC ?= 0# not using Trinamic TMCStepper ifeq ($(LIQUID_CRYSTAL_I2C), 1) VPATH += $(MightyCore)/avr/libraries/Wire/src VPATH += $(MightyCore)/avr/libraries/Wire/src/utility VPATH += $(HOME)/Arduino/libraries/LiquidCrystal_I2C LIB_SRC += twi.c LIB_CXXSRC += Wire.cpp LIB_CXXSRC += LiquidCrystal_I2C.cpp endif ifeq ($(LIQUID_CRYSTAL_I2C_TINY), 1) VPATH += $(HOME)/Arduino/libraries/SoftI2CMaster VPATH += $(HOME)/Arduino/libraries/LiquidCrystal_I2C_Tiny LIB_CXXSRC += SoftI2CMaster.cpp LIB_CXXSRC += LiquidCrystal_I2C_Tiny.cpp endif AVRDUDE_CONF = /etc/avrdude.conf UPLOAD_RATE = 115200 include ../Makefile
Modifcation to Marlin Makefile
My Makefiles over-ride some of settings used in the standard Makefile which is included in the end. This requires a few trivial changes is in the Marlin Makefile, ?= means that variable will only be set if not set already, and += appends a setting instead of just overriding it, some #ifdef to opt out of using the standard LCD-library, and lastly SRC_DIR can be set to direct the Makefile where to find the source-files, see the diffs below:
diff --git a/Marlin/Makefile b/Marlin/Makefile index fcd763881..4a295d5bc 100644 --- a/Marlin/Makefile +++ b/Marlin/Makefile @@ -80,6 +80,9 @@ UPLOAD_PORT ?= /dev/ttyUSB0 #on linux it is best to put an absolute path like /home/username/tmp . BUILD_DIR ?= applet +# This defines whether LiquidCrystal support will be built +LIQUID_CRYSTAL ?= 1 + # This defines whether Liquid_TWI2 support will be built LIQUID_TWI2 ?= 0 @@ -529,12 +532,14 @@ TARGET = $(notdir $(CURDIR)) # source files, but for Marlin 2.0, we use VPATH only for arduino # library files. -VPATH = . +VPATH += . VPATH += $(BUILD_DIR) VPATH += $(HARDWARE_SRC) ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino)) +ifeq ($(LIQUID_CRYSTAL), 1) VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/LiquidCrystal/src +endif VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/SPI endif @@ -546,7 +551,9 @@ ifeq ($(IS_MCU),1) VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial/src endif +ifeq ($(LIQUID_CRYSTAL), 1) VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src +endif ifeq ($(LIQUID_TWI2), 1) VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility @@ -593,7 +600,7 @@ else VPATH += $(ARDUINO_INSTALL_DIR)/hardware/$(HARDWARE_VARIANT)/variants/$(HARDWARE_SUB_VARIANT) endif -LIB_SRC = wiring.c \ +LIB_SRC += wiring.c \ wiring_analog.c wiring_digital.c \ wiring_shift.c WInterrupts.c hooks.c @@ -604,19 +611,21 @@ else endif ifeq ($(HARDWARE_VARIANT), Teensy) - LIB_SRC = wiring.c + LIB_SRC += wiring.c VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy endif -LIB_CXXSRC = WMath.cpp WString.cpp Print.cpp SPI.cpp +LIB_CXXSRC += WMath.cpp WString.cpp Print.cpp SPI.cpp ifeq ($(NEOPIXEL), 1) LIB_CXXSRC += Adafruit_NeoPixel.cpp endif -ifeq ($(LIQUID_TWI2), 0) +ifeq ($(LIQUID_CRYSTAL), 1) LIB_CXXSRC += LiquidCrystal.cpp -else +endif + +ifeq ($(LIQUID_TWI2), 1) LIB_SRC += twi.c LIB_CXXSRC += Wire.cpp LiquidTWI2.cpp endif @@ -708,7 +717,7 @@ CXXWARN = -Wall -Wno-packed-bitfield-compat -Wno-pragmas -Wu CTUNING = -fsigned-char -funsigned-bitfields -fno-exceptions \ -fshort-enums -ffunction-sections -fdata-sections ifneq ($(HARDWARE_MOTHERBOARD),) - CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD} +# CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD} endif #CEXTRA = -Wa,-adhlns=$(<:.c=.lst) CXXEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics -fno-rtti @@ -730,9 +739,9 @@ endif AVRDUDE_PORT = $(UPLOAD_PORT) AVRDUDE_WRITE_FLASH = -Uflash:w:$(BUILD_DIR)/$(TARGET).hex:i ifeq ($(shell uname -s), Linux) - AVRDUDE_CONF = /etc/avrdude/avrdude.conf + AVRDUDE_CONF ?= /etc/avrdude/avrdude.conf else - AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf + AVRDUDE_CONF ?= $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf endif AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \ -p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \ @@ -741,15 +750,17 @@ AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \ # Since Marlin 2.0, the source files may be distributed into several # different directories, so it is necessary to find them recursively -SRC = $(shell find src -name '*.c' -type f) -CXXSRC = $(shell find src -name '*.cpp' -type f) +SRC_DIR ?= src + +SRC = $(shell find $(SRC_DIR) -name '*.c' -type f) +CXXSRC = $(shell find $(SRC_DIR) -name '*.cpp' -type f) # Define all object files. OBJ = ${patsubst %.c, $(BUILD_DIR)/arduino/%.o, ${LIB_SRC}} OBJ += ${patsubst %.cpp, $(BUILD_DIR)/arduino/%.o, ${LIB_CXXSRC}} OBJ += ${patsubst %.S, $(BUILD_DIR)/arduino/%.o, ${LIB_ASRC}} -OBJ += ${patsubst %.c, $(BUILD_DIR)/%.o, ${SRC}} -OBJ += ${patsubst %.cpp, $(BUILD_DIR)/%.o, ${CXXSRC}} +OBJ += ${patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/src/%.o, ${SRC}} +OBJ += ${patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/src/%.o, ${CXXSRC}} # Define all listing files. LST = $(LIB_ASRC:.S=.lst) $(LIB_CXXSRC:.cpp=.lst) $(LIB_SRC:.c=.lst)
One of the include files also need to be modified to be able to find the configuration files in their new position.
diff --git a/Marlin/src/inc/MarlinConfigPre.h b/Marlin/src/inc/MarlinConfigPre.h index 1385f9e19..9a5d69e77 100644 --- a/Marlin/src/inc/MarlinConfigPre.h +++ b/Marlin/src/inc/MarlinConfigPre.h @@ -34,7 +34,8 @@ #include "../core/boards.h" #include "../core/macros.h" -#include "../../Configuration.h" +//#include "../../Configuration.h" +#include "Configuration.h" #ifdef CUSTOM_VERSION_FILE #if defined(__has_include) @@ -52,7 +53,8 @@ #include HAL_PATH(../HAL, inc/Conditionals_LCD.h) #include "../core/drivers.h" -#include "../../Configuration_adv.h" +//#include "../../Configuration_adv.h" +#include "Configuration_adv.h" #include "Conditionals_adv.h" #include HAL_PATH(../HAL, inc/Conditionals_adv.h)
These changes should not change Marlins ability to be compiled under the Arduino IDE.
Changes to let Tronxy X1 access its LCD via i2c
The Tronxy X1 uses a Melzi 2.0 mainboard and a 20×4 LCD with 5 buttons which is read via one analog input. I want to change the output to the LCD to go via i2c, the i2c-LCD-interface boards are available from Aliexpress for next to nothing. and takes over the control of the LCD, I just unsoldered the LCD, drilled out the holes in the current LCD/buttton-pcb, and had the connections run through to the new i2c-LCD board, scl/ada happens to be part of io-pins going to the board already, so these together with VCC and GND are connected. The buttons works as usual. Check the photo above.
The Tronxy X1 Configuration file just need a number of #define, and two files in the Marlin distribution needs an #ifdef, the diffs are below
peter@t470:Marlin> git diff src/lcd/HD44780 diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp index a032450ad..c71c09823 100644 --- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp @@ -68,6 +68,9 @@ #elif ENABLED(LCD_I2C_TYPE_PCA8574) +#ifdef LCD_I2C_TINY + SoftI2CMaster softi2c=SoftI2CMaster(PIN_WIRE_SCL,PIN_WIRE_SDA,0); +#endif LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_WIDTH, LCD_HEIGHT); #elif ENABLED(SR_LCD_2W_NL) @@ -354,7 +357,11 @@ void MarlinUI::init_lcd() { lcd.begin(LCD_WIDTH, LCD_HEIGHT); #elif ENABLED(LCD_I2C_TYPE_PCA8574) +#ifdef LCD_I2C_TINY + lcd.begin(); +#else lcd.init(); +#endif lcd.backlight(); #else diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.h b/Marlin/src/lcd/HD44780/ultralcd_HD44780.h index 12bf86a16..45b38fe54 100644 --- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.h +++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.h @@ -74,7 +74,12 @@ #define LCD_CLASS LiquidTWI2 #elif ENABLED(LCD_I2C_TYPE_PCA8574) +#ifdef LCD_I2C_TINY + #include+ #include +#else #include +#endif #define LCD_CLASS LiquidCrystal_I2C #elif ENABLED(SR_LCD_2W_NL)
The modification to Configuration.h, most of it is documentation.
--- Configurations-bugfix-2.0.x/config/examples/Tronxy/X1/Configuration.h 2020-03-10 15:59:48.000000000 -0400 +++ Configuration.h 2020-03-21 13:02:13.942851949 -0400 @@ -71,7 +71,62 @@ // @section info // Author info of this build printed to the host during boot and M115 -#define STRING_CONFIG_H_AUTHOR "(Claus Naeveke, 0.1)" // Who made the changes. +#define STRING_CONFIG_H_AUTHOR "(Peter Lorenzen, 0.1)" // Who made the changes. +/* + * (Claus Naeveke 0.1) configured Marlin 2 for Tronxy X1, file found in + * https://github.com/MarlinFirmware/Configurations/archive/bugfix-2.0.x.zip + * file: Configurations-bugfix-2.0.x/config/examples/Tronxy/X1/Configuration.h + * I have made the folowing changes: + * BAUD-rate 250000 + * extruder calibrated to geared extruder from Tevo Tarantula + * LCD changed to i2c to release pins for other use + * 10-pin 2x5 connector carries + * +-----+ + * (11) PC1 SDA -+1 2+- PA1 (30) buttons + * (10) PC0 SCL -+3 4+- PA2 (29) filament_sensor + * (17) PD3 TX1 -+5 6+- PA3 (28) + * (16) PD2 RX1 -+7 8+- PA4 (27) + * VCC -+9 10+- GND (26) + * +-----+ + * + * SDA,SCL used to control LCD + * PA1 analog input to detect buttons + * LEFT -| 470 |--+--| 4k7 |-- VCC + * RIGHT -| 4k7 |--+ + * UP -|10k |--+ + * DOWN -| 1k |--+ + * CENTER-| 2k2 |--+ + * lcd schematic: https://reprap.org/forum/file.php?406,file=74922 + * mainboard: https://reprap.org/wiki/Melzi + * + * Arduino pin 16,17,27,28 still free + * + * Filament sensor: JST connector pint(1,2,3)=(Signal,Vcc,Gnd) + */ +#define ADVANCED_PAUSE_FEATURE + +// use the buttons as is but use i2c to control LCD free's 6 pins + +#define IS_ULTIPANEL +#define LCD_I2C_TINY // use SoftI@CMAster instead of wire +#define LCD_I2C_TYPE_PCA8574 +#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander +#define LCD_WIDTH 20 +#define LCD_HEIGHT 4 + +#define ADC_KEYPAD_PIN 1 +#define BTN_EN1 -1 +#define BTN_EN2 -1 +#define ADC_KEYPAD +#define IS_RRW_KEYPAD +#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 +#define ADC_KEY_NUM 8 + // This helps to implement ADC_KEYPAD menus +#define REVERSE_MENU_DIRECTION +#define ENCODER_PULSES_PER_STEP 1 +#define ENCODER_STEPS_PER_MENU_ITEM 1 +#define ENCODER_FEEDRATE_DEADZONE 2 + //#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes) /** @@ -1814,7 +1872,7 @@ // // ANET and Tronxy 20x4 Controller // -#define ZONESTAR_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. // This LCD is known to be susceptible to electrical interference // which scrambles the display. Pressing any button clears it up. // This is a LCD2004 display with 5 analog buttons.
And voila a controller board has been saved from going to the landfils
You must be logged in to post a comment.