With the new system there are many files now. Arduino IDE is not good with handling many files. It easily becomes a pain, so we organized files in a tree into logical groups. Therefore we use PlatformIO to compile and develop the firmware.
Advantages:
Hint: PlatformIO also offers a paid plus membership. You do NOT need this. You only will need the free part that requires no account at all.
No panic, it is easy to install the 2 required tools. Just follow the steps.
PlatformIO has a extra toolbar on the left side at the bottom. From there you can test compilation (check
button)
or upload to board (fat right arrow). Before you do this you need to check the file
platformio.ini
.
It contains the different boards supported and at the top you see the active board type in
env_default
.
This defines the target compiler system and the environment that is used. By default it will autodetect the
upload port. Alternatively set in the used environment a upload_port
option that defines the
exact port.
Now it is time to have a look at the files src/Configuration.h
and
src/Configuration_io.h
which are the 2 configuration files that determine what your firmware will do and which hardware it uses.
The configuration is split into 2 files and it is very important to understand why and what content goes
where.
There is the classic Configuration.h
where you define values that are used later. therefore you
will
mostly
see
#define commands. The second file is Configuration_io.h
where all modules are defined. Here it is
important, in which order you define the modules. The rule is quite simple - you need to define a module first
before you can use it as input in an other module. For example a normal stepper driver module requires 3
output pins. So you need to define these first and can use them later.
The file consists of lots of variables that you can modify, not all are relevant to you. The default file we provide contains the typically required values already, but when you add extra modules you might want to define some additional values.
The file is divided into two parts. The top part defines most important values that are also required to configure the modules. Then find this:
// Next 7 lines are required to make the following work, do not change!
#include "pins.h"
#undef IO_TARGET
#define IO_TARGET 4
#undef CONFIG_EXTERN
#define CONFIG_EXTERN extern
#include "src/drivers/drivers.h"
#include "src/io/redefine.h"
After that you see defines that build lists containing module names created in Configuration_io.h. That way you define which modules belong to which group and how many items a group contains. For example you see a list of heaters. These need to be called to update, so we need one list that knows which heaters we have, because with the module system there is no direct match any more. Also we know an extruder uses a heater, you could also have 2 or 3 extruders share a heater or have an extruder with 2 heaters.
The following general settings are defined at the top of the configuration.h file. Most of them are not mentioned later in the specialized section, so we mention them here.
#define NUM_TOOLS 4 // Number of tools to ocntrol including cnc and laser.
#define NUM_SERVOS 1 // Number of serves available
#define MOTHERBOARD MOTHERBOARD_FELIX // Motherboard ID, see list below
#define EEPROM_MODE 1 // 0 = no eeprom support, changing eeprom mode forces copy of config values to eeprom.
#define RFSERIAL Serial
#define WAITING_IDENTIFIER "wait"
#define JSON_OUTPUT 1 // Also generate code for json output as required by panel due.
#define FEATURE_WATCHDOG 1 // Enable watchdog. Watchdog resets printer for safety if firmware hangs.
#define FEATURE_RETRACTION 1
#define NUM_AXES 4 // X,Y,Z and E for extruder A,B,C would be 5,6,7
#define PRINTLINE_CACHE_SIZE 32 // Number of moves we can cache
#define MIN_PRINTLINE_FILL 8 // Minimum moves to buffer when more are available
#define MAX_BUFFERED_LENGTH_MM 200 // Limit buffered motion length to this if move count exceed MIN_PRINTLINE_FILL
#define STEPPER_FREQUENCY 153000 // Maximum stepper frequency.
#define PREPARE_FREQUENCY 1000 // Update frequency for new blocks. Must be higher then PREPARE_FREQUENCY.
#define BLOCK_FREQUENCY 500 // Number of blocks with constant stepper rate per second.
#define VELOCITY_PROFILE 2 // 0 = linear, 1 = cubic, 2 = quintic velocity shape
#define SMALL_SEGMENT_SIZE 0.8 // Smaller segments reduce join speed to prevent vibrations causing lost steps
#define Z_SPEED 10 // Z positioning speed
#define XY_SPEED 150 // XY positioning speed for normal operations
#define E_SPEED 2 // Extrusion speed
#define G0_FEEDRATE 0 // Speed for G0 moves. Independent from set F value! Set 0 to use F value.
#define MAX_ROOM_TEMPERATURE 25 // No heating below this temperature!
#define TEMPERATURE_CONTROL_RANGE 20 // Start with controlling if temperature is +/- this value to target temperature
#define HOST_RESCUE 1 // Enable host rescue help system
#define DEBUG_RESCUE // Uncomment to add power loss entry in debug menu while printing
#define POWERLOSS_LEVEL 2 // How much time do we have on powerloss, 0 = no move, 1 = short just raise Z, 2 = long full park move
#define POWERLOSS_UP 5 // How much to move up if mode 1 is active
#define Z_PROBE_TYPE 2 // 0 = no z probe, 1 = default z probe, 2 = Nozzle as probe
#define Z_PROBE_BORDER 2 // Safety border to ensure position is allowed
#define Z_PROBE_TEMPERATURE 0 // Temperature for type 2
// 0 = Cartesian, 1 = CoreXYZ, 2 = delta, 3 = Dual X-Axis
#define PRINTER_TYPE 0
// steps to include as babysteps per 1/BLOCK_FREQUENCY seconds. Must be lower then STEPPER_FREQUENCY/BLOCK_FREQUENCY and be low enough to not loose steps.
#define BABYSTEPS_PER_BLOCK \
{ 10, 10, 10 }
Motherboard names available
Arduino Due based (SAM3X8E)For best printing results it is crucial to understand the way we handle motion and how to fine tune it. Basically there are three levels in motion algorithm with each lower level using results from levels above. In level 1 the move as send to printer is handled and put into a list of moves to be executed. This list size is defined by PRINTLINE_CACHE_SIZE and is the maximum number of moves we can cache. The bigger the value gets, the longer it takes to stop moves going on. Good values are 16-32. Main advantage of such a list is that there are no pauses between the individual moves and we can also optimize the speed profile to not slow down fully between moves.
The next level 2 takes the long moves and splits them into smaller moves of constant speed. BLOCK_FREQUENCY defines how many submoves per second will happen. While each submove runs at constant speed, the overall speed profile is defined by VELOCITY_PROFILE being linear, cubic or 5th order. WIth frequency being high enough the distinct differences in speed are small enough to have no negative effect on motion smoothness. Now please do not try to be overly clever by increasing this value to high values. Computations at this level can be quite complex for an interrupt function, so increasing it too high can cause cpu load to be over 100% and then you ruin the print. Speaking of frequency, the function to refill is called PREPARE_FREQUENCY times per second whcih must be higher then BLOCK_FREQUENCY to ensure it is always filled. We normally use double frequency but 50% higher should also suffice.
Last level 3 is where the real motor control happens. Due to precomputation in level 2 this is just running the bresenham algorithm at fixed frequency on blocks from level 2 and checking software end stops. The interrupt is run at STEPPER_FREQUENCY hertz. Again don't be greedy with the value. More frequency means CPU usage and if total CPU usage gets too high you might get wrong speeds/accelerations extra delays, watchdog triggering and other unwanted side effects. Best is to set it as low as your steps per mm * max. speed wanted allows. On cartesian printers it is easy to compute and for deltas you have to guess. Any value higher is not really a big gain. You should note that we have no stepper high delay here. At the beginning of the interrupt all stepper signals are put on low and set on high when it is their turn. If you have a stepper driver needing longer to switch, double the frequency to what you would need. Then you have at least one period high and one period low. And the fact that we have no delay increases available cpu time to use it for better things. Experts will see that the function is oversampling the required speed. As a side effect the depending axis are also moved with better timings. If you come from V1 firmware - there is no double or quad stepping any more. Due to the removed delays we can natively go much higher already.
How high you can go with each part depends on the number of axes you use, if end stops use hardware trigger or need to be polled in stepper interrupt and also the printer type. A delta printer needs to solve several square roots per level 2 block update which is much slower then a simple multiplication required for cartesian printers. A dual X printer has the additional A axis to check and compute. Also the processor type and speed matters a lot. 8 bit AVR are surely the worst solution. Due based boards are already a lot better having 32 bit and 84MHz instead of 16MHz. So they are around 10 times faster at least. On a due you can have BLOCK_FREQUENCY 500-1000 and STEPPER_FREQUENCY 100000 - 200000 depending on printer complexity. SAMD51 based boards have hardware floating point computation plus higher speed so they can get surely 50% higher. Same with STM32 based boards.
Last thing I want to note for motion is SMALL_SEGMENT_SIZE. You have normally yank per axis that limits the junction speed on successive moves. Higher values on yank create bigger shocks on the printer and cause more vibration. Without that we would like to have them at maximum speed to not need to slow down on curves. Now if we get a shock every now and then we can allow it quite high as long as you can live with the tiny ripples in print it creates. Now if you have many small segments with constant direction changes like you get when you infill between to perimeters with a width just a bit over extrusion width this can make your printer vibrate even more and if you hit resonance frequency forces add up and you might loose steps. SMALL_SEGMENT_SIZE helps to reduce these vibrations by reducing max. allowed yank in this case making printer vibrate less and not to loose steps. SMALL_SEGMENT_SIZE is the smallest segment size that will not cause any reduction. Smaller moves will be reduced by length^2/SMALL_SEGMENT_SIZE^2.
Each module gets defined by a C++ macro and has the form:
MACRO_NAME(PARAM1, PARAM2, ...)
The reason for this is complex and quite advanced, so you should only bother about it, if you need to write your own modules. In that case read the developing pages. If you only want to use existing modules, all you need to do is reading the following pages where we will describe, how to configure the modules. The order is the one you should use in Configuration_io.h to get no backward dependencies.