Bump to head, add new filament sensor type

This commit is contained in:
InsanityAutomation
2018-09-30 15:25:02 -04:00
parent d9ff0c86ab
commit 34255f82b8
86 changed files with 2718 additions and 1206 deletions
+10
View File
@@ -439,10 +439,20 @@
*/
#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
#define XYZE_N (XYZ + E_STEPPERS)
#if ENABLED(HANGPRINTER)
#define NUM_AXIS_N (ABCD + E_STEPPERS)
#else
#define NUM_AXIS_N (XYZ + E_STEPPERS)
#endif
#define E_AXIS_N (E_AXIS + extruder)
#else
#undef DISTINCT_E_FACTORS
#define XYZE_N XYZE
#if ENABLED(HANGPRINTER)
#define NUM_AXIS_N ABCDE
#else
#define NUM_AXIS_N XYZE
#endif
#define E_AXIS_N E_AXIS
#endif
+69 -22
View File
@@ -29,7 +29,7 @@
#define CONDITIONALS_POST_H
#define IS_SCARA (ENABLED(MORGAN_SCARA) || ENABLED(MAKERARM_SCARA))
#define IS_KINEMATIC (ENABLED(DELTA) || IS_SCARA)
#define IS_KINEMATIC (ENABLED(DELTA) || IS_SCARA || ENABLED(HANGPRINTER))
#define IS_CARTESIAN !IS_KINEMATIC
/**
@@ -47,7 +47,7 @@
#define Y_BED_SIZE Y_MAX_LENGTH
#endif
// Require 0,0 bed center for Delta and SCARA
// Require 0,0 bed center for Delta, SCARA, and HANGPRINTER
#if IS_KINEMATIC
#define BED_CENTER_AT_0_0
#endif
@@ -68,6 +68,18 @@
#define Y_MIN_BED (Y_CENTER - (Y_BED_SIZE) / 2)
#define Y_MAX_BED (Y_CENTER + (Y_BED_SIZE) / 2)
/**
* Dual X Carriage
*/
#if ENABLED(DUAL_X_CARRIAGE)
#ifndef X1_MIN_POS
#define X1_MIN_POS X_MIN_POS
#endif
#ifndef X1_MAX_POS
#define X1_MAX_POS X_BED_SIZE
#endif
#endif
/**
* CoreXY, CoreXZ, and CoreYZ - and their reverse
*/
@@ -117,7 +129,7 @@
#ifdef MANUAL_X_HOME_POS
#define X_HOME_POS MANUAL_X_HOME_POS
#elif ENABLED(BED_CENTER_AT_0_0)
#if ENABLED(DELTA)
#if ENABLED(DELTA) || ENABLED(HANGPRINTER)
#define X_HOME_POS 0
#else
#define X_HOME_POS ((X_BED_SIZE) * (X_HOME_DIR) * 0.5)
@@ -133,7 +145,7 @@
#ifdef MANUAL_Y_HOME_POS
#define Y_HOME_POS MANUAL_Y_HOME_POS
#elif ENABLED(BED_CENTER_AT_0_0)
#if ENABLED(DELTA)
#if (ENABLED(DELTA) || ENABLED(HANGPRINTER))
#define Y_HOME_POS 0
#else
#define Y_HOME_POS ((Y_BED_SIZE) * (Y_HOME_DIR) * 0.5)
@@ -409,17 +421,17 @@
#if HAS_DRIVER(TB6560)
#define MINIMUM_STEPPER_DIR_DELAY 15000
#elif HAS_DRIVER(TB6600)
#define MINIMUM_STEPPER_DIR_DELAY 1500
#define MINIMUM_STEPPER_DIR_DELAY 1500
#elif HAS_DRIVER(DRV8825)
#define MINIMUM_STEPPER_DIR_DELAY 650
#define MINIMUM_STEPPER_DIR_DELAY 650
#elif HAS_DRIVER(LV8729)
#define MINIMUM_STEPPER_DIR_DELAY 500
#define MINIMUM_STEPPER_DIR_DELAY 500
#elif HAS_DRIVER(A4988)
#define MINIMUM_STEPPER_DIR_DELAY 200
#elif HAS_TRINAMIC || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE)
#define MINIMUM_STEPPER_DIR_DELAY 20
#define MINIMUM_STEPPER_DIR_DELAY 200
#elif HAS_TRINAMIC || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE)
#define MINIMUM_STEPPER_DIR_DELAY 20
#else
#define MINIMUM_STEPPER_DIR_DELAY 0 // Expect at least 10µS since one Stepper ISR must transpire
#define MINIMUM_STEPPER_DIR_DELAY 200 // Expect at least 10µS since one Stepper ISR must transpire
#endif
#endif
@@ -427,33 +439,33 @@
#if HAS_DRIVER(TB6560)
#define MINIMUM_STEPPER_PULSE 30
#elif HAS_DRIVER(TB6600)
#define MINIMUM_STEPPER_PULSE 3
#define MINIMUM_STEPPER_PULSE 3
#elif HAS_DRIVER(DRV8825)
#define MINIMUM_STEPPER_PULSE 2
#define MINIMUM_STEPPER_PULSE 2
#elif HAS_DRIVER(A4988) || HAS_DRIVER(LV8729)
#define MINIMUM_STEPPER_PULSE 1
#elif HAS_TRINAMIC || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE)
#define MINIMUM_STEPPER_PULSE 0
#define MINIMUM_STEPPER_PULSE 1
#elif HAS_TRINAMIC || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE)
#define MINIMUM_STEPPER_PULSE 0
#else
#define MINIMUM_STEPPER_PULSE 2
#define MINIMUM_STEPPER_PULSE 1
#endif
#endif
#ifndef MAXIMUM_STEPPER_RATE
#if HAS_DRIVER(TB6560)
#define MAXIMUM_STEPPER_RATE 15000
#define MAXIMUM_STEPPER_RATE 15000
#elif HAS_DRIVER(LV8729)
#define MAXIMUM_STEPPER_RATE 130000
#elif HAS_DRIVER(TB6600)
#define MAXIMUM_STEPPER_RATE 150000
#elif HAS_DRIVER(DRV8825)
#define MAXIMUM_STEPPER_RATE 250000
#elif HAS_TRINAMIC || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE)
#elif HAS_TRINAMIC || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE)
#define MAXIMUM_STEPPER_RATE 400000
#elif HAS_DRIVER(A4988)
#define MAXIMUM_STEPPER_RATE 500000
#else
#define MAXIMUM_STEPPER_RATE 250000
#define MAXIMUM_STEPPER_RATE 500000
#endif
#endif
@@ -717,11 +729,33 @@
#define HAS_E4_MICROSTEPS (PIN_EXISTS(E4_MS1))
#define HAS_SOLENOID_4 (PIN_EXISTS(SOL4))
#if ENABLED(HANGPRINTER)
#define HAS_A_ENABLE (PIN_EXISTS(A_ENABLE))
#define HAS_A_DIR (PIN_EXISTS(A_DIR))
#define HAS_A_STEP (PIN_EXISTS(A_STEP))
#define HAS_A_MICROSTEPS (PIN_EXISTS(A_MS1))
#define HAS_B_ENABLE (PIN_EXISTS(B_ENABLE))
#define HAS_B_DIR (PIN_EXISTS(B_DIR))
#define HAS_B_STEP (PIN_EXISTS(B_STEP))
#define HAS_B_MICROSTEPS (PIN_EXISTS(B_MS1))
#define HAS_C_ENABLE (PIN_EXISTS(C_ENABLE))
#define HAS_C_DIR (PIN_EXISTS(C_DIR))
#define HAS_C_STEP (PIN_EXISTS(C_STEP))
#define HAS_C_MICROSTEPS (PIN_EXISTS(C_MS1))
#define HAS_D_ENABLE (PIN_EXISTS(D_ENABLE))
#define HAS_D_DIR (PIN_EXISTS(D_DIR))
#define HAS_D_STEP (PIN_EXISTS(D_STEP))
#define HAS_D_MICROSTEPS (PIN_EXISTS(D_MS1))
#endif
// Trinamic Stepper Drivers
#define HAS_STEALTHCHOP (HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2208))
#define HAS_STALLGUARD (HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2660))
#define HAS_STALLGUARD HAS_DRIVER(TMC2130)
#define AXIS_HAS_STEALTHCHOP(ST) ( AXIS_DRIVER_TYPE(ST, TMC2130) || AXIS_DRIVER_TYPE(ST, TMC2208) )
#define AXIS_HAS_STALLGUARD(ST) ( AXIS_DRIVER_TYPE(ST, TMC2130) || AXIS_DRIVER_TYPE(ST, TMC2660) )
#define AXIS_HAS_STALLGUARD(ST) AXIS_DRIVER_TYPE(ST, TMC2130)
#if ENABLED(SENSORLESS_HOMING)
// Disable Z axis sensorless homing if a probe is used to home the Z axis
@@ -1367,4 +1401,17 @@
#define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE))
#endif
/**
* MOV_AXIS: number of independent axes driving the tool head's translational movement
* NUM_AXIS: number of movement axes + 1
* NUM_AXIS_N: number of movement axes + number of extruders (defined elsewhere)
*/
#if ENABLED(HANGPRINTER)
#define MOV_AXIS ABCD
#define NUM_AXIS ABCDE
#else
#define MOV_AXIS XYZ
#define NUM_AXIS XYZE
#endif
#endif // CONDITIONALS_POST_H
+8 -2
View File
@@ -31,6 +31,8 @@
* Enables a filament sensor plugged into the laser pin. Disables the laser
*/
//#define FilamentSensor
//#define ledgeFilSensor //Modify filament sensor contact type for TM3D V2 sensors
/**
* Configuration.h
*
@@ -900,7 +902,11 @@
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
#define FIL_RUNOUT_INVERTING true // set to true to invert the logic of the sensor.
#if ENABLED(ledgeFilSensor)
#define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor.
#else
#define FIL_RUNOUT_INVERTING true // set to true to invert the logic of the sensor.
#endif
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
#define FIL_RUNOUT_PIN 4
#define FILAMENT_RUNOUT_SCRIPT "M600"
@@ -1078,7 +1084,7 @@
#endif
// Add a menu item to move between bed corners for manual bed adjustment
//#define LEVEL_BED_CORNERS
#define LEVEL_BED_CORNERS
#if ENABLED(LEVEL_BED_CORNERS)
#define LEVEL_CORNERS_INSET 30 // (mm) An inset for corner leveling
+6 -6
View File
@@ -198,7 +198,7 @@
destination[X_AXIS] = current_position[X_AXIS];
destination[Y_AXIS] = current_position[Y_AXIS];
destination[Z_AXIS] = z; // We know the last_z==z or we wouldn't be in this block of code.
destination[E_AXIS] = current_position[E_AXIS];
destination[E_CART] = current_position[E_CART];
G26_line_to_destination(feed_value);
set_destination_from_current();
@@ -212,7 +212,7 @@
destination[X_AXIS] = rx;
destination[Y_AXIS] = ry;
destination[E_AXIS] += e_delta;
destination[E_CART] += e_delta;
G26_line_to_destination(feed_value);
set_destination_from_current();
@@ -254,7 +254,7 @@
while (!is_lcd_clicked()) {
lcd_chirp();
destination[E_AXIS] += 0.25;
destination[E_CART] += 0.25;
#ifdef PREVENT_LENGTHY_EXTRUDE
Total_Prime += 0.25;
if (Total_Prime >= EXTRUDE_MAXLENGTH) return G26_ERR;
@@ -283,7 +283,7 @@
lcd_quick_feedback(true);
#endif
set_destination_from_current();
destination[E_AXIS] += g26_prime_length;
destination[E_CART] += g26_prime_length;
G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
set_destination_from_current();
retract_filament(destination);
@@ -697,7 +697,7 @@
if (turn_on_heaters() != G26_OK) goto LEAVE;
current_position[E_AXIS] = 0.0;
current_position[E_CART] = 0.0;
sync_plan_position_e();
if (g26_prime_flag && prime_nozzle() != G26_OK) goto LEAVE;
@@ -812,7 +812,7 @@
const float endpoint[XYZE] = {
ex, ey,
g26_layer_height,
current_position[E_AXIS] + (arc_length * g26_e_axis_feedrate * g26_extrusion_multiplier)
current_position[E_CART] + (arc_length * g26_e_axis_feedrate * g26_extrusion_multiplier)
};
if (dist_start > 2.0) {
-2
View File
@@ -152,8 +152,6 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t freque
#define _CAT(a, ...) a ## __VA_ARGS__
#define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare)
#define HAL_timer_restrain(timer, interval_ticks) NOLESS(_CAT(TIMER_OCR_, timer), _CAT(TIMER_COUNTER_, timer) + interval_ticks)
#define HAL_timer_get_compare(timer) _CAT(TIMER_OCR_, timer)
#define HAL_timer_get_count(timer) _CAT(TIMER_COUNTER_, timer)
+2 -3
View File
@@ -530,9 +530,8 @@ CSTANDARD = -std=gnu99
CXXSTANDARD = -std=gnu++11
CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -w -ffunction-sections -fdata-sections \
-flto \
CTUNING = -w -fsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -ffunction-sections -fdata-sections -flto \
-DARDUINO=$(ARDUINO_VERSION)
ifneq ($(HARDWARE_MOTHERBOARD),)
CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
+94 -3
View File
@@ -96,7 +96,10 @@ extern const char axis_codes[XYZE];
/**
* Mixing steppers synchronize their enable (and direction) together
*/
#if MIXING_STEPPERS > 3
#if MIXING_STEPPERS > 4
#define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); E3_ENABLE_WRITE( E_ENABLE_ON); E4_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); E3_ENABLE_WRITE(!E_ENABLE_ON); E4_ENABLE_WRITE(!E_ENABLE_ON); }
#elif MIXING_STEPPERS > 3
#define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); E3_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); E3_ENABLE_WRITE(!E_ENABLE_ON); }
#elif MIXING_STEPPERS > 2
@@ -159,6 +162,42 @@ extern const char axis_codes[XYZE];
#endif // !MIXING_EXTRUDER
#if ENABLED(HANGPRINTER)
#define enable_A() enable_X()
#define enable_B() enable_Y()
#define enable_C() enable_Z()
#define __D_ENABLE(p) E##p##_ENABLE_WRITE(E_ENABLE_ON)
#define _D_ENABLE(p) __D_ENABLE(p)
#define enable_D() _D_ENABLE(EXTRUDERS)
// Don't allow any axes to be disabled
#undef disable_X
#undef disable_Y
#undef disable_Z
#define disable_X() NOOP
#define disable_Y() NOOP
#define disable_Z() NOOP
#if EXTRUDERS >= 1
#undef disable_E1
#define disable_E1() NOOP
#if EXTRUDERS >= 2
#undef disable_E2
#define disable_E2() NOOP
#if EXTRUDERS >= 3
#undef disable_E3
#define disable_E3() NOOP
#if EXTRUDERS >= 4
#undef disable_E4
#define disable_E4() NOOP
#endif // EXTRUDERS >= 4
#endif // EXTRUDERS >= 3
#endif // EXTRUDERS >= 2
#endif // EXTRUDERS >= 1
#endif // HANGPRINTER
#if ENABLED(G38_PROBE_TARGET)
extern bool G38_move, // flag to tell the interrupt handler that a G38 command is being run
G38_endstop_hit; // flag from the interrupt handler to indicate if the endstop went active
@@ -301,12 +340,16 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ];
void tool_change(const uint8_t tmp_extruder, const float fr_mm_s=0.0, bool no_move=false);
void home_all_axes();
void home_all_axes();
void report_current_position();
#if IS_KINEMATIC
extern float delta[ABC];
#if ENABLED(HANGPRINTER)
extern float line_lengths[ABCD];
#else
extern float delta[ABC];
#endif
void inverse_kinematics(const float raw[XYZ]);
#endif
@@ -339,6 +382,51 @@ void report_current_position();
delta[C_AXIS] = DELTA_Z(V, C_AXIS); \
}while(0)
#elif ENABLED(HANGPRINTER)
// Don't collect anchor positions in array because there are no A_x, D_x or D_y
extern float anchor_A_y,
anchor_A_z,
anchor_B_x,
anchor_B_y,
anchor_B_z,
anchor_C_x,
anchor_C_y,
anchor_C_z,
anchor_D_z,
delta_segments_per_second,
line_lengths_origin[ABCD];
void recalc_hangprinter_settings();
#define HANGPRINTER_IK(V) do { \
line_lengths[A_AXIS] = SQRT(sq(anchor_A_z - V[Z_AXIS]) \
+ sq(anchor_A_y - V[Y_AXIS]) \
+ sq( V[X_AXIS])); \
line_lengths[B_AXIS] = SQRT(sq(anchor_B_z - V[Z_AXIS]) \
+ sq(anchor_B_y - V[Y_AXIS]) \
+ sq(anchor_B_x - V[X_AXIS])); \
line_lengths[C_AXIS] = SQRT(sq(anchor_C_z - V[Z_AXIS]) \
+ sq(anchor_C_y - V[Y_AXIS]) \
+ sq(anchor_C_x - V[X_AXIS])); \
line_lengths[D_AXIS] = SQRT(sq( V[X_AXIS]) \
+ sq( V[Y_AXIS]) \
+ sq(anchor_D_z - V[Z_AXIS])); \
}while(0)
// Inverse kinematics at origin
#define HANGPRINTER_IK_ORIGIN(LL) do { \
LL[A_AXIS] = SQRT(sq(anchor_A_z) \
+ sq(anchor_A_y)); \
LL[B_AXIS] = SQRT(sq(anchor_B_z) \
+ sq(anchor_B_y) \
+ sq(anchor_B_x)); \
LL[C_AXIS] = SQRT(sq(anchor_C_z) \
+ sq(anchor_C_y) \
+ sq(anchor_C_x)); \
LL[D_AXIS] = anchor_D_z; \
}while(0)
#elif IS_SCARA
void forward_kinematics_SCARA(const float &a, const float &b);
#endif
@@ -503,6 +591,9 @@ void do_blocking_move_to_xy(const float &rx, const float &ry, const float &fr_mm
inline bool position_is_reachable(const float &rx, const float &ry, const float inset=0) {
#if ENABLED(DELTA)
return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS - inset);
#elif ENABLED(HANGPRINTER)
// TODO: This is over simplified. Hangprinter's build volume is _not_ cylindrical.
return HYPOT2(rx, ry) <= sq(HANGPRINTER_PRINTABLE_RADIUS - inset);
#elif IS_SCARA
const float R2 = HYPOT2(rx - SCARA_OFFSET_X, ry - SCARA_OFFSET_Y);
return (
+1 -1
View File
@@ -9,7 +9,7 @@
================================================================================
Greetings! Thank you for choosing Marlin 2 as your 3D printer firmware.
Greetings! Thank you for choosing Marlin as your 3D printer firmware.
To configure Marlin you must edit Configuration.h and Configuration_adv.h
located in the root 'Marlin' folder. Check the example_configurations folder to
+1 -1
View File
@@ -25,10 +25,10 @@
#include "boards.h"
#include "macros.h"
#include "drivers.h"
#include "Version.h"
#include "Configuration.h"
#include "Conditionals_LCD.h"
#include "drivers.h"
#include "Configuration_adv.h"
#if USE_MARLINSERIAL
+891 -271
View File
File diff suppressed because it is too large Load Diff
+289 -240
View File
@@ -31,7 +31,7 @@
* #define MAX7219_DIN_PIN 78
* #define MAX7219_LOAD_PIN 79
*
* Max7219_init() is called automatically at startup, and then there are a number of
* send() is called automatically at startup, and then there are a number of
* support functions available to control the LEDs in the 8x8 grid.
*/
@@ -48,12 +48,92 @@
#include "Marlin.h"
#include "delay.h"
uint8_t LEDs[8*MAX7219_NUMBER_UNITS] = { 0 };
Max7219 max7219;
// Delay for 0.1875µs (16MHz AVR) or 0.15µs (20MHz AVR)
#define SIG_DELAY() DELAY_NS(188)
uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 };
void Max7219_PutByte(uint8_t data) {
#define LINE_REG(Q) (max7219_reg_digit0 + ((Q) & 0x7))
#if _ROT == 0 || _ROT == 270
#define _LED_BIT(Q) (7 - ((Q) & 0x7))
#define _LED_UNIT(Q) ((Q) & ~0x7)
#else
#define _LED_BIT(Q) ((Q) & 0x7)
#define _LED_UNIT(Q) ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3)
#endif
#if _ROT < 180
#define _LED_IND(P,Q) (_LED_UNIT(P) + (Q))
#else
#define _LED_IND(P,Q) (_LED_UNIT(P) + (7 - ((Q) & 0x7)))
#endif
#if _ROT == 0 || _ROT == 180
#define LED_IND(X,Y) _LED_IND(X,Y)
#define LED_BIT(X,Y) _LED_BIT(X)
#elif _ROT == 90 || _ROT == 270
#define LED_IND(X,Y) _LED_IND(Y,X)
#define LED_BIT(X,Y) _LED_BIT(Y)
#endif
#define XOR_7219(X,Y) do{ led_line[LED_IND(X,Y)] ^= _BV(LED_BIT(X,Y)); }while(0)
#define SET_7219(X,Y) do{ led_line[LED_IND(X,Y)] |= _BV(LED_BIT(X,Y)); }while(0)
#define CLR_7219(X,Y) do{ led_line[LED_IND(X,Y)] &= ~_BV(LED_BIT(X,Y)); }while(0)
#define BIT_7219(X,Y) TEST(led_line[LED_IND(X,Y)], LED_BIT(X,Y))
#ifdef CPU_32_BIT
#define SIG_DELAY() DELAY_US(1) // Approximate a 1µs delay on 32-bit ARM
#undef CRITICAL_SECTION_START
#undef CRITICAL_SECTION_END
#define CRITICAL_SECTION_START NOOP
#define CRITICAL_SECTION_END NOOP
#else
#define SIG_DELAY() DELAY_NS(188) // Delay for 0.1875µs (16MHz AVR) or 0.15µs (20MHz AVR)
#endif
void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) {
#if ENABLED(MAX7219_ERRORS)
SERIAL_ECHOPGM("??? Max7219::");
serialprintPGM(func);
SERIAL_CHAR('(');
SERIAL_ECHO(v1);
if (v2 > 0) SERIAL_ECHOPAIR(", ", v2);
SERIAL_CHAR(')');
SERIAL_EOL();
#else
UNUSED(func); UNUSED(v1); UNUSED(v2);
#endif
}
/**
* Flip the lowest n_bytes of the supplied bits:
* flipped(x, 1) flips the low 8 bits of x.
* flipped(x, 2) flips the low 16 bits of x.
* flipped(x, 3) flips the low 24 bits of x.
* flipped(x, 4) flips the low 32 bits of x.
*/
inline uint32_t flipped(const uint32_t bits, const uint8_t n_bytes) {
uint32_t mask = 1, outbits = 0;
for (uint8_t b = 0; b < n_bytes * 8; b++) {
outbits <<= 1;
if (bits & mask) outbits |= 1;
mask <<= 1;
}
return outbits;
}
void Max7219::noop() {
CRITICAL_SECTION_START;
SIG_DELAY();
WRITE(MAX7219_DIN_PIN, LOW);
for (uint8_t i = 16; i--;) {
SIG_DELAY();
WRITE(MAX7219_CLK_PIN, LOW);
SIG_DELAY();
SIG_DELAY();
WRITE(MAX7219_CLK_PIN, HIGH);
SIG_DELAY();
}
CRITICAL_SECTION_END;
}
void Max7219::putbyte(uint8_t data) {
CRITICAL_SECTION_START;
for (uint8_t i = 8; i--;) {
SIG_DELAY();
@@ -68,7 +148,7 @@ void Max7219_PutByte(uint8_t data) {
CRITICAL_SECTION_END;
}
void Max7219_pulse_load() {
void Max7219::pulse_load() {
SIG_DELAY();
WRITE(MAX7219_LOAD_PIN, LOW); // tell the chip to load the data
SIG_DELAY();
@@ -76,20 +156,39 @@ void Max7219_pulse_load() {
SIG_DELAY();
}
void Max7219(const uint8_t reg, const uint8_t data) {
void Max7219::send(const uint8_t reg, const uint8_t data) {
SIG_DELAY();
CRITICAL_SECTION_START;
SIG_DELAY();
Max7219_PutByte(reg); // specify register
putbyte(reg); // specify register
SIG_DELAY();
Max7219_PutByte(data); // put data
putbyte(data); // put data
CRITICAL_SECTION_END;
}
// Send out a single native row of bits to all units
void Max7219::refresh_line(const uint8_t line) {
for (uint8_t u = MAX7219_NUMBER_UNITS; u--;)
send(LINE_REG(line), led_line[(u << 3) | (line & 0x7)]);
pulse_load();
}
// Send out a single native row of bits to just one unit
void Max7219::refresh_unit_line(const uint8_t line) {
for (uint8_t u = MAX7219_NUMBER_UNITS; u--;)
if (u == (line >> 3)) send(LINE_REG(line), led_line[line]); else noop();
pulse_load();
}
void Max7219::set(const uint8_t line, const uint8_t bits) {
led_line[line] = bits;
refresh_line(line);
}
#if ENABLED(MAX7219_NUMERIC)
// Draw an integer with optional leading zeros and optional decimal point
void Max7219_Print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false) {
void Max7219::print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false) {
constexpr uint8_t led_numeral[10] = { 0x7E, 0x60, 0x6D, 0x79, 0x63, 0x5B, 0x5F, 0x70, 0x7F, 0x7A },
led_decimal = 0x80, led_minus = 0x01;
@@ -98,11 +197,11 @@ void Max7219(const uint8_t reg, const uint8_t data) {
while (size--) {
const bool minus = neg && blank;
if (minus) neg = false;
Max7219(
send(
max7219_reg_digit0 + start + size,
minus ? led_minus : blank ? 0x00 : led_numeral[value % 10] | (dec ? led_decimal : 0x00)
);
Max7219_pulse_load(); // tell the chips to load the clocked out data
pulse_load(); // tell the chips to load the clocked out data
value /= 10;
if (!value && !leadzero) blank = true;
dec = false;
@@ -110,247 +209,197 @@ void Max7219(const uint8_t reg, const uint8_t data) {
}
// Draw a float with a decimal point and optional digits
void Max7219_Print(const uint8_t start, const float value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false) {
if (pre_size) Max7219_Print(start, value, pre_size, leadzero, !!post_size);
void Max7219::print(const uint8_t start, const float value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false) {
if (pre_size) print(start, value, pre_size, leadzero, !!post_size);
if (post_size) {
const int16_t after = ABS(value) * (10 ^ post_size);
Max7219_Print(start + pre_size, after, post_size, true);
print(start + pre_size, after, post_size, true);
}
}
#endif // MAX7219_NUMERIC
inline void Max7219_Error(const char * const func, const int32_t v1, const int32_t v2=-1) {
#if ENABLED(MAX7219_ERRORS)
SERIAL_ECHOPGM("??? ");
serialprintPGM(func);
SERIAL_CHAR('(');
SERIAL_ECHO(v1);
if (v2 > 0) SERIAL_ECHOPAIR(", ", v2);
SERIAL_CHAR(')');
SERIAL_EOL();
// Modify a single LED bit and send the changed line
void Max7219::led_set(const uint8_t x, const uint8_t y, const bool on) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_set"), x, y);
if (BIT_7219(x, y) == on) return;
XOR_7219(x, y);
refresh_line(LED_IND(x, y));
}
void Max7219::led_on(const uint8_t x, const uint8_t y) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_on"), x, y);
led_set(x, y, true);
}
void Max7219::led_off(const uint8_t x, const uint8_t y) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_off"), x, y);
led_set(x, y, false);
}
void Max7219::led_toggle(const uint8_t x, const uint8_t y) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_toggle"), x, y);
led_set(x, y, !BIT_7219(x, y));
}
void Max7219::send_row(const uint8_t row) {
#if _ROT == 0 || _ROT == 180
refresh_line(LED_IND(0, row));
#else
UNUSED(func); UNUSED(v1); UNUSED(v2);
UNUSED(row);
refresh();
#endif
}
void Max7219::send_column(const uint8_t col) {
#if _ROT == 90 || _ROT == 270
refresh_line(LED_IND(col, 0));
#else
UNUSED(col);
refresh();
#endif
}
void Max7219::clear() {
ZERO(led_line);
refresh();
}
void Max7219::fill() {
memset(led_line, 0xFF, sizeof(led_line));
refresh();
}
void Max7219::clear_row(const uint8_t row) {
if (row >= MAX7219_Y_LEDS) return error(PSTR("clear_row"), row);
for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) CLR_7219(x, row);
send_row(row);
}
void Max7219::clear_column(const uint8_t col) {
if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) CLR_7219(col, y);
send_column(col);
}
/**
* uint32_t flipped(const uint32_t bits, const uint8_t n_bytes) operates on the number
* of bytes specified in n_bytes. The lower order bits of the supplied bits are flipped.
* flipped( x, 1) flips the low 8 bits of x.
* flipped( x, 2) flips the low 16 bits of x.
* flipped( x, 3) flips the low 24 bits of x.
* flipped( x, 4) flips the low 32 bits of x.
* Plot the low order bits of val to the specified row of the matrix.
* With 4 Max7219 units in the chain, it's possible to set 32 bits at once with
* one call to the function (if rotated 90° or 180°).
*/
inline uint32_t flipped(const uint32_t bits, const uint8_t n_bytes) {
uint32_t mask = 1, outbits = 0;
for (uint8_t b = 0; b < n_bytes * 8; b++) {
outbits = (outbits << 1);
if (bits & mask)
outbits |= 1;
mask <<= 1;
void Max7219::set_row(const uint8_t row, const uint32_t val) {
if (row >= MAX7219_Y_LEDS) return error(PSTR("set_row"), row);
uint32_t mask = _BV32(MAX7219_X_LEDS - 1);
for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) {
if (val & mask) SET_7219(x, row); else CLR_7219(x, row);
mask >>= 1;
}
return outbits;
send_row(row);
}
// Modify a single LED bit and send the changed line
void Max7219_LED_Set(const uint8_t x, const uint8_t y, const bool on) {
if (x > (MAX7219_X_LEDS - 1) || y > (MAX7219_Y_LEDS - 1)) return Max7219_Error(PSTR("Max7219_LED_Set"), x, y);
if (BIT_7219(x, y) == on) return;
XOR_7219(x, y);
SEND_7219(MAX7219_UPDATE_AXIS);
}
void Max7219_LED_On(const uint8_t x, const uint8_t y) {
if (x > (MAX7219_X_LEDS - 1) || y > (MAX7219_Y_LEDS - 1)) return Max7219_Error(PSTR("Max7219_LED_On"), x, y);
Max7219_LED_Set(x, y, true);
}
void Max7219_LED_Off(const uint8_t x, const uint8_t y) {
if (x > (MAX7219_X_LEDS - 1) || y > (MAX7219_Y_LEDS - 1)) return Max7219_Error(PSTR("Max7219_LED_Off"), x, y);
Max7219_LED_Set(x, y, false);
}
void Max7219_LED_Toggle(const uint8_t x, const uint8_t y) {
if (x > (MAX7219_X_LEDS - 1) || y > (MAX7219_Y_LEDS - 1)) return Max7219_Error(PSTR("Max7219_LED_Toggle"), x, y);
Max7219_LED_Set(x, y, !BIT_7219(x, y));
}
inline void _Max7219_Set_Digit_Segments(const uint8_t digit, const uint8_t val) {
LEDs[digit] = val;
SEND_7219(digit);
}
/*
* void Max7219_Set_Row( const uint8_t col, const uint32_t val) plots the low order bits of
* val to the specified row of the Max7219 matrix. With 4 Max7219 units in the chain, it
* is possible to display an entire 32-bit number with one call to the function (if appropriately
* orientated).
/**
* Plot the low order bits of val to the specified column of the matrix.
* With 4 Max7219 units in the chain, it's possible to set 32 bits at once with
* one call to the function (if rotated 90° or 180°).
*/
void Max7219_Set_Row(const uint8_t row, const uint32_t val) {
if (row >= MAX7219_Y_LEDS) return Max7219_Error(PSTR("Max7219_Set_Row"), row);
uint32_t mask = 0x0000001;
for(uint8_t x = 0; x < MAX7219_X_LEDS; x++) {
if (val & mask)
SET_PIXEL_7219(MAX7219_X_LEDS-1-x, row);
else
CLEAR_PIXEL_7219(MAX7219_X_LEDS-1-x, row);
mask <<= 1;
void Max7219::set_column(const uint8_t col, const uint32_t val) {
if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
uint32_t mask = _BV32(MAX7219_Y_LEDS - 1);
for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) {
if (val & mask) SET_7219(col, y); else CLR_7219(col, y);
mask >>= 1;
}
#if _ROT == 90 || _ROT == 270
for(uint8_t x = 0; x < 8; x++)
SEND_7219(x); // force all columns out to the Max7219 chips and strobe them
#else
SEND_7219(row); // force the single column out to the Max7219 chips and strobe them
#endif
return;
send_column(col);
}
void Max7219_Clear_Row(const uint8_t row) {
if (row > 7) return Max7219_Error(PSTR("Max7219_Clear_Row"), row);
#if _ROT == 90 || _ROT == 270
for (uint8_t col = 0; col < 8; col++) Max7219_LED_Off(col, row);
#else
_Max7219_Set_Digit_Segments(row, 0);
#endif
}
/*
* void Max7219_Set_Column( const uint8_t col, const uint32_t val) plots the low order bits of
* val to the specified column of the Max7219 matrix. With 4 Max7219 units in the chain, it
* is possible to display an entire 32-bit number with one call to the function (if appropriately
* orientated).
*/
void Max7219_Set_Column(const uint8_t col, const uint32_t val) {
if (col >= MAX7219_X_LEDS) return Max7219_Error(PSTR("Max7219_Set_Column"), col);
uint32_t mask = 0x0000001;
for(uint8_t y = 0; y < MAX7219_Y_LEDS; y++) {
if (val & mask)
SET_PIXEL_7219(col, MAX7219_Y_LEDS-1-y);
else
CLEAR_PIXEL_7219(col, MAX7219_Y_LEDS-1-y);
mask <<= 1;
}
#if _ROT == 90 || _ROT == 270
SEND_7219(col); // force the column out to the Max7219 chips and strobe them
#else
for(uint8_t yy = 0; yy < 8; yy++)
SEND_7219(yy); // force all columns out to the Max7219 chips and strobe them
#endif
return;
}
void Max7219_Clear_Column(const uint8_t col) {
if (col >= MAX7219_X_LEDS) return Max7219_Error(PSTR("Max7219_Clear_Column"), col);
for(uint8_t yy = 0; yy < MAX7219_Y_LEDS; yy++)
CLEAR_PIXEL_7219(col, yy);
#if _ROT == 90 || _ROT == 270
SEND_7219(col); // force the column out to the Max7219 chips and strobe them
#else
for(uint8_t y = 0; y < 8; y++)
SEND_7219(y); // force all columns out to the Max7219 chips and strobe them
#endif
return;
}
void Max7219_Clear() {
for (uint8_t i = 0; i <= 7; i++) { // Clear LED bitmap
for (uint8_t j = 0; j < MAX7219_NUMBER_UNITS; j++)
LEDs[i + j * 8] = 0x00;
SEND_7219(i);
}
}
void Max7219_Set_Rows_16bits(const uint8_t y, uint32_t val) {
void Max7219::set_rows_16bits(const uint8_t y, uint32_t val) {
#if MAX7219_X_LEDS == 8
if (y > MAX7219_Y_LEDS - 2) return Max7219_Error(PSTR("Max7219_Set_Rows_16bits"), y, val);
Max7219_Set_Row(y + 1, val); val >>= 8;
Max7219_Set_Row(y + 0, val);
if (y > MAX7219_Y_LEDS - 2) return error(PSTR("set_rows_16bits"), y, val);
set_row(y + 1, val); val >>= 8;
set_row(y + 0, val);
#else // at least 16 bits on each row
if (y > MAX7219_Y_LEDS - 1) return Max7219_Error(PSTR("Max7219_Set_Rows_16bits"), y, val);
Max7219_Set_Row(y, val);
if (y > MAX7219_Y_LEDS - 1) return error(PSTR("set_rows_16bits"), y, val);
set_row(y, val);
#endif
}
void Max7219_Set_Rows_32bits(const uint8_t y, uint32_t val) {
void Max7219::set_rows_32bits(const uint8_t y, uint32_t val) {
#if MAX7219_X_LEDS == 8
if (y > MAX7219_Y_LEDS - 4) return Max7219_Error(PSTR("Max7219_Set_Rows_32bits"), y, val);
Max7219_Set_Row(y + 3, val); val >>= 8;
Max7219_Set_Row(y + 2, val); val >>= 8;
Max7219_Set_Row(y + 1, val); val >>= 8;
Max7219_Set_Row(y + 0, val);
if (y > MAX7219_Y_LEDS - 4) return error(PSTR("set_rows_32bits"), y, val);
set_row(y + 3, val); val >>= 8;
set_row(y + 2, val); val >>= 8;
set_row(y + 1, val); val >>= 8;
set_row(y + 0, val);
#elif MAX7219_X_LEDS == 16
if (y > MAX7219_Y_LEDS - 2) return Max7219_Error(PSTR("Max7219_Set_Rows_32bits"), y, val);
Max7219_Set_Row(y + 1, val); val >>= 16;
Max7219_Set_Row(y + 0, val);
if (y > MAX7219_Y_LEDS - 2) return error(PSTR("set_rows_32bits"), y, val);
set_row(y + 1, val); val >>= 16;
set_row(y + 0, val);
#else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits
if (y > MAX7219_Y_LEDS - 1) return Max7219_Error(PSTR("Max7219_Set_Rows_32bits"), y, val);
Max7219_Set_Row(y, val);
if (y > MAX7219_Y_LEDS - 1) return error(PSTR("set_rows_32bits"), y, val);
set_row(y, val);
#endif
}
void Max7219_Set_Columns_16bits(const uint8_t x, uint32_t val) {
void Max7219::set_columns_16bits(const uint8_t x, uint32_t val) {
#if MAX7219_Y_LEDS == 8
if (x > MAX7219_X_LEDS - 2) return Max7219_Error(PSTR("Max7219_Set_Columns_16bits"), x, val);
Max7219_Set_Column(x + 0, val); val >>= 8;
Max7219_Set_Column(x + 1, val);
if (x > MAX7219_X_LEDS - 2) return error(PSTR("set_columns_16bits"), x, val);
set_column(x + 0, val); val >>= 8;
set_column(x + 1, val);
#else // at least 16 bits in each column
if (x > MAX7219_X_LEDS - 1) return Max7219_Error(PSTR("Max7219_Set_Columns_16bits"), x, val);
Max7219_Set_Column(x, val);
if (x > MAX7219_X_LEDS - 1) return error(PSTR("set_columns_16bits"), x, val);
set_column(x, val);
#endif
}
void Max7219_Set_Columns_32bits(const uint8_t x, uint32_t val) {
void Max7219::set_columns_32bits(const uint8_t x, uint32_t val) {
#if MAX7219_Y_LEDS == 8
if (x > MAX7219_X_LEDS - 4) return Max7219_Error(PSTR("Max7219_Set_Rows_32bits"), x, val);
Max7219_Set_Column(x + 3, val); val >>= 8;
Max7219_Set_Column(x + 2, val); val >>= 8;
Max7219_Set_Column(x + 1, val); val >>= 8;
Max7219_Set_Column(x + 0, val);
if (x > MAX7219_X_LEDS - 4) return error(PSTR("set_rows_32bits"), x, val);
set_column(x + 3, val); val >>= 8;
set_column(x + 2, val); val >>= 8;
set_column(x + 1, val); val >>= 8;
set_column(x + 0, val);
#elif MAX7219_Y_LEDS == 16
if (x > MAX7219_X_LEDS - 2) return Max7219_Error(PSTR("Max7219_Set_Rows_32bits"), x, val);
Max7219_Set_Column(x + 1, val); val >>= 16;
Max7219_Set_Column(x + 0, val);
if (x > MAX7219_X_LEDS - 2) return error(PSTR("set_rows_32bits"), x, val);
set_column(x + 1, val); val >>= 16;
set_column(x + 0, val);
#else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits
if (x > MAX7219_X_LEDS - 1) return Max7219_Error(PSTR("Max7219_Set_Rows_32bits"), x, val);
Max7219_Set_Column(x, val);
if (x > MAX7219_X_LEDS - 1) return error(PSTR("set_rows_32bits"), x, val);
set_column(x, val);
#endif
}
void Max7219_register_setup() {
// Initialize the Max7219
for(int i=0; i < MAX7219_NUMBER_UNITS; i++)
Max7219(max7219_reg_scanLimit, 0x07);
Max7219_pulse_load(); // tell the chips to load the clocked out data
// Initialize the Max7219
void Max7219::register_setup() {
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_scanLimit, 0x07);
pulse_load(); // tell the chips to load the clocked out data
for(int i=0; i < MAX7219_NUMBER_UNITS; i++)
Max7219(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)
Max7219_pulse_load(); // tell the chips to load the clocked out data
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)
pulse_load(); // tell the chips to load the clocked out data
for(int i=0; i < MAX7219_NUMBER_UNITS; i++)
Max7219(max7219_reg_shutdown, 0x01); // not in shutdown mode
Max7219_pulse_load(); // tell the chips to load the clocked out data
for(int i=0; i < MAX7219_NUMBER_UNITS; i++)
Max7219(max7219_reg_displayTest, 0x00); // no display test
Max7219_pulse_load(); // tell the chips to load the clocked out data
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_shutdown, 0x01); // not in shutdown mode
pulse_load(); // tell the chips to load the clocked out data
for(int i=0; i < MAX7219_NUMBER_UNITS; i++)
Max7219(max7219_reg_intensity, 0x01 & 0x0F); // the first 0x0F is the value you can set
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_displayTest, 0x00); // no display test
pulse_load(); // tell the chips to load the clocked out data
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_intensity, 0x01 & 0x0F); // the first 0x0F is the value you can set
// range: 0x00 to 0x0F
Max7219_pulse_load(); // tell the chips to load the clocked out data
pulse_load(); // tell the chips to load the clocked out data
}
#ifdef MAX7219_INIT_TEST
#if (MAX7219_INIT_TEST + 0) == 2
#if MAX7219_INIT_TEST == 2
inline void Max7219_spiral(const bool on, const uint16_t del) {
void Max7219::spiral(const bool on, const uint16_t del) {
constexpr int8_t way[] = { 1, 0, 0, 1, -1, 0, 0, -1 };
int8_t px = 0, py = 0, dir = 0;
for (uint8_t i = MAX7219_X_LEDS * MAX7219_Y_LEDS; i--;) {
Max7219_LED_Set(px, py, on);
led_set(px, py, on);
delay(del);
const int8_t x = px + way[dir], y = py + way[dir + 1];
if (!WITHIN(x, 0, MAX7219_X_LEDS-1) || !WITHIN(y, 0, MAX7219_Y_LEDS-1) || BIT_7219(x, y) == on) dir = (dir + 2) & 0x7;
@@ -360,10 +409,10 @@ void Max7219_register_setup() {
#else
inline void Max7219_sweep(const int8_t dir, const uint16_t ms, const bool on) {
void Max7219::sweep(const int8_t dir, const uint16_t ms, const bool on) {
uint8_t x = dir > 0 ? 0 : MAX7219_X_LEDS-1;
for (uint8_t i = MAX7219_X_LEDS; i--; x += dir) {
Max7219_Set_Column(x, on ? 0xFFFFFFFF : 0x00000000);
set_column(x, on ? 0xFFFFFFFF : 0x00000000);
delay(ms);
}
}
@@ -371,33 +420,33 @@ void Max7219_register_setup() {
#endif
#endif // MAX7219_INIT_TEST
void Max7219_init() {
void Max7219::init() {
SET_OUTPUT(MAX7219_DIN_PIN);
SET_OUTPUT(MAX7219_CLK_PIN);
OUT_WRITE(MAX7219_LOAD_PIN, HIGH);
delay(1);
Max7219_register_setup();
register_setup();
for (uint8_t i = 0; i <= 7; i++) { // Empty registers to turn all LEDs off
LEDs[i] = 0x00;
Max7219(max7219_reg_digit0 + i, 0);
Max7219_pulse_load(); // tell the chips to load the clocked out data
led_line[i] = 0x00;
send(max7219_reg_digit0 + i, 0);
pulse_load(); // tell the chips to load the clocked out data
}
#ifdef MAX7219_INIT_TEST
#if (MAX7219_INIT_TEST + 0) == 2
Max7219_spiral(true, 8);
#if MAX7219_INIT_TEST == 2
spiral(true, 8);
delay(150);
Max7219_spiral(false, 8);
spiral(false, 8);
#else
// Do an aesthetically-pleasing pattern to fully test the Max7219 module and LEDs.
// Light up and turn off columns, both forward and backward.
Max7219_sweep(1, 20, true);
Max7219_sweep(1, 20, false);
sweep(1, 20, true);
sweep(1, 20, false);
delay(150);
Max7219_sweep(-1, 20, true);
Max7219_sweep(-1, 20, false);
sweep(-1, 20, true);
sweep(-1, 20, false);
#endif
#endif
}
@@ -409,58 +458,58 @@ void Max7219_init() {
*/
// Apply changes to update a marker
inline void Max7219_Mark16(const uint8_t y, const uint8_t v1, const uint8_t v2) {
void Max7219::mark16(const uint8_t y, const uint8_t v1, const uint8_t v2) {
#if MAX7219_X_LEDS == 8
#if MAX7219_Y_LEDS == 8
Max7219_LED_Off(v1 & 0x7, y + (v1 >= 8));
Max7219_LED_On(v2 & 0x7, y + (v2 >= 8));
led_off(v1 & 0x7, y + (v1 >= 8));
led_on(v2 & 0x7, y + (v2 >= 8));
#else
Max7219_LED_Off(y, v1 & 0xF); // The Max7219 Y-Axis has at least 16 LED's. So use a single column
Max7219_LED_On(y, v2 & 0xF);
led_off(y, v1 & 0xF); // At least 16 LEDs down. Use a single column.
led_on(y, v2 & 0xF);
#endif
#else // LED matrix has at least 16 LED's on the X-Axis. Use single line of LED's
Max7219_LED_Off(v1 & 0xf, y);
Max7219_LED_On(v2 & 0xf, y);
#else
led_off(v1 & 0xF, y); // At least 16 LEDs across. Use a single row.
led_on(v2 & 0xF, y);
#endif
}
// Apply changes to update a tail-to-head range
inline void Max7219_Range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh) {
void Max7219::range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh) {
#if MAX7219_X_LEDS == 8
#if MAX7219_Y_LEDS == 8
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
Max7219_LED_Off(n & 0x7, y + (n >= 8));
led_off(n & 0x7, y + (n >= 8));
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
Max7219_LED_On(n & 0x7, y + (n >= 8));
led_on(n & 0x7, y + (n >= 8));
#else // The Max7219 Y-Axis has at least 16 LED's. So use a single column
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
Max7219_LED_Off(y, n & 0xF);
led_off(y, n & 0xF);
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
Max7219_LED_On(y, n & 0xF);
led_on(y, n & 0xF);
#endif
#else // LED matrix has at least 16 LED's on the X-Axis. Use single line of LED's
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
Max7219_LED_Off(n & 0xf, y);
led_off(n & 0xF, y);
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
Max7219_LED_On(n & 0xf, y);
led_on(n & 0xF, y);
#endif
}
// Apply changes to update a quantity
inline void Max7219_Quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv) {
void Max7219::quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv) {
for (uint8_t i = MIN(nv, ov); i < MAX(nv, ov); i++)
#if MAX7219_X_LEDS == 8
#if MAX7219_Y_LEDS == 8
Max7219_LED_Set(i >> 1, y + (i & 1), nv >= ov); // single 8x8 LED matrix. Use two lines to get 16 LED's
led_set(i >> 1, y + (i & 1), nv >= ov); // single 8x8 LED matrix. Use two lines to get 16 LED's
#else
Max7219_LED_Set(y, i, nv >= ov); // The Max7219 Y-Axis has at least 16 LED's. So use a single column
led_set(y, i, nv >= ov); // The Max7219 Y-Axis has at least 16 LED's. So use a single column
#endif
#else
Max7219_LED_Set(i, y, nv >= ov); // LED matrix has at least 16 LED's on the X-Axis. Use single line of LED's
led_set(i, y, nv >= ov); // LED matrix has at least 16 LED's on the X-Axis. Use single line of LED's
#endif
}
void Max7219_idle_tasks() {
void Max7219::idle_tasks() {
#define MAX7219_USE_HEAD (defined(MAX7219_DEBUG_PLANNER_HEAD) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
#define MAX7219_USE_TAIL (defined(MAX7219_DEBUG_PLANNER_TAIL) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
#if MAX7219_USE_HEAD || MAX7219_USE_TAIL
@@ -491,12 +540,12 @@ void Max7219_idle_tasks() {
// corrupted, this will fix it within a couple seconds.
if (do_blink && ++refresh_cnt >= refresh_limit) {
refresh_cnt = 0;
Max7219_register_setup();
register_setup();
}
#if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE)
if (do_blink) {
Max7219_LED_Toggle(MAX7219_X_LEDS - 1, MAX7219_Y_LEDS - 1);
led_toggle(MAX7219_X_LEDS - 1, MAX7219_Y_LEDS - 1);
next_blink = ms + 1000;
}
#endif
@@ -506,7 +555,7 @@ void Max7219_idle_tasks() {
static int16_t last_head_cnt = 0xF, last_tail_cnt = 0xF;
if (last_head_cnt != head || last_tail_cnt != tail) {
Max7219_Range16(MAX7219_DEBUG_PLANNER_HEAD, last_tail_cnt, tail, last_head_cnt, head);
range16(MAX7219_DEBUG_PLANNER_HEAD, last_tail_cnt, tail, last_head_cnt, head);
last_head_cnt = head;
last_tail_cnt = tail;
}
@@ -516,7 +565,7 @@ void Max7219_idle_tasks() {
#ifdef MAX7219_DEBUG_PLANNER_HEAD
static int16_t last_head_cnt = 0x1;
if (last_head_cnt != head) {
Max7219_Mark16(MAX7219_DEBUG_PLANNER_HEAD, last_head_cnt, head);
mark16(MAX7219_DEBUG_PLANNER_HEAD, last_head_cnt, head);
last_head_cnt = head;
}
#endif
@@ -524,7 +573,7 @@ void Max7219_idle_tasks() {
#ifdef MAX7219_DEBUG_PLANNER_TAIL
static int16_t last_tail_cnt = 0x1;
if (last_tail_cnt != tail) {
Max7219_Mark16(MAX7219_DEBUG_PLANNER_TAIL, last_tail_cnt, tail);
mark16(MAX7219_DEBUG_PLANNER_TAIL, last_tail_cnt, tail);
last_tail_cnt = tail;
}
#endif
@@ -535,7 +584,7 @@ void Max7219_idle_tasks() {
static int16_t last_depth = 0;
const int16_t current_depth = (head - tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1) & 0xF;
if (current_depth != last_depth) {
Max7219_Quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth);
quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth);
last_depth = current_depth;
}
#endif
+83 -76
View File
@@ -31,18 +31,33 @@
* #define MAX7219_DIN_PIN 78
* #define MAX7219_LOAD_PIN 79
*
* Max7219_init() is called automatically at startup, and then there are a number of
* max7219.init() is called automatically at startup, and then there are a number of
* support functions available to control the LEDs in the 8x8 grid.
*
* If you are using the Max7219 matrix for firmware debug purposes in time sensitive
* areas of the code, please be aware that the orientation (rotation) of the display can
* areas of the code, please be aware that the orientation (rotation) of the display can
* affect the speed. The Max7219 can update a single column fairly fast. It is much
* faster to do a Max7219_Set_Column() with a rotation of 90 or 270 degrees than to do
* a Max7219_Set_Row(). The opposite is true for rotations of 0 or 180 degrees.
*/
#pragma once
#ifndef __MAX7219_DEBUG_LEDS_H__
#define __MAX7219_DEBUG_LEDS_H__
#ifndef MAX7219_ROTATE
#define MAX7219_ROTATE 0
#endif
#define _ROT ((MAX7219_ROTATE + 360) % 360)
#define MAX7219_LINES (8 * (MAX7219_NUMBER_UNITS))
#if _ROT == 0 || _ROT == 180
#define MAX7219_Y_LEDS 8
#define MAX7219_X_LEDS MAX7219_LINES
#elif _ROT == 90 || _ROT == 270
#define MAX7219_X_LEDS 8
#define MAX7219_Y_LEDS MAX7219_LINES
#else
#error "MAX7219_ROTATE must be a multiple of +/- 90°."
#endif
//
// MAX7219 registers
@@ -63,85 +78,77 @@
#define max7219_reg_shutdown 0x0C
#define max7219_reg_displayTest 0x0F
void Max7219_init();
void Max7219_PutByte(uint8_t data);
void Max7219_pulse_load();
class Max7219 {
public:
static uint8_t led_line[MAX7219_LINES];
// Set a single register (e.g., a whole native row)
void Max7219(const uint8_t reg, const uint8_t data);
Max7219() { }
// Set a single LED by XY coordinate
void Max7219_LED_Set(const uint8_t x, const uint8_t y, const bool on);
void Max7219_LED_On(const uint8_t x, const uint8_t y);
void Max7219_LED_Off(const uint8_t x, const uint8_t y);
void Max7219_LED_Toggle(const uint8_t x, const uint8_t y);
static void init();
static void register_setup();
static void putbyte(uint8_t data);
static void pulse_load();
// Set all LEDs in a single column
void Max7219_Set_Column(const uint8_t col, const uint32_t val);
void Max7219_Clear_Column(const uint8_t col);
// Set a single register (e.g., a whole native row)
static void send(const uint8_t reg, const uint8_t data);
// Set all LEDs in a single row
void Max7219_Set_Row(const uint8_t row, const uint32_t val);
void Max7219_Clear_Row(const uint8_t row);
// Refresh all units
inline static void refresh() { for (uint8_t i = 0; i < 8; i++) refresh_line(i); }
// 16 and 32 bit versions of Row and Column functions
// Multiple rows and columns will be used to display the value if
// the array of matrix LED's is too narrow to accomplish the goal
void Max7219_Set_Rows_16bits(const uint8_t y, uint32_t val);
void Max7219_Set_Rows_32bits(const uint8_t y, uint32_t val);
void Max7219_Set_Columns_16bits(const uint8_t x, uint32_t val);
void Max7219_Set_Columns_32bits(const uint8_t x, uint32_t val);
// Update a single native line on all units
static void refresh_line(const uint8_t line);
// Quickly clear the whole matrix
void Max7219_Clear();
// Update a single native line on just one unit
static void refresh_unit_line(const uint8_t line);
// Apply custom code to update the matrix
void Max7219_idle_tasks();
// Set a single LED by XY coordinate
static void led_set(const uint8_t x, const uint8_t y, const bool on);
static void led_on(const uint8_t x, const uint8_t y);
static void led_off(const uint8_t x, const uint8_t y);
static void led_toggle(const uint8_t x, const uint8_t y);
#ifndef MAX7219_ROTATE
#define MAX7219_ROTATE 0
#endif
#define _ROT ((MAX7219_ROTATE + 360) % 360)
#if _ROT == 0
#define MAX7219_UPDATE_AXIS y // Fast line update axis for this orientation of the matrix display
#define MAX7219_X_LEDS (8 * MAX7219_NUMBER_UNITS)
#define MAX7219_Y_LEDS 8
#define XOR_7219(x, y) LEDs[y + (x >> 3) * 8] ^= _BV(7 - (x & 0x07))
#define SET_PIXEL_7219(x, y) LEDs[y + (x >> 3) * 8] |= _BV(7 - (x & 0x07))
#define CLEAR_PIXEL_7219(x, y) LEDs[y + (x >> 3) * 8] &= (_BV(7 - (x & 0x07)) ^ 0xff)
#define BIT_7219(x, y) TEST(LEDs[y + (x >> 3) * 8], 7 - (x & 0x07))
#define SEND_7219(R) do {for(int8_t jj = 0; jj < MAX7219_NUMBER_UNITS; jj++) Max7219(max7219_reg_digit0 + (R & 0x7), LEDs[(R & 0x7) + jj * 8]); Max7219_pulse_load(); } while (0);
#elif _ROT == 90
#define MAX7219_UPDATE_AXIS x // Fast line update axis for this orientation of the matrix display
#define MAX7219_X_LEDS 8
#define MAX7219_Y_LEDS (8 * MAX7219_NUMBER_UNITS)
#define XOR_7219(x, y) LEDs[x + (((MAX7219_Y_LEDS - 1 - y) >> 3) * 8)] ^= _BV((y & 0x7))
#define SET_PIXEL_7219(x, y) LEDs[x + (((MAX7219_Y_LEDS - 1 - y) >> 3) * 8)] |= _BV((y & 0x7))
#define CLEAR_PIXEL_7219(x, y) LEDs[x + (((MAX7219_Y_LEDS - 1 - y) >> 3) * 8)] &= (_BV((y & 0x7)) ^ 0xff)
#define BIT_7219(x, y) TEST(LEDs[x + (((MAX7219_Y_LEDS - 1 - y) >> 3) * 8)], (y & 0x7))
#define SEND_7219(R) do {for(int8_t jj = 0; jj < MAX7219_NUMBER_UNITS; jj++) Max7219(max7219_reg_digit0 + (R & 0x7), LEDs[(R & 0x7) + jj * 8]); Max7219_pulse_load(); } while (0);
#elif _ROT == 180
#define MAX7219_UPDATE_AXIS y // Fast line update axis for this orientation of the matrix display
#define MAX7219_X_LEDS (8 * MAX7219_NUMBER_UNITS)
#define MAX7219_Y_LEDS 8
#define XOR_7219(x, y) LEDs[y + ((MAX7219_X_LEDS - 1 - x) >> 3) * 8] ^= _BV((x & 0x07))
#define SET_PIXEL_7219(x, y) LEDs[y + ((MAX7219_X_LEDS - 1 - x) >> 3) * 8] |= _BV((x & 0x07))
#define CLEAR_PIXEL_7219(x, y) LEDs[y + ((MAX7219_X_LEDS - 1 - x) >> 3) * 8] &= (_BV((x & 0x07)) ^ 0xff)
#define BIT_7219(x, y) TEST(LEDs[y + ((MAX7219_X_LEDS - 1 - x) >> 3) * 8], ((x & 0x07)))
#define SEND_7219(R) do {for(int8_t jj = 0; jj < MAX7219_NUMBER_UNITS; jj++) Max7219(max7219_reg_digit7 - (R & 0x7), LEDs[(R & 0x7) + jj * 8]); Max7219_pulse_load(); } while (0);
#elif _ROT == 270
#define MAX7219_UPDATE_AXIS x // Fast line update axis for this orientation of the matrix display
#define MAX7219_X_LEDS 8
#define MAX7219_Y_LEDS (8 * MAX7219_NUMBER_UNITS)
#define XOR_7219(x, y) LEDs[x + (y >> 3) * 8] ^= _BV(7 - (y & 0x7))
#define SET_PIXEL_7219(x, y) LEDs[x + (y >> 3) * 8] |= _BV(7 - (y & 0x7))
#define CLEAR_PIXEL_7219(x, y) LEDs[x + (y >> 3) * 8] &= (_BV(7 - (y & 0x7)) ^ 0xff)
#define BIT_7219(x, y) TEST(LEDs[x + ( y >> 3) * 8], 7 - (y & 0x7))
#define SEND_7219(R) do {for(int8_t jj = 0; jj < MAX7219_NUMBER_UNITS; jj++) Max7219(max7219_reg_digit7 - (R & 0x7), LEDs[(R & 0x7) + jj * 8]); Max7219_pulse_load(); } while (0);
#else
#error "MAX7219_ROTATE must be a multiple of +/- 90°."
#endif
// Set all LEDs in a single column
static void set_column(const uint8_t col, const uint32_t val);
static void clear_column(const uint8_t col);
extern uint8_t LEDs[8*MAX7219_NUMBER_UNITS];
// Set all LEDs in a single row
static void set_row(const uint8_t row, const uint32_t val);
static void clear_row(const uint8_t row);
#endif // __MAX7219_DEBUG_LEDS_H__
// 16 and 32 bit versions of Row and Column functions
// Multiple rows and columns will be used to display the value if
// the array of matrix LED's is too narrow to accomplish the goal
static void set_rows_16bits(const uint8_t y, uint32_t val);
static void set_rows_32bits(const uint8_t y, uint32_t val);
static void set_columns_16bits(const uint8_t x, uint32_t val);
static void set_columns_32bits(const uint8_t x, uint32_t val);
// Quickly clear the whole matrix
static void clear();
// Quickly fill the whole matrix
static void fill();
// Apply custom code to update the matrix
static void idle_tasks();
private:
static void error(const char * const func, const int32_t v1, const int32_t v2=-1);
static void noop();
static void set(const uint8_t line, const uint8_t bits);
static void send_row(const uint8_t row);
static void send_column(const uint8_t col);
static void mark16(const uint8_t y, const uint8_t v1, const uint8_t v2);
static void range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh);
static void quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv);
#ifdef MAX7219_INIT_TEST
#if MAX7219_INIT_TEST == 2
static void spiral(const bool on, const uint16_t del);
#else
static void sweep(const int8_t dir, const uint16_t ms, const bool on);
#endif
#endif
};
extern Max7219 max7219;
+98 -39
View File
@@ -403,10 +403,10 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#if ENABLED(LCD_PROGRESS_BAR)
#if DISABLED(SDSUPPORT) && DISABLED(LCD_SET_PROGRESS_MANUALLY)
#error "LCD_PROGRESS_BAR requires SDSUPPORT or LCD_SET_PROGRESS_MANUALLY."
#elif DISABLED(ULTRA_LCD)
#error "LCD_PROGRESS_BAR requires a character LCD."
#elif ENABLED(DOGLCD)
#error "LCD_PROGRESS_BAR does not apply to graphical displays."
#elif DISABLED(ULTIPANEL)
#error "LCD_PROGRESS_BAR requires a character LCD."
#elif ENABLED(FILAMENT_LCD_DISPLAY)
#error "LCD_PROGRESS_BAR and FILAMENT_LCD_DISPLAY are not fully compatible. Comment out this line to use both."
#endif
@@ -465,6 +465,8 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#if ENABLED(BABYSTEPPING)
#if ENABLED(SCARA)
#error "BABYSTEPPING is not implemented for SCARA yet."
#elif ENABLED(HANGPRINTER)
#error "BABYSTEPPING is not implemented for HANGPRINTER."
#elif ENABLED(DELTA) && ENABLED(BABYSTEP_XY)
#error "BABYSTEPPING only implemented for Z axis on deltabots."
#elif ENABLED(BABYSTEP_ZPROBE_OFFSET) && ENABLED(MESH_BED_LEVELING)
@@ -527,8 +529,12 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
/**
* Individual axis homing is useless for DELTAS
*/
#if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU) && ENABLED(DELTA)
#error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with DELTA kinematics."
#if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU)
#if ENABLED(DELTA)
#error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with DELTA kinematics."
#elif ENABLED(HANGPRINTER)
#error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with HANGPRINTER kinematics."
#endif
#endif
/**
@@ -686,6 +692,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
* Allow only one kinematic type to be defined
*/
#if 1 < 0 \
+ ENABLED(HANGPRINTER) \
+ ENABLED(DELTA) \
+ ENABLED(MORGAN_SCARA) \
+ ENABLED(MAKERARM_SCARA) \
@@ -695,7 +702,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
+ ENABLED(COREYX) \
+ ENABLED(COREZX) \
+ ENABLED(COREZY)
#error "Please enable only one of DELTA, MORGAN_SCARA, MAKERARM_SCARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, or COREZY."
#error "Please enable only one of HANGPRINTER, DELTA, MORGAN_SCARA, MAKERARM_SCARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, or COREZY."
#endif
/**
@@ -717,6 +724,42 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#endif
#endif
/**
* Hangprinter requirements
*/
#if ENABLED(HANGPRINTER)
#if EXTRUDERS > 4
#error "Marlin supports a maximum of 4 EXTRUDERS when driving a Hangprinter."
#elif ENABLED(CONVENTIONAL_GEOMETRY)
#if ANCHOR_A_Y > 0
#error "ANCHOR_A_Y should be negative by convention."
#elif (ANCHOR_B_X) * (ANCHOR_C_X) > 0
#error "ANCHOR_B_X and ANCHOR_C_X should have opposite signs by convention."
#elif ANCHOR_B_Y < 0
#error "ANCHOR_B_Y should be positive by convention."
#elif ANCHOR_C_Y < 0
#error "ANCHOR_C_Y should be positive by convention."
#elif ANCHOR_A_Z > 0
#error "ANCHOR_A_Z should be negative by convention."
#elif ANCHOR_B_Z > 0
#error "ANCHOR_B_Z should be negative by convention."
#elif ANCHOR_C_Z > 0
#error "ANCHOR_C_Z should be negative by convention."
#elif ANCHOR_D_Z < 0
#error "ANCHOR_D_Z should be positive by convention."
#endif
#endif
#elif ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
#error "LINE_BUILDUP_COMPENSATION_FEATURE is only compatible with HANGPRINTER."
#endif
/**
* Mechaduino requirements
*/
#if ENABLED(MECHADUINO_I2C_COMMANDS) && DISABLED(EXPERIMENTAL_I2CBUS)
#error "MECHADUINO_I2C_COMMANDS requires EXPERIMENTAL_I2CBUS to be enabled."
#endif
/**
* Probes
*/
@@ -761,6 +804,14 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#if HAS_Z_SERVO_PROBE
#ifndef NUM_SERVOS
#error "You must set NUM_SERVOS for a Z servo probe (Z_PROBE_SERVO_NR)."
#elif Z_PROBE_SERVO_NR == 0 && !PIN_EXISTS(SERVO0)
#error "SERVO0_PIN must be defined for your servo or BLTOUCH probe."
#elif Z_PROBE_SERVO_NR == 1 && !PIN_EXISTS(SERVO1)
#error "SERVO1_PIN must be defined for your servo or BLTOUCH probe."
#elif Z_PROBE_SERVO_NR == 2 && !PIN_EXISTS(SERVO2)
#error "SERVO2_PIN must be defined for your servo or BLTOUCH probe."
#elif Z_PROBE_SERVO_NR == 3 && !PIN_EXISTS(SERVO3)
#error "SERVO3_PIN must be defined for your servo or BLTOUCH probe."
#elif Z_PROBE_SERVO_NR >= NUM_SERVOS
#error "Z_PROBE_SERVO_NR must be smaller than NUM_SERVOS."
#endif
@@ -1203,6 +1254,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#endif
#endif
#endif
/**
* Endstop Tests
*/
@@ -1210,33 +1262,33 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#define _PLUG_UNUSED_TEST(AXIS,PLUG) (DISABLED(USE_##PLUG##MIN_PLUG) && DISABLED(USE_##PLUG##MAX_PLUG) && !(ENABLED(AXIS##_DUAL_ENDSTOPS) && WITHIN(AXIS##2_USE_ENDSTOP, _##PLUG##MAX_, _##PLUG##MIN_)))
#define _AXIS_PLUG_UNUSED_TEST(AXIS) (_PLUG_UNUSED_TEST(AXIS,X) && _PLUG_UNUSED_TEST(AXIS,Y) && _PLUG_UNUSED_TEST(AXIS,Z))
// At least 3 endstop plugs must be used
#if _AXIS_PLUG_UNUSED_TEST(X)
#error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG."
#endif
#if _AXIS_PLUG_UNUSED_TEST(Y)
#error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG."
#endif
#if _AXIS_PLUG_UNUSED_TEST(Z)
#error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG."
#endif
// Delta and Cartesian use 3 homing endstops
#if !IS_SCARA
#if X_HOME_DIR < 0 && DISABLED(USE_XMIN_PLUG)
#error "Enable USE_XMIN_PLUG when homing X to MIN."
#elif X_HOME_DIR > 0 && DISABLED(USE_XMAX_PLUG)
#error "Enable USE_XMAX_PLUG when homing X to MAX."
#elif Y_HOME_DIR < 0 && DISABLED(USE_YMIN_PLUG)
#error "Enable USE_YMIN_PLUG when homing Y to MIN."
#elif Y_HOME_DIR > 0 && DISABLED(USE_YMAX_PLUG)
#error "Enable USE_YMAX_PLUG when homing Y to MAX."
#if DISABLED(HANGPRINTER)
// At least 3 endstop plugs must be used
#if _AXIS_PLUG_UNUSED_TEST(X)
#error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG."
#elif _AXIS_PLUG_UNUSED_TEST(Y)
#error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG."
#elif _AXIS_PLUG_UNUSED_TEST(Z)
#error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG."
#endif
// Delta and Cartesian use 3 homing endstops
#if !IS_SCARA
#if X_HOME_DIR < 0 && DISABLED(USE_XMIN_PLUG)
#error "Enable USE_XMIN_PLUG when homing X to MIN."
#elif X_HOME_DIR > 0 && DISABLED(USE_XMAX_PLUG)
#error "Enable USE_XMAX_PLUG when homing X to MAX."
#elif Y_HOME_DIR < 0 && DISABLED(USE_YMIN_PLUG)
#error "Enable USE_YMIN_PLUG when homing Y to MIN."
#elif Y_HOME_DIR > 0 && DISABLED(USE_YMAX_PLUG)
#error "Enable USE_YMAX_PLUG when homing Y to MAX."
#endif
#endif
#if Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG)
#error "Enable USE_ZMIN_PLUG when homing Z to MIN."
#elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG)
#error "Enable USE_ZMAX_PLUG when homing Z to MAX."
#endif
#endif
#if Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG)
#error "Enable USE_ZMIN_PLUG when homing Z to MIN."
#elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG)
#error "Enable USE_ZMAX_PLUG when homing Z to MAX."
#endif
// Dual endstops requirements
@@ -1523,7 +1575,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#endif
#if ENABLED(STEALTHCHOP) && !HAS_STEALTHCHOP
#error "STEALTHCHOP requires TMC2130 or TMC2208 stepper drivers."
#endif
#endif
/**
* Digipot requirement
@@ -1536,17 +1588,24 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#endif
/**
* Require 4 or more elements in per-axis initializers
* Require 5/4 or more elements in per-axis initializers
*/
#if ENABLED(HANGPRINTER)
#define MIN_ELEMENTS "5"
#else
#define MIN_ELEMENTS "4"
#endif
constexpr float sanity_arr_1[] = DEFAULT_AXIS_STEPS_PER_UNIT,
sanity_arr_2[] = DEFAULT_MAX_FEEDRATE,
sanity_arr_3[] = DEFAULT_MAX_ACCELERATION;
static_assert(COUNT(sanity_arr_1) >= XYZE, "DEFAULT_AXIS_STEPS_PER_UNIT requires 4 (or more) elements.");
static_assert(COUNT(sanity_arr_2) >= XYZE, "DEFAULT_MAX_FEEDRATE requires 4 (or more) elements.");
static_assert(COUNT(sanity_arr_3) >= XYZE, "DEFAULT_MAX_ACCELERATION requires 4 (or more) elements.");
static_assert(COUNT(sanity_arr_1) <= XYZE_N, "DEFAULT_AXIS_STEPS_PER_UNIT has too many elements.");
static_assert(COUNT(sanity_arr_2) <= XYZE_N, "DEFAULT_MAX_FEEDRATE has too many elements.");
static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too many elements.");
static_assert(COUNT(sanity_arr_1) >= NUM_AXIS, "DEFAULT_AXIS_STEPS_PER_UNIT requires " MIN_ELEMENTS " (or more) elements for HANGPRINTER.");
static_assert(COUNT(sanity_arr_2) >= NUM_AXIS, "DEFAULT_MAX_FEEDRATE requires " MIN_ELEMENTS " (or more) elements for HANGPRINTER.");
static_assert(COUNT(sanity_arr_3) >= NUM_AXIS, "DEFAULT_MAX_ACCELERATION requires " MIN_ELEMENTS " (or more) elements for HANGPRINTER.");
static_assert(COUNT(sanity_arr_1) <= NUM_AXIS_N, "DEFAULT_AXIS_STEPS_PER_UNIT has too many elements.");
static_assert(COUNT(sanity_arr_2) <= NUM_AXIS_N, "DEFAULT_MAX_FEEDRATE has too many elements.");
static_assert(COUNT(sanity_arr_3) <= NUM_AXIS_N, "DEFAULT_MAX_ACCELERATION has too many elements.");
/**
* Sanity checks for Spindle / Laser
+1 -1
View File
@@ -399,7 +399,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
#if ENABLED(SD_CHECK_AND_RETRY)
uint8_t retryCnt = 3;
for(;;) {
for (;;) {
if (cardCommand(CMD17, blockNumber))
error(SD_CARD_ERROR_CMD17);
else if (readData(dst, 512))
+3 -3
View File
@@ -35,7 +35,7 @@
/**
* Marlin release version identifier
*/
#define SHORT_BUILD_VERSION "TM3D 1.1.8_R7"
#define SHORT_BUILD_VERSION "TM3D 1.1.9_R2"
/**
* Verbose version identifier which should contain a reference to the location
@@ -48,7 +48,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
#define STRING_DISTRIBUTION_DATE "2018-07-28"
#define STRING_DISTRIBUTION_DATE "2018-09-30"
/**
* Required minimum Configuration.h and Configuration_adv.h file versions.
@@ -89,6 +89,6 @@
* The WEBSITE_URL is the location where users can get more information such as
* documentation about a specific Marlin release.
*/
#define WEBSITE_URL "www.formbotusa.com"
#define WEBSITE_URL "tinymachines3d.com"
#endif // USE_AUTOMATIC_VERSIONING
+167 -43
View File
@@ -95,19 +95,19 @@ typedef struct SettingsDataStruct {
//
// DISTINCT_E_FACTORS
//
uint8_t esteppers; // XYZE_N - XYZ
uint8_t esteppers; // NUM_AXIS_N - MOV_AXIS
uint32_t planner_max_acceleration_mm_per_s2[XYZE_N], // M201 XYZE planner.max_acceleration_mm_per_s2[XYZE_N]
planner_min_segment_time_us; // M205 B planner.min_segment_time_us
float planner_axis_steps_per_mm[XYZE_N], // M92 XYZE planner.axis_steps_per_mm[XYZE_N]
planner_max_feedrate_mm_s[XYZE_N], // M203 XYZE planner.max_feedrate_mm_s[XYZE_N]
planner_acceleration, // M204 P planner.acceleration
planner_retract_acceleration, // M204 R planner.retract_acceleration
planner_travel_acceleration, // M204 T planner.travel_acceleration
planner_min_feedrate_mm_s, // M205 S planner.min_feedrate_mm_s
planner_min_travel_feedrate_mm_s, // M205 T planner.min_travel_feedrate_mm_s
planner_max_jerk[XYZE], // M205 XYZE planner.max_jerk[XYZE]
planner_junction_deviation_mm; // M205 J planner.junction_deviation_mm
uint32_t planner_max_acceleration_mm_per_s2[NUM_AXIS_N], // M201 XYZE/ABCDE planner.max_acceleration_mm_per_s2[NUM_AXIS_N]
planner_min_segment_time_us; // M205 Q planner.min_segment_time_us
float planner_axis_steps_per_mm[NUM_AXIS_N], // M92 XYZE/ABCDE planner.axis_steps_per_mm[NUM_AXIS_N]
planner_max_feedrate_mm_s[NUM_AXIS_N], // M203 XYZE/ABCDE planner.max_feedrate_mm_s[NUM_AXIS_N]
planner_acceleration, // M204 P planner.acceleration
planner_retract_acceleration, // M204 R planner.retract_acceleration
planner_travel_acceleration, // M204 T planner.travel_acceleration
planner_min_feedrate_mm_s, // M205 S planner.min_feedrate_mm_s
planner_min_travel_feedrate_mm_s, // M205 T planner.min_travel_feedrate_mm_s
planner_max_jerk[NUM_AXIS], // M205 XYZE/ABCDE planner.max_jerk[NUM_AXIS]
planner_junction_deviation_mm; // M205 J planner.junction_deviation_mm
float home_offset[XYZ]; // M206 XYZ
@@ -163,6 +163,7 @@ typedef struct SettingsDataStruct {
// DELTA / [XYZ]_DUAL_ENDSTOPS
//
#if ENABLED(DELTA)
float delta_height, // M666 H
delta_endstop_adj[ABC], // M666 XYZ
delta_radius, // M665 R
@@ -170,10 +171,27 @@ typedef struct SettingsDataStruct {
delta_segments_per_second, // M665 S
delta_calibration_radius, // M665 B
delta_tower_angle_trim[ABC]; // M665 XYZ
#elif ENABLED(HANGPRINTER)
float anchor_A_y, // M665 W
anchor_A_z, // M665 E
anchor_B_x, // M665 R
anchor_B_y, // M665 T
anchor_B_z, // M665 Y
anchor_C_x, // M665 U
anchor_C_y, // M665 I
anchor_C_z, // M665 O
anchor_D_z, // M665 P
delta_segments_per_second, // M665 S
hangprinter_calibration_radius_placeholder;
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
float x_endstop_adj, // M666 X
y_endstop_adj, // M666 Y
z_endstop_adj; // M666 Z
#endif
//
@@ -285,6 +303,8 @@ void MarlinSettings::postprocess() {
// planner position so the stepper counts will be set correctly.
#if ENABLED(DELTA)
recalc_delta_settings();
#elif ENABLED(HANGPRINTER)
recalc_hangprinter_settings();
#endif
#if ENABLED(PIDTEMP)
@@ -418,7 +438,7 @@ void MarlinSettings::postprocess() {
_FIELD_TEST(esteppers);
const uint8_t esteppers = COUNT(planner.axis_steps_per_mm) - XYZ;
const uint8_t esteppers = NUM_AXIS_N - MOV_AXIS;
EEPROM_WRITE(esteppers);
EEPROM_WRITE(planner.max_acceleration_mm_per_s2);
@@ -432,7 +452,13 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(planner.min_travel_feedrate_mm_s);
#if ENABLED(JUNCTION_DEVIATION)
const float planner_max_jerk[] = { float(DEFAULT_XJERK), float(DEFAULT_YJERK), float(DEFAULT_ZJERK), float(DEFAULT_EJERK) };
const float planner_max_jerk[] = {
#if ENABLED(HANGPRINTER)
float(DEFAULT_AJERK), float(DEFAULT_BJERK), float(DEFAULT_CJERK), float(DEFAULT_DJERK), float(DEFAULT_EJERK)
#else
float(DEFAULT_XJERK), float(DEFAULT_YJERK), float(DEFAULT_ZJERK), float(DEFAULT_EJERK)
#endif
};
EEPROM_WRITE(planner_max_jerk);
EEPROM_WRITE(planner.junction_deviation_mm);
#else
@@ -560,6 +586,22 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(delta_calibration_radius); // 1 float
EEPROM_WRITE(delta_tower_angle_trim); // 3 floats
#elif ENABLED(HANGPRINTER)
dummy = 0.0f;
_FIELD_TEST(anchor_A_y);
EEPROM_WRITE(anchor_A_y); // 1 float
EEPROM_WRITE(anchor_A_z); // 1 float
EEPROM_WRITE(anchor_B_x); // 1 float
EEPROM_WRITE(anchor_B_y); // 1 float
EEPROM_WRITE(anchor_B_z); // 1 float
EEPROM_WRITE(anchor_C_x); // 1 float
EEPROM_WRITE(anchor_C_y); // 1 float
EEPROM_WRITE(anchor_C_z); // 1 float
EEPROM_WRITE(anchor_D_z); // 1 float
EEPROM_WRITE(delta_segments_per_second); // 1 float
EEPROM_WRITE(dummy); // 1 float
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
_FIELD_TEST(x_endstop_adj);
@@ -1010,17 +1052,17 @@ void MarlinSettings::postprocess() {
const uint32_t def1[] = DEFAULT_MAX_ACCELERATION;
const float def2[] = DEFAULT_AXIS_STEPS_PER_UNIT, def3[] = DEFAULT_MAX_FEEDRATE;
uint32_t tmp1[XYZ + esteppers];
uint32_t tmp1[MOV_AXIS + esteppers];
EEPROM_READ(tmp1); // max_acceleration_mm_per_s2
EEPROM_READ(planner.min_segment_time_us);
float tmp2[XYZ + esteppers], tmp3[XYZ + esteppers];
float tmp2[MOV_AXIS + esteppers], tmp3[MOV_AXIS + esteppers];
EEPROM_READ(tmp2); // axis_steps_per_mm
EEPROM_READ(tmp3); // max_feedrate_mm_s
if (!validating) LOOP_XYZE_N(i) {
planner.max_acceleration_mm_per_s2[i] = i < XYZ + esteppers ? tmp1[i] : def1[i < COUNT(def1) ? i : COUNT(def1) - 1];
planner.axis_steps_per_mm[i] = i < XYZ + esteppers ? tmp2[i] : def2[i < COUNT(def2) ? i : COUNT(def2) - 1];
planner.max_feedrate_mm_s[i] = i < XYZ + esteppers ? tmp3[i] : def3[i < COUNT(def3) ? i : COUNT(def3) - 1];
if (!validating) LOOP_NUM_AXIS_N(i) {
planner.max_acceleration_mm_per_s2[i] = i < MOV_AXIS + esteppers ? tmp1[i] : def1[i < COUNT(def1) ? i : COUNT(def1) - 1];
planner.axis_steps_per_mm[i] = i < MOV_AXIS + esteppers ? tmp2[i] : def2[i < COUNT(def2) ? i : COUNT(def2) - 1];
planner.max_feedrate_mm_s[i] = i < MOV_AXIS + esteppers ? tmp3[i] : def3[i < COUNT(def3) ? i : COUNT(def3) - 1];
}
EEPROM_READ(planner.acceleration);
@@ -1165,6 +1207,19 @@ void MarlinSettings::postprocess() {
EEPROM_READ(delta_calibration_radius); // 1 float
EEPROM_READ(delta_tower_angle_trim); // 3 floats
#elif ENABLED(HANGPRINTER)
EEPROM_READ(anchor_A_y); // 1 float
EEPROM_READ(anchor_A_z); // 1 float
EEPROM_READ(anchor_B_x); // 1 float
EEPROM_READ(anchor_B_y); // 1 float
EEPROM_READ(anchor_B_z); // 1 float
EEPROM_READ(anchor_C_x); // 1 float
EEPROM_READ(anchor_C_y); // 1 float
EEPROM_READ(anchor_C_z); // 1 float
EEPROM_READ(anchor_D_z); // 1 float
EEPROM_READ(delta_segments_per_second); // 1 float
EEPROM_READ(dummy); // 1 float
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
_FIELD_TEST(x_endstop_adj);
@@ -1714,8 +1769,9 @@ void MarlinSettings::postprocess() {
*/
void MarlinSettings::reset() {
static const float tmp1[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] PROGMEM = DEFAULT_MAX_FEEDRATE;
static const uint32_t tmp3[] PROGMEM = DEFAULT_MAX_ACCELERATION;
LOOP_XYZE_N(i) {
LOOP_NUM_AXIS_N(i) {
planner.axis_steps_per_mm[i] = pgm_read_float(&tmp1[i < COUNT(tmp1) ? i : COUNT(tmp1) - 1]);
planner.max_feedrate_mm_s[i] = pgm_read_float(&tmp2[i < COUNT(tmp2) ? i : COUNT(tmp2) - 1]);
planner.max_acceleration_mm_per_s2[i] = pgm_read_dword_near(&tmp3[i < COUNT(tmp3) ? i : COUNT(tmp3) - 1]);
@@ -1731,9 +1787,16 @@ void MarlinSettings::reset() {
#if ENABLED(JUNCTION_DEVIATION)
planner.junction_deviation_mm = float(JUNCTION_DEVIATION_MM);
#else
planner.max_jerk[X_AXIS] = DEFAULT_XJERK;
planner.max_jerk[Y_AXIS] = DEFAULT_YJERK;
planner.max_jerk[Z_AXIS] = DEFAULT_ZJERK;
#if ENABLED(HANGPRINTER)
planner.max_jerk[A_AXIS] = DEFAULT_AJERK;
planner.max_jerk[B_AXIS] = DEFAULT_BJERK;
planner.max_jerk[C_AXIS] = DEFAULT_CJERK;
planner.max_jerk[D_AXIS] = DEFAULT_DJERK;
#else
planner.max_jerk[X_AXIS] = DEFAULT_XJERK;
planner.max_jerk[Y_AXIS] = DEFAULT_YJERK;
planner.max_jerk[Z_AXIS] = DEFAULT_ZJERK;
#endif
planner.max_jerk[E_AXIS] = DEFAULT_EJERK;
#endif
@@ -1785,6 +1848,19 @@ void MarlinSettings::reset() {
delta_calibration_radius = DELTA_CALIBRATION_RADIUS;
COPY(delta_tower_angle_trim, dta);
#elif ENABLED(HANGPRINTER)
anchor_A_y = float(ANCHOR_A_Y);
anchor_A_z = float(ANCHOR_A_Z);
anchor_B_x = float(ANCHOR_B_X);
anchor_B_y = float(ANCHOR_B_Y);
anchor_B_z = float(ANCHOR_B_Z);
anchor_C_x = float(ANCHOR_C_X);
anchor_C_y = float(ANCHOR_C_Y);
anchor_C_z = float(ANCHOR_C_Z);
anchor_D_z = float(ANCHOR_D_Z);
delta_segments_per_second = KINEMATIC_SEGMENTS_PER_SECOND;
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#if ENABLED(X_DUAL_ENDSTOPS)
@@ -1814,7 +1890,6 @@ void MarlinSettings::reset() {
#endif
);
#endif
#endif
#if ENABLED(ULTIPANEL)
@@ -2038,9 +2113,16 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM("Steps per unit:");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M92 X", LINEAR_UNIT(planner.axis_steps_per_mm[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.axis_steps_per_mm[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.axis_steps_per_mm[Z_AXIS]));
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(" M92 A", LINEAR_UNIT(planner.axis_steps_per_mm[A_AXIS]));
SERIAL_ECHOPAIR(" B", LINEAR_UNIT(planner.axis_steps_per_mm[B_AXIS]));
SERIAL_ECHOPAIR(" C", LINEAR_UNIT(planner.axis_steps_per_mm[C_AXIS]));
SERIAL_ECHOPAIR(" D", LINEAR_UNIT(planner.axis_steps_per_mm[D_AXIS]));
#else
SERIAL_ECHOPAIR(" M92 X", LINEAR_UNIT(planner.axis_steps_per_mm[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.axis_steps_per_mm[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.axis_steps_per_mm[Z_AXIS]));
#endif
#if DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS]));
#endif
@@ -2058,9 +2140,16 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM("Maximum feedrates (units/s):");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M203 X", LINEAR_UNIT(planner.max_feedrate_mm_s[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_feedrate_mm_s[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_feedrate_mm_s[Z_AXIS]));
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(" M203 A", LINEAR_UNIT(planner.max_feedrate_mm_s[A_AXIS]));
SERIAL_ECHOPAIR(" B", LINEAR_UNIT(planner.max_feedrate_mm_s[B_AXIS]));
SERIAL_ECHOPAIR(" C", LINEAR_UNIT(planner.max_feedrate_mm_s[C_AXIS]));
SERIAL_ECHOPAIR(" D", LINEAR_UNIT(planner.max_feedrate_mm_s[D_AXIS]));
#else
SERIAL_ECHOPAIR(" M203 X", LINEAR_UNIT(planner.max_feedrate_mm_s[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_feedrate_mm_s[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_feedrate_mm_s[Z_AXIS]));
#endif
#if DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS]));
#endif
@@ -2078,9 +2167,16 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM("Maximum Acceleration (units/s2):");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M201 X", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Z_AXIS]));
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(" M201 A", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[A_AXIS]));
SERIAL_ECHOPAIR(" B", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[B_AXIS]));
SERIAL_ECHOPAIR(" C", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[C_AXIS]));
SERIAL_ECHOPAIR(" D", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[D_AXIS]));
#else
SERIAL_ECHOPAIR(" M201 X", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Z_AXIS]));
#endif
#if DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS]));
#endif
@@ -2104,11 +2200,15 @@ void MarlinSettings::reset() {
if (!forReplay) {
CONFIG_ECHO_START;
SERIAL_ECHOPGM("Advanced: B<min_segment_time_us> S<min_feedrate> T<min_travel_feedrate>");
SERIAL_ECHOPGM("Advanced: Q<min_segment_time_us> S<min_feedrate> T<min_travel_feedrate>");
#if ENABLED(JUNCTION_DEVIATION)
SERIAL_ECHOPGM(" J<junc_dev>");
#else
SERIAL_ECHOPGM(" X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk>");
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPGM(" A<max_a_jerk> B<max_b_jerk> C<max_c_jerk> D<max_d_jerk>");
#else
SERIAL_ECHOPGM(" X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk>");
#endif
#endif
#if DISABLED(JUNCTION_DEVIATION) || ENABLED(LIN_ADVANCE)
SERIAL_ECHOPGM(" E<max_e_jerk>");
@@ -2116,19 +2216,25 @@ void MarlinSettings::reset() {
SERIAL_EOL();
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M205 B", LINEAR_UNIT(planner.min_segment_time_us));
SERIAL_ECHOPAIR(" M205 Q", LINEAR_UNIT(planner.min_segment_time_us));
SERIAL_ECHOPAIR(" S", LINEAR_UNIT(planner.min_feedrate_mm_s));
SERIAL_ECHOPAIR(" T", LINEAR_UNIT(planner.min_travel_feedrate_mm_s));
#if ENABLED(JUNCTION_DEVIATION)
SERIAL_ECHOPAIR(" J", LINEAR_UNIT(planner.junction_deviation_mm));
#else
SERIAL_ECHOPAIR(" X", LINEAR_UNIT(planner.max_jerk[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS]));
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(" A", LINEAR_UNIT(planner.max_jerk[A_AXIS]));
SERIAL_ECHOPAIR(" B", LINEAR_UNIT(planner.max_jerk[B_AXIS]));
SERIAL_ECHOPAIR(" C", LINEAR_UNIT(planner.max_jerk[C_AXIS]));
SERIAL_ECHOPAIR(" D", LINEAR_UNIT(planner.max_jerk[D_AXIS]));
#else
SERIAL_ECHOPAIR(" X", LINEAR_UNIT(planner.max_jerk[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS]));
#endif
SERIAL_ECHOPAIR(" E", LINEAR_UNIT(planner.max_jerk[E_AXIS]));
#endif
SERIAL_EOL();
#if HAS_M206_COMMAND
@@ -2219,8 +2325,8 @@ void MarlinSettings::reset() {
SERIAL_ECHOPAIR("EEPROM can hold ", calc_num_meshes());
SERIAL_ECHOLNPGM(" meshes.\n");
}
// ubl.report_current_mesh(PORTVAR_SOLO); // This is too verbose for large mesh's. A better (more terse)
//ubl.report_current_mesh(PORTVAR_SOLO); // This is too verbose for large mesh's. A better (more terse)
// solution needs to be found.
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
@@ -2266,6 +2372,24 @@ void MarlinSettings::reset() {
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS]));
SERIAL_EOL();
#elif ENABLED(HANGPRINTER)
if (!forReplay) {
CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Hangprinter settings: W<Ay> E<Az> R<Bx> T<By> Y<Bz> U<Cx> I<Cy> O<Cz> P<Dz> S<segments_per_s>");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M665 W", anchor_A_y);
SERIAL_ECHOPAIR(" E", anchor_A_z);
SERIAL_ECHOPAIR(" R", anchor_B_x);
SERIAL_ECHOPAIR(" T", anchor_B_y);
SERIAL_ECHOPAIR(" Y", anchor_B_z);
SERIAL_ECHOPAIR(" U", anchor_C_x);
SERIAL_ECHOPAIR(" I", anchor_C_y);
SERIAL_ECHOPAIR(" O", anchor_C_z);
SERIAL_ECHOPAIR(" P", anchor_D_z);
SERIAL_ECHOPAIR(" S", delta_segments_per_second);
SERIAL_EOL();
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
if (!forReplay) {
+15 -47
View File
@@ -40,52 +40,21 @@
#define TMC2660 0x10B
#define TMC2660_STANDALONE 0x00B
#define AXIS_DRIVER_TYPE(A,T) ( defined(A##_DRIVER_TYPE) && (A##_DRIVER_TYPE == T) )
#define _AXIS_DRIVER_TYPE(A,T) ( defined(A##_DRIVER_TYPE) && (A##_DRIVER_TYPE == T) )
#define AXIS_DRIVER_TYPE_X(T) AXIS_DRIVER_TYPE(X,T)
#define AXIS_DRIVER_TYPE_Y(T) AXIS_DRIVER_TYPE(Y,T)
#define AXIS_DRIVER_TYPE_Z(T) AXIS_DRIVER_TYPE(Z,T)
#define AXIS_DRIVER_TYPE_X(T) _AXIS_DRIVER_TYPE(X,T)
#define AXIS_DRIVER_TYPE_Y(T) _AXIS_DRIVER_TYPE(Y,T)
#define AXIS_DRIVER_TYPE_Z(T) _AXIS_DRIVER_TYPE(Z,T)
#define AXIS_DRIVER_TYPE_X2(T) (ENABLED(X_DUAL_STEPPER_DRIVERS) || ENABLED(DUAL_X_CARRIAGE)) && _AXIS_DRIVER_TYPE(X2,T)
#define AXIS_DRIVER_TYPE_Y2(T) (ENABLED(Y_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Y2,T))
#define AXIS_DRIVER_TYPE_Z2(T) (ENABLED(Z_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Z2,T))
#define AXIS_DRIVER_TYPE_E0(T) (E_STEPPERS > 0 && _AXIS_DRIVER_TYPE(E0,T))
#define AXIS_DRIVER_TYPE_E1(T) (E_STEPPERS > 1 && _AXIS_DRIVER_TYPE(E1,T))
#define AXIS_DRIVER_TYPE_E2(T) (E_STEPPERS > 2 && _AXIS_DRIVER_TYPE(E2,T))
#define AXIS_DRIVER_TYPE_E3(T) (E_STEPPERS > 3 && _AXIS_DRIVER_TYPE(E3,T))
#define AXIS_DRIVER_TYPE_E4(T) (E_STEPPERS > 4 && _AXIS_DRIVER_TYPE(E4,T))
#if ENABLED(X_DUAL_STEPPER_DRIVERS) || ENABLED(DUAL_X_CARRIAGE)
#define AXIS_DRIVER_TYPE_X2(T) AXIS_DRIVER_TYPE(X2,T)
#else
#define AXIS_DRIVER_TYPE_X2(T) false
#endif
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
#define AXIS_DRIVER_TYPE_Y2(T) AXIS_DRIVER_TYPE(Y2,T)
#else
#define AXIS_DRIVER_TYPE_Y2(T) false
#endif
#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
#define AXIS_DRIVER_TYPE_Z2(T) AXIS_DRIVER_TYPE(Z2,T)
#else
#define AXIS_DRIVER_TYPE_Z2(T) false
#endif
#if E_STEPPERS > 0
#define AXIS_DRIVER_TYPE_E0(T) AXIS_DRIVER_TYPE(E0,T)
#else
#define AXIS_DRIVER_TYPE_E0(T) false
#endif
#if E_STEPPERS > 1
#define AXIS_DRIVER_TYPE_E1(T) AXIS_DRIVER_TYPE(E1,T)
#else
#define AXIS_DRIVER_TYPE_E1(T) false
#endif
#if E_STEPPERS > 2
#define AXIS_DRIVER_TYPE_E2(T) AXIS_DRIVER_TYPE(E2,T)
#else
#define AXIS_DRIVER_TYPE_E2(T) false
#endif
#if E_STEPPERS > 3
#define AXIS_DRIVER_TYPE_E3(T) AXIS_DRIVER_TYPE(E3,T)
#else
#define AXIS_DRIVER_TYPE_E3(T) false
#endif
#if E_STEPPERS > 4
#define AXIS_DRIVER_TYPE_E4(T) AXIS_DRIVER_TYPE(E4,T)
#else
#define AXIS_DRIVER_TYPE_E4(T) false
#endif
#define AXIS_DRIVER_TYPE(A,T) AXIS_DRIVER_TYPE_##A(T)
#define HAS_DRIVER(T) (AXIS_DRIVER_TYPE_X(T) || AXIS_DRIVER_TYPE_X2(T) || \
AXIS_DRIVER_TYPE_Y(T) || AXIS_DRIVER_TYPE_Y2(T) || \
@@ -96,10 +65,9 @@
// Test for supported TMC drivers that require advanced configuration
// Does not match standalone configurations
#define HAS_TRINAMIC ( HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2660) )
#define HAS_TRINAMIC (HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2208))
#define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE_##A(TMC2130) || \
AXIS_DRIVER_TYPE_##A(TMC2208) || \
AXIS_DRIVER_TYPE_##A(TMC2660) )
AXIS_DRIVER_TYPE_##A(TMC2208) )
#endif // _DRIVERS_H_
+41 -14
View File
@@ -229,11 +229,13 @@ void Endstops::not_homing() {
#endif
}
// If the last move failed to trigger an endstop, call kill
void Endstops::validate_homing_move() {
if (trigger_state()) hit_on_purpose();
else kill(PSTR(MSG_ERR_HOMING_FAILED));
}
#if ENABLED(VALIDATE_HOMING_ENDSTOPS)
// If the last move failed to trigger an endstop, call kill
void Endstops::validate_homing_move() {
if (trigger_state()) hit_on_purpose();
else kill(PSTR(MSG_ERR_HOMING_FAILED));
}
#endif
// Enable / disable endstop z-probe checking
#if HAS_BED_PROBE
@@ -306,12 +308,16 @@ void Endstops::event_handler() {
prev_hit_state = hit_state;
} // Endstops::report_state
void Endstops::M119() {
static void print_es_state(const bool is_hit, const char * const label=NULL) {
if (label) serialprintPGM(label);
SERIAL_PROTOCOLPGM(": ");
serialprintPGM(is_hit ? PSTR(MSG_ENDSTOP_HIT) : PSTR(MSG_ENDSTOP_OPEN));
SERIAL_EOL();
}
void _O2 Endstops::M119() {
SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT);
#define ES_REPORT(AXIS) do{ \
SERIAL_PROTOCOLPGM(MSG_##AXIS); \
SERIAL_PROTOCOLLN(((READ(AXIS##_PIN)^AXIS##_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); \
}while(0)
#define ES_REPORT(S) print_es_state(READ(S##_PIN) != S##_ENDSTOP_INVERTING, PSTR(MSG_##S))
#if HAS_X_MIN
ES_REPORT(X_MIN);
#endif
@@ -349,12 +355,33 @@ void Endstops::M119() {
ES_REPORT(Z2_MAX);
#endif
#if ENABLED(Z_MIN_PROBE_ENDSTOP)
SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
SERIAL_PROTOCOLLN(((READ(Z_MIN_PROBE_PIN)^Z_MIN_PROBE_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
print_es_state(READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING, PSTR(MSG_Z_PROBE));
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
SERIAL_PROTOCOLPGM(MSG_FILAMENT_RUNOUT_SENSOR);
SERIAL_PROTOCOLLN(((READ(FIL_RUNOUT_PIN)^FIL_RUNOUT_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#if NUM_RUNOUT_SENSORS == 1
print_es_state(READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_INVERTING, PSTR(MSG_FILAMENT_RUNOUT_SENSOR));
#else
for (uint8_t i = 1; i <= NUM_RUNOUT_SENSORS; i++) {
pin_t pin;
switch (i) {
default: continue;
case 1: pin = FIL_RUNOUT_PIN; break;
case 2: pin = FIL_RUNOUT2_PIN; break;
#if NUM_RUNOUT_SENSORS > 2
case 3: pin = FIL_RUNOUT3_PIN; break;
#if NUM_RUNOUT_SENSORS > 3
case 4: pin = FIL_RUNOUT4_PIN; break;
#if NUM_RUNOUT_SENSORS > 4
case 5: pin = FIL_RUNOUT5_PIN; break;
#endif
#endif
#endif
}
SERIAL_PROTOCOLPGM(MSG_FILAMENT_RUNOUT_SENSOR);
if (i > 1) { SERIAL_CHAR(' '); SERIAL_CHAR('0' + i); }
print_es_state(digitalRead(pin) != FIL_RUNOUT_INVERTING);
}
#endif
#endif
} // Endstops::M119
+8 -2
View File
@@ -29,6 +29,8 @@
#include "MarlinConfig.h"
#define VALIDATE_HOMING_ENDSTOPS
enum EndstopEnum : char {
X_MIN,
Y_MIN,
@@ -143,8 +145,12 @@ class Endstops {
// Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable
static void not_homing();
// If the last move failed to trigger an endstop, call kill
static void validate_homing_move();
#if ENABLED(VALIDATE_HOMING_ENDSTOPS)
// If the last move failed to trigger an endstop, call kill
static void validate_homing_move();
#else
FORCE_INLINE static void validate_homing_move() { hit_on_purpose(); }
#endif
// Clear endstops (i.e., they were hit intentionally) to suppress the report
FORCE_INLINE static void hit_on_purpose() { hit_state = 0; }
+12 -8
View File
@@ -39,10 +39,14 @@ enum AxisEnum : unsigned char {
B_AXIS = 1,
Z_AXIS = 2,
C_AXIS = 2,
E_AXIS = 3,
X_HEAD = 4,
Y_HEAD = 5,
Z_HEAD = 6,
E_CART = 3,
#if ENABLED(HANGPRINTER) // Hangprinter order: A_AXIS, B_AXIS, C_AXIS, D_AXIS, E_AXIS
D_AXIS = 3,
E_AXIS = 4,
#else
E_AXIS = 3,
#endif
X_HEAD, Y_HEAD, Z_HEAD,
ALL_AXES = 0xFE,
NO_AXIS = 0xFF
};
@@ -54,11 +58,11 @@ enum AxisEnum : unsigned char {
#define LOOP_NA(VAR) LOOP_L_N(VAR, NUM_AXIS)
#define LOOP_XYZ(VAR) LOOP_S_LE_N(VAR, X_AXIS, Z_AXIS)
#define LOOP_XYZE(VAR) LOOP_S_LE_N(VAR, X_AXIS, E_AXIS)
#define LOOP_XYZE(VAR) LOOP_S_LE_N(VAR, X_AXIS, E_CART)
#define LOOP_XYZE_N(VAR) LOOP_S_L_N(VAR, X_AXIS, XYZE_N)
#define LOOP_ABC(VAR) LOOP_S_LE_N(VAR, A_AXIS, C_AXIS)
#define LOOP_ABCE(VAR) LOOP_S_LE_N(VAR, A_AXIS, E_AXIS)
#define LOOP_ABCE_N(VAR) LOOP_S_L_N(VAR, A_AXIS, XYZE_N)
#define LOOP_MOV_AXIS(VAR) LOOP_S_L_N(VAR, A_AXIS, MOV_AXIS)
#define LOOP_NUM_AXIS(VAR) LOOP_S_L_N(VAR, A_AXIS, NUM_AXIS)
#define LOOP_NUM_AXIS_N(VAR) LOOP_S_L_N(VAR, A_AXIS, NUM_AXIS_N)
typedef enum {
LINEARUNIT_MM,
+6 -6
View File
@@ -123,7 +123,7 @@ void FWRetract::retract(const bool retracting
#endif
}
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_CART]);
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
//*/
@@ -131,7 +131,7 @@ void FWRetract::retract(const bool retracting
renormalize = RECIPROCAL(planner.e_factor[active_extruder]),
base_retract = swapping ? swap_retract_length : retract_length,
old_z = current_position[Z_AXIS],
old_e = current_position[E_AXIS];
old_e = current_position[E_CART];
// The current position will be the destination for E and Z moves
set_destination_from_current();
@@ -139,7 +139,7 @@ void FWRetract::retract(const bool retracting
if (retracting) {
// Retract by moving from a faux E position back to the current E position
feedrate_mm_s = retract_feedrate_mm_s;
destination[E_AXIS] -= base_retract * renormalize;
destination[E_CART] -= base_retract * renormalize;
prepare_move_to_destination(); // set_current_to_destination
// Is a Z hop set, and has the hop not yet been done?
@@ -160,14 +160,14 @@ void FWRetract::retract(const bool retracting
hop_amount = 0.0; // Clear the hop amount
}
destination[E_AXIS] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize;
destination[E_CART] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize;
feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
prepare_move_to_destination(); // Recover E, set_current_to_destination
}
feedrate_mm_s = old_feedrate_mm_s; // Restore original feedrate
current_position[Z_AXIS] = old_z; // Restore Z and E positions
current_position[E_AXIS] = old_e;
current_position[E_CART] = old_e;
SYNC_PLAN_POSITION_KINEMATIC(); // As if the move never took place
retracted[active_extruder] = retracting; // Active extruder now retracted / recovered
@@ -190,7 +190,7 @@ void FWRetract::retract(const bool retracting
#endif
}
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_CART]);
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
//*/
+14 -14
View File
@@ -149,23 +149,23 @@
#define MSG_RESEND "Resend: "
#define MSG_UNKNOWN_COMMAND "Unknown command: \""
#define MSG_ACTIVE_EXTRUDER "Active Extruder: "
#define MSG_X_MIN "x_min: "
#define MSG_X_MAX "x_max: "
#define MSG_X2_MIN "x2_min: "
#define MSG_X2_MAX "x2_max: "
#define MSG_Y_MIN "y_min: "
#define MSG_Y_MAX "y_max: "
#define MSG_Y2_MIN "y2_min: "
#define MSG_Y2_MAX "y2_max: "
#define MSG_Z_MIN "z_min: "
#define MSG_Z_MAX "z_max: "
#define MSG_Z2_MIN "z2_min: "
#define MSG_Z2_MAX "z2_max: "
#define MSG_Z_PROBE "z_probe: "
#define MSG_X_MIN "x_min"
#define MSG_X_MAX "x_max"
#define MSG_X2_MIN "x2_min"
#define MSG_X2_MAX "x2_max"
#define MSG_Y_MIN "y_min"
#define MSG_Y_MAX "y_max"
#define MSG_Y2_MIN "y2_min"
#define MSG_Y2_MAX "y2_max"
#define MSG_Z_MIN "z_min"
#define MSG_Z_MAX "z_max"
#define MSG_Z2_MIN "z2_min"
#define MSG_Z2_MAX "z2_max"
#define MSG_Z_PROBE "z_probe"
#define MSG_FILAMENT_RUNOUT_SENSOR "filament"
#define MSG_PROBE_Z_OFFSET "Probe Z Offset"
#define MSG_SKEW_MIN "min_skew_factor: "
#define MSG_SKEW_MAX "max_skew_factor: "
#define MSG_FILAMENT_RUNOUT_SENSOR "filament: "
#define MSG_ERR_MATERIAL_INDEX "M145 S<index> out of range (0-1)"
#define MSG_ERR_M355_NONE "No case light"
#define MSG_ERR_M421_PARAMETERS "M421 incorrect parameter usage"
+1
View File
@@ -44,6 +44,7 @@
#define MSG_AUTO_HOME_X _UxGT("Orichen X")
#define MSG_AUTO_HOME_Y _UxGT("Orichen Y")
#define MSG_AUTO_HOME_Z _UxGT("Orichen Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Orichen XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Encetar (pretar)")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Vinient punto")
+1
View File
@@ -41,6 +41,7 @@
#define MSG_AUTOSTART _UxGT("Автостарт")
#define MSG_DISABLE_STEPPERS _UxGT("Изкл. двигатели")
#define MSG_AUTO_HOME _UxGT("Паркиране")
#define MSG_TMC_Z_CALIBRATION _UxGT("Калибровка Z")
#define MSG_SET_HOME_OFFSETS _UxGT("Задай Начало")
#define MSG_SET_ORIGIN _UxGT("Изходна точка")
#define MSG_PREHEAT_1 _UxGT("Подгряване PLA")
+1
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("X a origen")
#define MSG_AUTO_HOME_Y _UxGT("Y a origen")
#define MSG_AUTO_HOME_Z _UxGT("Z a origen")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibra Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origen XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Premeu per iniciar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Següent punt")
+1
View File
@@ -40,6 +40,7 @@
#define MSG_AUTOSTART "\xb1\xb2\xb3\xb4"
#define MSG_DISABLE_STEPPERS "\xb5\xb6\xb7\xb8\xb9\xba"
#define MSG_AUTO_HOME "\xbb\xbc\xbd"
#define MSG_TMC_Z_CALIBRATION "Calibrate Z"
#define MSG_LEVEL_BED_HOMING "Homing XYZ"
#define MSG_LEVEL_BED_WAITING "Click to Begin"
#define MSG_LEVEL_BED_DONE "Leveling Done!"
+1
View File
@@ -50,6 +50,7 @@
#define MSG_AUTO_HOME_X _UxGT("Domu osa X")
#define MSG_AUTO_HOME_Y _UxGT("Domu osa Y")
#define MSG_AUTO_HOME_Z _UxGT("Domu osa Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibrovat Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Mereni podlozky")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknutim spustte")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Dalsi bod")
+9
View File
@@ -44,6 +44,7 @@
#define MSG_SD_INSERTED _UxGT("Karta vložena")
#define MSG_SD_REMOVED _UxGT("Karta vyjmuta")
#define MSG_LCD_ENDSTOPS _UxGT("Endstopy") // max 8 znaku
#define MSG_LCD_SOFT_ENDSTOPS _UxGT("Soft Endstopy")
#define MSG_MAIN _UxGT("Hlavní nabídka")
#define MSG_AUTOSTART _UxGT("Autostart")
#define MSG_DISABLE_STEPPERS _UxGT("Uvolnit motory")
@@ -53,6 +54,7 @@
#define MSG_AUTO_HOME_X _UxGT("Domů osa X")
#define MSG_AUTO_HOME_Y _UxGT("Domů osa Y")
#define MSG_AUTO_HOME_Z _UxGT("Domů osa Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibrovat Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Měření podložky")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknutím spusťte")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Další bod")
@@ -252,11 +254,13 @@
#define MSG_PAUSE_PRINT _UxGT("Pozastavit tisk")
#define MSG_RESUME_PRINT _UxGT("Obnovit tisk")
#define MSG_STOP_PRINT _UxGT("Zastavit tisk")
#define MSG_POWER_LOSS_RECOVERY _UxGT("Obnova vypadku")
#define MSG_CARD_MENU _UxGT("Tisknout z SD")
#define MSG_NO_CARD _UxGT("Žádná SD karta")
#define MSG_DWELL _UxGT("Uspáno...")
#define MSG_USERWAIT _UxGT("Čekání na uživ...")
#define MSG_PRINT_PAUSED _UxGT("Tisk pozastaven")
#define MSG_PRINTING _UxGT("Tisknu...")
#define MSG_PRINT_ABORTED _UxGT("Tisk zrušen")
#define MSG_NO_MOVE _UxGT("Žádný pohyb.")
#define MSG_KILLED _UxGT("PŘERUSENO. ")
@@ -292,8 +296,10 @@
#define MSG_BABYSTEP_Z _UxGT("Babystep Z")
#define MSG_ENDSTOP_ABORT _UxGT("Endstop abort")
#define MSG_HEATING_FAILED_LCD _UxGT("Chyba zahřívání")
#define MSG_HEATING_FAILED_LCD_BED _UxGT("Chyba zahř. podl.")
#define MSG_ERR_REDUNDANT_TEMP _UxGT("REDUND. TEPLOTA")
#define MSG_THERMAL_RUNAWAY _UxGT("TEPLOTNÍ SKOK")
#define MSG_THERMAL_RUNAWAY_BED _UxGT("PODL. TEPL. SKOK")
#define MSG_ERR_MAXTEMP _UxGT("VYSOKÁ TEPLOTA")
#define MSG_ERR_MINTEMP _UxGT("NÍZKA TEPLOTA")
#define MSG_ERR_MAXTEMP_BED _UxGT("VYS. TEPL. PODL.")
@@ -305,7 +311,9 @@
#define MSG_SHORT_HOUR _UxGT("h")
#define MSG_SHORT_MINUTE _UxGT("m")
#define MSG_HEATING _UxGT("Zahřívání...")
#define MSG_COOLING _UxGT("Chlazení")
#define MSG_BED_HEATING _UxGT("Zahřívání podl...")
#define MSG_BED_COOLING _UxGT("Chlazení podl...")
#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibrace")
#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibrovat X")
#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibrovat Y")
@@ -314,6 +322,7 @@
#define MSG_DELTA_SETTINGS _UxGT("Delta nastavení")
#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Autokalibrace")
#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Nast.výšku delty")
#define MSG_DELTA_Z_OFFSET_CALIBRATE _UxGT("Nast. Z-ofset")
#define MSG_DELTA_DIAG_ROD _UxGT("Diag rameno")
#define MSG_DELTA_HEIGHT _UxGT("Výška")
#define MSG_DELTA_RADIUS _UxGT("Poloměr")
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home X")
#define MSG_AUTO_HOME_Y _UxGT("Home Y")
#define MSG_AUTO_HOME_Z _UxGT("Home Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibrer Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Klik når du er klar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Næste punkt")
+1
View File
@@ -50,6 +50,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home X")
#define MSG_AUTO_HOME_Y _UxGT("Home Y")
#define MSG_AUTO_HOME_Z _UxGT("Home Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibriere Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Home XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Klick für Start")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Nächste Koordinate")
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Αρχικό σημείο X")
#define MSG_AUTO_HOME_Y _UxGT("Αρχικό σημείο Y")
#define MSG_AUTO_HOME_Z _UxGT("Αρχικό σημείο Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Βαθμονόμηση Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Επαναφορά στο αρχικό σημείο ΧΥΖ")
#define MSG_LEVEL_BED_WAITING _UxGT("Κάντε κλικ για να ξεκινήσετε")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Επόμενο σημείο")
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Αρχικό σημείο X")
#define MSG_AUTO_HOME_Y _UxGT("Αρχικό σημείο Y")
#define MSG_AUTO_HOME_Z _UxGT("Αρχικό σημείο Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Βαθμονόμηση Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Επαναφορά Επ. Εκτύπωσης") //SHORTEN
#define MSG_LEVEL_BED_WAITING _UxGT("Επιπεδοποίηση επ. Εκτύπωσης περιμενει") //SHORTEN
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Επόμενο σημείο")
+6 -2
View File
@@ -85,6 +85,9 @@
#ifndef MSG_AUTO_HOME_Z
#define MSG_AUTO_HOME_Z _UxGT("Home Z")
#endif
#ifndef MSG_TMC_Z_CALIBRATION
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrate Z")
#endif
#ifndef MSG_LEVEL_BED_HOMING
#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ")
#endif
@@ -468,14 +471,12 @@
#ifndef MSG_EXTRA_FAN_SPEED
#define MSG_EXTRA_FAN_SPEED _UxGT("Extra fan speed")
#endif
#ifndef MSG_LASER_ON
#define MSG_LASER_ON _UxGT("Laser On")
#endif
#ifndef MSG_LASER_OFF
#define MSG_LASER_OFF _UxGT("Laser Off")
#endif
#ifndef MSG_FLOW
#define MSG_FLOW _UxGT("Flow")
#endif
@@ -1063,6 +1064,9 @@
#ifndef MSG_FILAMENT_CHANGE_INSERT_1
#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insert and Click")
#endif
#ifndef MSG_FILAMENT_CHANGE_HEAT_1
#define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Click to heat")
#endif
#ifndef MSG_FILAMENT_CHANGE_HEATING_1
#define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Heating...")
#endif
+1
View File
@@ -48,6 +48,7 @@
#define MSG_AUTO_HOME_X _UxGT("Origen X")
#define MSG_AUTO_HOME_Y _UxGT("Origen Y")
#define MSG_AUTO_HOME_Z _UxGT("Origen Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origen XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Iniciar (Presione)")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Siguiente punto")
+1
View File
@@ -48,6 +48,7 @@
#define MSG_AUTO_HOME_X _UxGT("Origen X")
#define MSG_AUTO_HOME_Y _UxGT("Origen Y")
#define MSG_AUTO_HOME_Z _UxGT("Origen Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origen XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Iniciar (Presione)")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Siguiente punto")
+1
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("X jatorrira")
#define MSG_AUTO_HOME_Y _UxGT("Y jatorrira")
#define MSG_AUTO_HOME_Z _UxGT("Z jatorrira")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibratu Z")
#define MSG_LEVEL_BED_HOMING _UxGT("XYZ hasieraratzen")
#define MSG_LEVEL_BED_WAITING _UxGT("Klik egin hasteko")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Hurrengo Puntua")
+1
View File
@@ -41,6 +41,7 @@
#define MSG_AUTOSTART _UxGT("Automaatti")
#define MSG_DISABLE_STEPPERS _UxGT("Vapauta moottorit")
#define MSG_AUTO_HOME _UxGT("Aja referenssiin")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibroi Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Click to Begin")
#define MSG_LEVEL_BED_DONE _UxGT("Leveling Done!")
+3 -2
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("Origine X Auto.")
#define MSG_AUTO_HOME_Y _UxGT("Origine Y Auto.")
#define MSG_AUTO_HOME_Z _UxGT("Origine Z Auto.")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrer Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origine XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Clic pour commencer")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Point suivant")
@@ -58,13 +59,13 @@
#define MSG_PREHEAT_1 _UxGT("Prechauffage PLA")
#define MSG_PREHEAT_1_N _UxGT("Prechauff. PLA ")
#define MSG_PREHEAT_1_ALL _UxGT("Prech. PLA Tout")
#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" fini")
#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" buse")
#define MSG_PREHEAT_1_BEDONLY _UxGT("Prech. PLA lit")
#define MSG_PREHEAT_1_SETTINGS _UxGT("Regl. prech. PLA")
#define MSG_PREHEAT_2 _UxGT("Prechauffage ABS")
#define MSG_PREHEAT_2_N _UxGT("Prechauff. ABS ")
#define MSG_PREHEAT_2_ALL _UxGT("Prech. ABS Tout")
#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" fini")
#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" buse")
#define MSG_PREHEAT_2_BEDONLY _UxGT("Prech. ABS lit")
#define MSG_PREHEAT_2_SETTINGS _UxGT("Regl. prech. ABS")
#define MSG_COOLDOWN _UxGT("Refroidir")
+10 -9
View File
@@ -40,7 +40,7 @@
#define MSG_SD_REMOVED _UxGT("Carte retirée")
#define MSG_LCD_ENDSTOPS _UxGT("Butées") // Max length 8 characters
#define MSG_MAIN _UxGT("Menu principal")
#define MSG_AUTOSTART _UxGT("Demarrage auto")
#define MSG_AUTOSTART _UxGT("Démarrage auto")
#define MSG_DISABLE_STEPPERS _UxGT("Arrêter moteurs")
#define MSG_DEBUG_MENU _UxGT("Menu debug")
#define MSG_PROGRESS_BAR_TEST _UxGT("Test barre progress.")
@@ -48,6 +48,7 @@
#define MSG_AUTO_HOME_X _UxGT("Origine X Auto.")
#define MSG_AUTO_HOME_Y _UxGT("Origine Y Auto.")
#define MSG_AUTO_HOME_Z _UxGT("Origine Z Auto.")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrer Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origine XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Clic pour commencer")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Point suivant")
@@ -59,18 +60,18 @@
#define MSG_PREHEAT_1 _UxGT("Préchauffage PLA")
#define MSG_PREHEAT_1_N _UxGT("Préchauff. PLA ")
#define MSG_PREHEAT_1_ALL _UxGT("Préch. PLA Tout")
#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" fini")
#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" buse")
#define MSG_PREHEAT_1_BEDONLY _UxGT("Préch. PLA lit")
#define MSG_PREHEAT_1_SETTINGS _UxGT("Régl. prech. PLA")
#define MSG_PREHEAT_2 _UxGT("Préchauffage ABS")
#define MSG_PREHEAT_2_N _UxGT("Préchauff. ABS ")
#define MSG_PREHEAT_2_ALL _UxGT("Préch. ABS Tout")
#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" fini")
#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" buse")
#define MSG_PREHEAT_2_BEDONLY _UxGT("Préch. ABS lit")
#define MSG_PREHEAT_2_SETTINGS _UxGT("Régl. prech. ABS")
#define MSG_COOLDOWN _UxGT("Refroidir")
#define MSG_SWITCH_PS_ON _UxGT("Allumer alim.")
#define MSG_SWITCH_PS_OFF _UxGT("Eteindre alim.")
#define MSG_SWITCH_PS_OFF _UxGT("Éteindre alim.")
#define MSG_EXTRUDE _UxGT("Extrusion")
#define MSG_RETRACT _UxGT("Retrait")
#define MSG_MOVE_AXIS _UxGT("Déplacer un axe")
@@ -86,9 +87,9 @@
#define MSG_UBL_TOOLS _UxGT("Outils UBL")
#define MSG_UBL_LEVEL_BED _UxGT("Niveau lit unifié")
#define MSG_UBL_MANUAL_MESH _UxGT("Maillage manuel")
#define MSG_UBL_BC_INSERT _UxGT("Poser câle & mesurer")
#define MSG_UBL_BC_INSERT _UxGT("Poser cale & mesurer")
#define MSG_UBL_BC_INSERT2 _UxGT("Mesure")
#define MSG_UBL_BC_REMOVE _UxGT("ôter et mesurer lit")
#define MSG_UBL_BC_REMOVE _UxGT("Ôter et mesurer lit")
#define MSG_UBL_MOVING_TO_NEXT _UxGT("Aller au suivant")
#define MSG_UBL_ACTIVATE_MESH _UxGT("Activer l'UBL")
#define MSG_UBL_DEACTIVATE_MESH _UxGT("Désactiver l'UBL")
@@ -96,8 +97,8 @@
#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP
#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Température buse")
#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP
#define MSG_UBL_MESH_EDIT _UxGT("Editer maille")
#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Editer maille perso")
#define MSG_UBL_MESH_EDIT _UxGT("Éditer maille")
#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Éditer maille perso")
#define MSG_UBL_FINE_TUNE_MESH _UxGT("Réglage fin maille")
#define MSG_UBL_DONE_EDITING_MESH _UxGT("Terminer maille")
#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Créer maille perso")
@@ -155,7 +156,7 @@
#define MSG_SET_LEDS_INDIGO _UxGT("Indigo")
#define MSG_SET_LEDS_VIOLET _UxGT("Violet")
#define MSG_SET_LEDS_WHITE _UxGT("Blanc")
#define MSG_SET_LEDS_DEFAULT _UxGT("Defaut")
#define MSG_SET_LEDS_DEFAULT _UxGT("Défaut")
#define MSG_CUSTOM_LEDS _UxGT("Lum. perso.")
#define MSG_INTENSITY_R _UxGT("Intensité rouge")
#define MSG_INTENSITY_G _UxGT("Intensité vert")
+1 -1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Ir orixe X")
#define MSG_AUTO_HOME_Y _UxGT("Ir orixe Y")
#define MSG_AUTO_HOME_Z _UxGT("Ir orixe Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Ir orixes XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Prema pulsador")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Seguinte punto")
@@ -252,4 +253,3 @@
#endif // LCD_HEIGHT < 4
#endif // LANGUAGE_GL_H
+1
View File
@@ -44,6 +44,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home-aj X")
#define MSG_AUTO_HOME_Y _UxGT("Home-aj Y")
#define MSG_AUTO_HOME_Z _UxGT("Home-aj Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibriraj Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Home-aj XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Klikni za početak")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Sljedeća točka")
+1
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home asse X")
#define MSG_AUTO_HOME_Y _UxGT("Home asse Y")
#define MSG_AUTO_HOME_Z _UxGT("Home asse Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibra Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Home assi XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Premi per iniziare")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Punto successivo")
+1
View File
@@ -50,6 +50,7 @@
#define MSG_AUTO_HOME_X "X\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Xジク ゲンテンフッキ" ("Home X")
#define MSG_AUTO_HOME_Y "Y\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Yジク ゲンテンフッキ" ("Home Y")
#define MSG_AUTO_HOME_Z "Z\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Zジク ゲンテンフッキ" ("Home Z")
#define MSG_TMC_Z_CALIBRATION "Z\xbc\xde\xb8\x20\xba\xb3\xbe\xb2" // "Zジク コウセイ" ("Calibrate Z")
#define MSG_LEVEL_BED_HOMING "\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7\xc1\xad\xb3" // "ゲンテンフッキチュウ" ("Homing XYZ")
#define MSG_LEVEL_BED_WAITING "\xda\xcd\xde\xd8\xdd\xb8\xde\xb6\xb2\xbc" // "レベリングカイシ" ("Click to Begin")
#define MSG_LEVEL_BED_NEXT_POINT "\xc2\xb7\xde\xc9\xbf\xb8\xc3\xb2\xc3\xdd\xcd" // "ツギノソクテイテンヘ" ("Next Point")
+1
View File
@@ -53,6 +53,7 @@
#define MSG_AUTO_HOME_X _UxGT("Xジク ゲンテンフッキ") // "Home X"
#define MSG_AUTO_HOME_Y _UxGT("Yジク ゲンテンフッキ") // "Home Y"
#define MSG_AUTO_HOME_Z _UxGT("Zジク ゲンテンフッキ") // "Home Z"
#define MSG_TMC_Z_CALIBRATION _UxGT("Zジク コウセイ") // "Calibrate Z"
#define MSG_LEVEL_BED_HOMING _UxGT("ゲンテンフッキチュウ") // "Homing XYZ"
#define MSG_LEVEL_BED_WAITING _UxGT("レベリングカイシ") // "Click to Begin"
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("ツギノソクテイテンヘ") // "Next Point"
+1
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home X")
#define MSG_AUTO_HOME_Y _UxGT("Home Y")
#define MSG_AUTO_HOME_Z _UxGT("Home Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibreer Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Klik voor begin")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Volgende Plaats")
+1
View File
@@ -39,6 +39,7 @@
#define MSG_AUTO_HOME_X _UxGT("Zeruj X")
#define MSG_AUTO_HOME_Y _UxGT("Zeruj Y")
#define MSG_AUTO_HOME_Z _UxGT("Zeruj Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibruj Z")
#define MSG_LEVEL_BED _UxGT("Poziom. stołu")
#define MSG_LEVEL_BED_HOMING _UxGT("Pozycja zerowa")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknij by rozp.")
+1
View File
@@ -40,6 +40,7 @@
#define MSG_AUTO_HOME_X _UxGT("Zeruj X")
#define MSG_AUTO_HOME_Y _UxGT("Zeruj Y")
#define MSG_AUTO_HOME_Z _UxGT("Zeruj Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibruj Z")
#define MSG_LEVEL_BED _UxGT("Poziom. stolu")
#define MSG_LEVEL_BED_HOMING _UxGT("Pozycja zerowa")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknij by rozp.")
+1
View File
@@ -48,6 +48,7 @@
#define MSG_AUTO_HOME_Y _UxGT("Ir na origem Y")
#define MSG_AUTO_HOME_Z _UxGT("Ir na origem Z")
#define MSG_AUTO_HOME _UxGT("Ir na origem XYZ")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Indo para origem")
#define MSG_LEVEL_BED_WAITING _UxGT("Clique para Iniciar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Proximo Ponto")
+1
View File
@@ -50,6 +50,7 @@
#define MSG_AUTO_HOME_Y _UxGT("Ir na origem Y")
#define MSG_AUTO_HOME_Z _UxGT("Ir na origem Z")
#define MSG_AUTO_HOME _UxGT("Ir na origem XYZ")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Indo para origem")
#define MSG_LEVEL_BED_WAITING _UxGT("Clique para Iniciar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Próximo Ponto")
+1
View File
@@ -43,6 +43,7 @@
#define MSG_AUTO_HOME_X "Ir para origem X"
#define MSG_AUTO_HOME_Y "Ir para origem Y"
#define MSG_AUTO_HOME_Z "Ir para origem Z"
#define MSG_TMC_Z_CALIBRATION "Calibrar Z"
#define MSG_LEVEL_BED_HOMING "Indo para origem"
#define MSG_LEVEL_BED_WAITING "Click para iniciar"
#define MSG_LEVEL_BED_NEXT_POINT "Proximo ponto"
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Ir para origem X")
#define MSG_AUTO_HOME_Y _UxGT("Ir para origem Y")
#define MSG_AUTO_HOME_Z _UxGT("Ir para origem Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Indo para origem")
#define MSG_LEVEL_BED_WAITING _UxGT("Click para iniciar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Próximo ponto")
+1
View File
@@ -49,6 +49,7 @@
#define MSG_AUTO_HOME_X _UxGT("Парковка X")
#define MSG_AUTO_HOME_Y _UxGT("Парковка Y")
#define MSG_AUTO_HOME_Z _UxGT("Парковка Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Калибровать Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Нулевое положение")
#define MSG_LEVEL_BED_WAITING _UxGT("Нажмите чтобы начать")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Следующая точка")
+1
View File
@@ -53,6 +53,7 @@
#define MSG_AUTO_HOME_X _UxGT("Domov os X")
#define MSG_AUTO_HOME_Y _UxGT("Domov os Y")
#define MSG_AUTO_HOME_Z _UxGT("Domov os Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibrovať Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Meranie podložky")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknutím spusťte")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Ďalší bod")
+1
View File
@@ -52,6 +52,7 @@
#define MSG_AUTO_HOME_X _UxGT("X Sıfırla") // X Sıfırla
#define MSG_AUTO_HOME_Y _UxGT("Y Sıfırla") // Y Sıfırla
#define MSG_AUTO_HOME_Z _UxGT("Z Sıfırla") // Z Sıfırla
#define MSG_TMC_Z_CALIBRATION _UxGT("Ayarla Z") // Ayarla Z
#define MSG_LEVEL_BED_HOMING _UxGT("XYZ Sıfırlanıyor") // XYZ Sıfırlanıyor
#define MSG_LEVEL_BED_WAITING _UxGT("Başlatmak için tıkla") // Başlatmak için tıkla
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Sıradaki Nokta") // Sıradaki Nokta
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Паркування X")
#define MSG_AUTO_HOME_Y _UxGT("Паркування Y")
#define MSG_AUTO_HOME_Z _UxGT("Паркування Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Калібрування Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Паркування XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Почати")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Слідуюча Точка")
+1
View File
@@ -46,6 +46,7 @@
#define MSG_AUTO_HOME_X _UxGT("回X原位") //"Home X"
#define MSG_AUTO_HOME_Y _UxGT("回Y原位") //"Home Y"
#define MSG_AUTO_HOME_Z _UxGT("回Z原位") //"Home Z"
#define MSG_TMC_Z_CALIBRATION _UxGT("⊿校准Z") //"Calibrate Z"
#define MSG_LEVEL_BED_HOMING _UxGT("平台调平XYZ归原位") //"Homing XYZ"
#define MSG_LEVEL_BED_WAITING _UxGT("单击开始热床调平") //"Click to Begin"
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("下个热床调平点") //"Next Point"
+1
View File
@@ -46,6 +46,7 @@
#define MSG_AUTO_HOME_X _UxGT("回X原點") //"Home X"
#define MSG_AUTO_HOME_Y _UxGT("回Y原點") //"Home Y"
#define MSG_AUTO_HOME_Z _UxGT("回Z原點") //"Home Z"
#define MSG_TMC_Z_CALIBRATION _UxGT("⊿校準Z") //"Calibrate Z"
#define MSG_LEVEL_BED_HOMING _UxGT("平台調平XYZ歸原點") //"Homing XYZ"
#define MSG_LEVEL_BED_WAITING _UxGT("單擊開始熱床調平") //"Click to Begin"
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("下個熱床調平點") //"Next Point"
+11 -6
View File
@@ -23,13 +23,18 @@
#ifndef MACROS_H
#define MACROS_H
#define NUM_AXIS 4
#define ABCE 4
#define XYZE 4
#define ABC 3
#define XYZ 3
#define XYZ 3
#define XYZE 4
#define ABC 3
#define ABCD 4
#define ABCE 4
#define ABCDE 5
// For use in macros that take a single axis letter
/**
* For use in macros that take a single axis letter
* The axis order in all axis related arrays is X, Y, Z, E
* For Hangprinter it is A, B, C, D, E
*/
#define _AXIS(A) (A##_AXIS)
#define _XMIN_ 100
+5 -3
View File
@@ -161,9 +161,11 @@
#if ENABLED(NOZZLE_PARK_FEATURE)
void Nozzle::park(const uint8_t &z_action, const point_t &park /*= NOZZLE_PARK_POINT*/) {
const float fr_xy = NOZZLE_PARK_XY_FEEDRATE;
const float fr_z = NOZZLE_PARK_Z_FEEDRATE;
constexpr float npp[] = NOZZLE_PARK_POINT;
static_assert(COUNT(npp) == XYZ, "NOZZLE_PARK_POINT requires X, Y, and Z values.");
void Nozzle::park(const uint8_t &z_action, const point_t &park/*=NOZZLE_PARK_POINT*/) {
const float fr_xy = NOZZLE_PARK_XY_FEEDRATE, fr_z = NOZZLE_PARK_Z_FEEDRATE;
switch (z_action) {
case 1: // Go to Z-park height
+1 -1
View File
@@ -100,9 +100,9 @@ static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const
#endif
void pca9632_set_led_color(const LEDColor &color) {
Wire.begin();
if (!PCA_init) {
PCA_init = 1;
Wire.begin();
PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE1, PCA9632_MODE1_VALUE);
PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE2, PCA9632_MODE2_VALUE);
}
+59 -10
View File
@@ -696,6 +696,7 @@
// Dual X-carriage, Dual Y, Dual Z support
//
#define _D_PINS
#define _X2_PINS
#define _Y2_PINS
#define _Z2_PINS
@@ -703,16 +704,64 @@
#define __EPIN(p,q) E##p##_##q##_PIN
#define _EPIN(p,q) __EPIN(p,q)
// The HANGPRINTER A, B, C, D axes
#if ENABLED(HANGPRINTER)
#define A_ENABLE_PIN X_ENABLE_PIN
#define A_DIR_PIN X_DIR_PIN
#define A_STEP_PIN X_STEP_PIN
#define A_MS1_PIN X_MS1_PIN
#define B_ENABLE_PIN Y_ENABLE_PIN
#define B_DIR_PIN Y_DIR_PIN
#define B_STEP_PIN Y_STEP_PIN
#define B_MS1_PIN Y_MS1_PIN
#define C_ENABLE_PIN Z_ENABLE_PIN
#define C_DIR_PIN Z_DIR_PIN
#define C_STEP_PIN Z_STEP_PIN
#define C_MS1_PIN Z_MS1_PIN
#ifndef D_STEP_PIN
#define D_STEP_PIN _EPIN(E_STEPPERS, STEP)
#define D_DIR_PIN _EPIN(E_STEPPERS, DIR)
#define D_ENABLE_PIN _EPIN(E_STEPPERS, ENABLE)
#ifndef D_CS_PIN
#define D_CS_PIN _EPIN(E_STEPPERS, CS)
#endif
#ifndef D_MS1_PIN
#define D_MS1_PIN _EPIN(E_STEPPERS, MS1)
#endif
#if E_STEPPERS >= MAX_EXTRUDERS || !PIN_EXISTS(D_ENABLE)
#error "No E stepper plug left for D Axis!"
#endif
#endif
#undef _D_PINS
#define ___D_PINS D_STEP_PIN, D_DIR_PIN, D_ENABLE_PIN,
#ifdef D_CS_PIN
#define __D_PINS ___D_PINS D_CS_PIN,
#else
#define __D_PINS ___D_PINS
#endif
#ifdef D_MS1_PIN
#define _D_PINS __D_PINS D_MS1_PIN,
#else
#define _D_PINS __D_PINS
#endif
#define X2_E_INDEX INCREMENT(E_STEPPERS)
#else
#define X2_E_INDEX E_STEPPERS
#endif
// The X2 axis, if any, should be the next open extruder port
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(X_DUAL_STEPPER_DRIVERS)
#ifndef X2_STEP_PIN
#define X2_STEP_PIN _EPIN(E_STEPPERS, STEP)
#define X2_DIR_PIN _EPIN(E_STEPPERS, DIR)
#define X2_ENABLE_PIN _EPIN(E_STEPPERS, ENABLE)
#define X2_STEP_PIN _EPIN(X2_E_INDEX, STEP)
#define X2_DIR_PIN _EPIN(X2_E_INDEX, DIR)
#define X2_ENABLE_PIN _EPIN(X2_E_INDEX, ENABLE)
#ifndef X2_CS_PIN
#define X2_CS_PIN _EPIN(E_STEPPERS, CS)
#define X2_CS_PIN _EPIN(X2_E_INDEX, CS)
#endif
#if E_STEPPERS > 4 || !PIN_EXISTS(X2_ENABLE)
#if X2_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(X2_ENABLE)
#error "No E stepper plug left for X2!"
#endif
#endif
@@ -723,9 +772,9 @@
#else
#define _X2_PINS __X2_PINS
#endif
#define Y2_E_INDEX INCREMENT(E_STEPPERS)
#define Y2_E_INDEX INCREMENT(X2_E_INDEX)
#else
#define Y2_E_INDEX E_STEPPERS
#define Y2_E_INDEX X2_E_INDEX
#endif
// The Y2 axis, if any, should be the next open extruder port
@@ -737,7 +786,7 @@
#ifndef Y2_CS_PIN
#define Y2_CS_PIN _EPIN(Y2_E_INDEX, CS)
#endif
#if Y2_E_INDEX > 4 || !PIN_EXISTS(Y2_ENABLE)
#if Y2_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(Y2_ENABLE)
#error "No E stepper plug left for Y2!"
#endif
#endif
@@ -762,7 +811,7 @@
#ifndef Z2_CS_PIN
#define Z2_CS_PIN _EPIN(Z2_E_INDEX, CS)
#endif
#if Z2_E_INDEX > 4 || !PIN_EXISTS(Z2_ENABLE)
#if Z2_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(Z2_ENABLE)
#error "No E stepper plug left for Z2!"
#endif
#endif
@@ -782,7 +831,7 @@
PS_ON_PIN, HEATER_BED_PIN, FAN_PIN, FAN1_PIN, FAN2_PIN, CONTROLLER_FAN_PIN, \
_E0_PINS _E1_PINS _E2_PINS _E3_PINS _E4_PINS BED_PINS \
_H0_PINS _H1_PINS _H2_PINS _H3_PINS _H4_PINS \
_X2_PINS _Y2_PINS _Z2_PINS \
_D_PINS _X2_PINS _Y2_PINS _Z2_PINS \
}
#define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS))
+12
View File
@@ -443,6 +443,18 @@
#if PIN_EXISTS(FIL_RUNOUT)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT_PIN)
#endif
#if PIN_EXISTS(FIL_RUNOUT2)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT2_PIN)
#endif
#if PIN_EXISTS(FIL_RUNOUT3)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT3_PIN)
#endif
#if PIN_EXISTS(FIL_RUNOUT4)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT4_PIN)
#endif
#if PIN_EXISTS(FIL_RUNOUT5)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT5_PIN)
#endif
#if PIN_EXISTS(HEATER_0)
REPORT_NAME_DIGITAL(__LINE__, HEATER_0_PIN)
#endif
+2 -2
View File
@@ -153,7 +153,7 @@
* REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
*/
#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL)
#if ENABLED(ULTRA_LCD)
#define LCD_SDSS 28
#if ENABLED(ADC_KEYPAD)
#define SERVO0_PIN 27 // free for BLTouch/3D-Touch
@@ -193,7 +193,7 @@
#endif
#else
#define SERVO0_PIN 27
#endif // ULTRA_LCD && NEWPANEL
#endif
/**
* ====================================================================
+4 -1
View File
@@ -118,7 +118,10 @@
#ifndef FAN_PIN
#define FAN_PIN 8
#endif
#define FAN1_PIN 6
#ifndef FAN1_PIN
#define FAN1_PIN 6
#endif
//
// Misc. Functions
+1
View File
@@ -36,6 +36,7 @@
//
// MOSFET changes
//
#define RAMPS_D9_PIN 8 // FAN (by default)
#define RAMPS_D10_PIN 9 // EXTRUDER 1
#define MOSFET_D_PIN 12 // EXTRUDER 2 or FAN
+47 -2
View File
@@ -30,7 +30,52 @@
#define IS_RAMPS_EFB
#define FAN2_PIN 44
#define ORIG_E0_AUTO_FAN_PIN 44
// FAN0 / D9 - Typically used for the part fan on Anycubic Delta devices
#define FAN_PIN 9
// FAN1 / D7 - Typically unused, can be allocated as Case Fan
// FAN2 / D44 - Typical Extruder Fan on Anycubic Delta devices
#define FAN2_PIN 44
#define ORIG_E0_AUTO_FAN_PIN 44
#include "pins_RAMPS.h"
// TODO 1.4 boards do have an E1 stepper driver. However the pin definitions
// from pins_RAMPS.h are incorrect for this board. e.g., Pin 44 is the Extruder fan.
#undef E1_STEP_PIN
#undef E1_DIR_PIN
#undef E1_ENABLE_PIN
#undef E1_CS_PIN
//
// AnyCubic made the following changes to 1.1.0-RC8
// If these are appropriate for your LCD let us know.
//
#if 0 && ENABLED(ULTRA_LCD)
// LCD Display output pins
#if ENABLED(NEWPANEL) && ENABLED(PANEL_ONE)
#undef LCD_PINS_D6
#define LCD_PINS_D6 57
#endif
// LCD Display input pins
#if ENABLED(NEWPANEL)
#if ENABLED(VIKI2) || ENABLED(miniVIKI)
#undef DOGLCD_A0
#define DOGLCD_A0 23
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#undef BEEPER_PIN
#define BEEPER_PIN 33
#undef LCD_BACKLIGHT_PIN
#define LCD_BACKLIGHT_PIN 67
#endif
#elif ENABLED(MINIPANEL)
#undef BEEPER_PIN
#define BEEPER_PIN 33
#undef DOGLCD_A0
#define DOGLCD_A0 42
#endif
#endif // ULTRA_LCD
+1 -1
View File
@@ -43,7 +43,7 @@
//
// Servos
//
#define SERVO0_PIN 13 // UNTESTED
#define SERVO0_PIN 11
//
// Limit Switches
+249 -88
View File
@@ -100,13 +100,13 @@ volatile uint8_t Planner::block_buffer_head, // Index of the next block to be
uint16_t Planner::cleaning_buffer_counter; // A counter to disable queuing of blocks
uint8_t Planner::delay_before_delivering; // This counter delays delivery of blocks when queue becomes empty to allow the opportunity of merging blocks
uint32_t Planner::max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE
Planner::max_acceleration_steps_per_s2[XYZE_N], // (steps/s^2) Derived from mm_per_s2
Planner::min_segment_time_us; // (µs) M205 B
uint32_t Planner::max_acceleration_mm_per_s2[NUM_AXIS_N], // (mm/s^2) M201 XYZE
Planner::max_acceleration_steps_per_s2[NUM_AXIS_N], // (steps/s^2) Derived from mm_per_s2
Planner::min_segment_time_us; // (µs) M205 Q
float Planner::max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds
Planner::axis_steps_per_mm[XYZE_N], // (steps) M92 XYZE - Steps per millimeter
Planner::steps_to_mm[XYZE_N], // (mm) Millimeters per step
float Planner::max_feedrate_mm_s[NUM_AXIS_N], // (mm/s) M203 XYZE - Max speeds
Planner::axis_steps_per_mm[NUM_AXIS_N], // (steps) M92 XYZE - Steps per millimeter
Planner::steps_to_mm[NUM_AXIS_N], // (mm) Millimeters per step
Planner::min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
Planner::acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
Planner::retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
@@ -123,7 +123,14 @@ float Planner::max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds
#endif
#endif
#else
float Planner::max_jerk[XYZE]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
float Planner::max_jerk[NUM_AXIS]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
#endif
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
float Planner::k0[MOV_AXIS],
Planner::k1[MOV_AXIS],
Planner::k2[MOV_AXIS],
Planner::sqrtk1[MOV_AXIS];
#endif
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
@@ -206,7 +213,7 @@ float Planner::previous_speed[NUM_AXIS],
#endif
#if HAS_POSITION_FLOAT
float Planner::position_float[XYZE]; // Needed for accurate maths. Steps cannot be used!
float Planner::position_float[NUM_AXIS]; // Needed for accurate maths. Steps cannot be used!
#endif
#if ENABLED(ULTRA_LCD)
@@ -1137,7 +1144,13 @@ void Planner::recalculate() {
float high = 0.0;
for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
block_t* block = &block_buffer[b];
if (block->steps[X_AXIS] || block->steps[Y_AXIS] || block->steps[Z_AXIS]) {
if (
#if ENABLED(HANGPRINTER)
block->steps[A_AXIS] || block->steps[B_AXIS] || block->steps[C_AXIS] || block->steps[D_AXIS]
#else
block->steps[X_AXIS] || block->steps[Y_AXIS] || block->steps[Z_AXIS]
#endif
) {
const float se = (float)block->steps[E_AXIS] / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
NOLESS(high, se);
}
@@ -1514,6 +1527,9 @@ float Planner::get_axis_position_mm(const AxisEnum axis) {
#else
axis_steps = stepper.position(axis);
#endif
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
if (axis != E_AXIS) return (sq(axis_steps / k0[axis] + sqrtk1[axis]) - k1[axis]) / k2[axis];
#endif
return axis_steps * steps_to_mm[axis];
}
@@ -1522,23 +1538,34 @@ float Planner::get_axis_position_mm(const AxisEnum axis) {
*/
void Planner::synchronize() { while (has_blocks_queued() || cleaning_buffer_counter) idle(); }
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
#define COUNT_MOVE count_it
#else
#define COUNT_MOVE true
#endif
/**
* Planner::_buffer_steps
*
* Add a new linear movement to the planner queue (in terms of steps).
*
* target - target position in steps units
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* target - target position in steps units
* target_float - target position in mm (HAS_POSITION_FLOAT)
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - apply this move to the counters (UNREGISTERED_MOVE_SUPPORT)
*
* Returns true if movement was properly queued, false otherwise
*/
bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
bool Planner::_buffer_steps(const int32_t (&target)[NUM_AXIS]
#if HAS_POSITION_FLOAT
, const float (&target_float)[XYZE]
, const float (&target_float)[NUM_AXIS]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, const bool count_it/*=true*/
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters
) {
// If we are cleaning, do not accept queuing of movements
@@ -1554,6 +1581,9 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
, target_float
#endif
, fr_mm_s, extruder, millimeters
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, count_it
#endif
)) {
// Movement was not queued, probably because it was too short.
// Simply accept that as movement queued and done
@@ -1585,24 +1615,33 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
*
* Fills a new linear movement in the block (in terms of steps).
*
* target - target position in steps units
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* target - target position in steps units
* target_float - target position in mm (HAS_POSITION_FLOAT)
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - apply this move to the counters (UNREGISTERED_MOVE_SUPPORT)
*
* Returns true is movement is acceptable, false otherwise
*/
bool Planner::_populate_block(block_t * const block, bool split_move,
const int32_t (&target)[XYZE]
const int32_t (&target)[NUM_AXIS]
#if HAS_POSITION_FLOAT
, const float (&target_float)[XYZE]
, const float (&target_float)[NUM_AXIS]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, const bool count_it/*=true*/
#endif
) {
const int32_t da = target[A_AXIS] - position[A_AXIS],
db = target[B_AXIS] - position[B_AXIS],
dc = target[C_AXIS] - position[C_AXIS];
dc = target[C_AXIS] - position[C_AXIS]
#if ENABLED(HANGPRINTER)
, dd = target[D_AXIS] - position[D_AXIS]
#endif
;
int32_t de = target[E_AXIS] - position[E_AXIS];
/* <-- add a slash to enable
@@ -1622,10 +1661,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
if (de) {
#if ENABLED(PREVENT_COLD_EXTRUSION)
if (thermalManager.tooColdToExtrude(extruder)) {
position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = target_float[E_AXIS];
#endif
if (COUNT_MOVE) {
position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = target_float[E_AXIS];
#endif
}
de = 0; // no difference
SERIAL_ECHO_START();
SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP);
@@ -1633,10 +1674,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
#endif // PREVENT_COLD_EXTRUSION
#if ENABLED(PREVENT_LENGTHY_EXTRUDE)
if (ABS(de * e_factor[extruder]) > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int
position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = target_float[E_AXIS];
#endif
if (COUNT_MOVE) {
position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = target_float[E_AXIS];
#endif
}
de = 0; // no difference
SERIAL_ECHO_START();
SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP);
@@ -1665,6 +1708,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
if (dc < 0) SBI(dm, Z_HEAD); // ...and Z
if (db + dc < 0) SBI(dm, B_AXIS); // Motor B direction
if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction
#elif ENABLED(HANGPRINTER)
if (da < 0) SBI(dm, A_AXIS);
if (db < 0) SBI(dm, B_AXIS);
if (dc < 0) SBI(dm, C_AXIS);
if (dd < 0) SBI(dm, D_AXIS);
#else
if (da < 0) SBI(dm, X_AXIS);
if (db < 0) SBI(dm, Y_AXIS);
@@ -1681,6 +1729,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Set direction bits
block->direction_bits = dm;
// Specify if block is to be counted or not
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
block->count_it = count_it;
#endif
// Number of steps for each axis
// See http://www.corexy.com/theory.html
#if CORE_IS_XY
@@ -1699,6 +1752,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
block->steps[A_AXIS] = ABS(da);
block->steps[B_AXIS] = ABS(db);
block->steps[Z_AXIS] = ABS(dc);
#elif ENABLED(HANGPRINTER)
block->steps[A_AXIS] = ABS(da);
block->steps[B_AXIS] = ABS(db);
block->steps[C_AXIS] = ABS(dc);
block->steps[D_AXIS] = ABS(dd);
#else
// default non-h-bot planning
block->steps[A_AXIS] = ABS(da);
@@ -1707,7 +1765,14 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
#endif
block->steps[E_AXIS] = esteps;
block->step_event_count = MAX4(block->steps[A_AXIS], block->steps[B_AXIS], block->steps[C_AXIS], esteps);
block->step_event_count = (
#if ENABLED(HANGPRINTER)
MAX5(block->steps[A_AXIS], block->steps[B_AXIS], block->steps[C_AXIS], block->steps[D_AXIS], esteps)
#else
MAX4(block->steps[A_AXIS], block->steps[B_AXIS], block->steps[C_AXIS], esteps)
#endif
);
// Bail if this is a zero-length block
if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return false;
@@ -1715,13 +1780,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// For a mixing extruder, get a magnified esteps for each
#if ENABLED(MIXING_EXTRUDER)
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
block->mix_steps[i] = mixing_factor[i] * (
#if ENABLED(LIN_ADVANCE)
esteps
#else
block->step_event_count
#endif
);
block->mix_steps[i] = mixing_factor[i] * esteps;
#endif
#if FAN_COUNT > 0
@@ -1761,7 +1820,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
enable_Z();
}
if (block->steps[X_AXIS]) enable_X();
#else
#elif DISABLED(HANGPRINTER) // Hangprinters X, Y, Z, E0 axes should always be enabled anyways
if (block->steps[X_AXIS]) enable_X();
if (block->steps[Y_AXIS]) enable_Y();
#if DISABLED(Z_LATE_ENABLE)
@@ -1902,14 +1961,21 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
delta_mm[C_AXIS] = CORESIGN(db - dc) * steps_to_mm[C_AXIS];
#endif
#else
float delta_mm[ABCE];
float delta_mm[NUM_AXIS];
delta_mm[A_AXIS] = da * steps_to_mm[A_AXIS];
delta_mm[B_AXIS] = db * steps_to_mm[B_AXIS];
delta_mm[C_AXIS] = dc * steps_to_mm[C_AXIS];
#if ENABLED(HANGPRINTER)
delta_mm[D_AXIS] = dd * steps_to_mm[D_AXIS];
#endif
#endif
delta_mm[E_AXIS] = esteps_float * steps_to_mm[E_AXIS_N];
if (block->steps[A_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[B_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[C_AXIS] < MIN_STEPS_PER_SEGMENT) {
if (block->steps[A_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[B_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[C_AXIS] < MIN_STEPS_PER_SEGMENT
#if ENABLED(HANGPRINTER)
&& block->steps[D_AXIS] < MIN_STEPS_PER_SEGMENT
#endif
) {
block->millimeters = ABS(delta_mm[E_AXIS]);
}
else if (!millimeters) {
@@ -1920,6 +1986,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
sq(delta_mm[X_HEAD]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_HEAD])
#elif CORE_IS_YZ
sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_HEAD]) + sq(delta_mm[Z_HEAD])
#elif ENABLED(HANGPRINTER)
sq(delta_mm[A_AXIS]) + sq(delta_mm[B_AXIS]) + sq(delta_mm[C_AXIS]) + sq(delta_mm[D_AXIS])
#else
sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_AXIS])
#endif
@@ -2005,7 +2073,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Calculate and limit speed in mm/sec for each axis
float current_speed[NUM_AXIS], speed_factor = 1.0f; // factor <1 decreases speed
LOOP_XYZE(i) {
LOOP_NUM_AXIS(i) {
const float cs = ABS((current_speed[i] = delta_mm[i] * inverse_secs));
#if ENABLED(DISTINCT_E_FACTORS)
if (i == E_AXIS) i += extruder;
@@ -2053,7 +2121,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Correct the speed
if (speed_factor < 1.0f) {
LOOP_XYZE(i) current_speed[i] *= speed_factor;
LOOP_NUM_AXIS(i) current_speed[i] *= speed_factor;
block->nominal_rate *= speed_factor;
block->nominal_speed_sqr = block->nominal_speed_sqr * sq(speed_factor);
}
@@ -2061,7 +2129,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Compute and limit the acceleration rate for the trapezoid generator.
const float steps_per_mm = block->step_event_count * inverse_millimeters;
uint32_t accel;
if (!block->steps[A_AXIS] && !block->steps[B_AXIS] && !block->steps[C_AXIS]) {
if (!block->steps[A_AXIS] && !block->steps[B_AXIS] && !block->steps[C_AXIS]
#if ENABLED(HANGPRINTER)
&& !block->steps[D_AXIS]
#endif
) {
// convert to: acceleration steps/sec^2
accel = CEIL(retract_acceleration * steps_per_mm);
#if ENABLED(LIN_ADVANCE)
@@ -2148,12 +2220,18 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
LIMIT_ACCEL_LONG(A_AXIS, 0);
LIMIT_ACCEL_LONG(B_AXIS, 0);
LIMIT_ACCEL_LONG(C_AXIS, 0);
#if ENABLED(HANGPRINTER)
LIMIT_ACCEL_LONG(D_AXIS, 0);
#endif
LIMIT_ACCEL_LONG(E_AXIS, ACCEL_IDX);
}
else {
LIMIT_ACCEL_FLOAT(A_AXIS, 0);
LIMIT_ACCEL_FLOAT(B_AXIS, 0);
LIMIT_ACCEL_FLOAT(C_AXIS, 0);
#if ENABLED(HANGPRINTER)
LIMIT_ACCEL_FLOAT(D_AXIS, 0);
#endif
LIMIT_ACCEL_FLOAT(E_AXIS, ACCEL_IDX);
}
}
@@ -2279,27 +2357,27 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
/**
* Adapted from Průša MKS firmware
* https://github.com/prusa3d/Prusa-Firmware
*
* Start with a safe speed (from which the machine may halt to stop immediately).
*/
const float nominal_speed = SQRT(block->nominal_speed_sqr);
// Exit speed limited by a jerk to full halt of a previous last segment
static float previous_safe_speed;
const float nominal_speed = SQRT(block->nominal_speed_sqr);
// Start with a safe speed (from which the machine may halt to stop immediately).
float safe_speed = nominal_speed;
uint8_t limited = 0;
LOOP_XYZE(i) {
const float jerk = ABS(current_speed[i]), maxj = max_jerk[i];
if (jerk > maxj) {
if (limited) {
const float mjerk = maxj * nominal_speed;
if (jerk * safe_speed > mjerk) safe_speed = mjerk / jerk;
LOOP_NUM_AXIS(i) {
const float jerk = ABS(current_speed[i]), // cs : Starting from zero, change in speed for this axis
maxj = max_jerk[i]; // mj : The max jerk setting for this axis
if (jerk > maxj) { // cs > mj : New current speed too fast?
if (limited) { // limited already?
const float mjerk = nominal_speed * maxj; // ns*mj
if (jerk * safe_speed > mjerk) safe_speed = mjerk / jerk; // ns*mj/cs
}
else {
++limited;
safe_speed = maxj;
safe_speed *= maxj / jerk; // Initial limit: ns*mj/cs
++limited; // Initially limited
}
}
}
@@ -2321,7 +2399,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Now limit the jerk in all axes.
const float smaller_speed_factor = vmax_junction / previous_nominal_speed;
LOOP_XYZE(axis) {
LOOP_NUM_AXIS(axis) {
// Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop.
float v_exit = previous_speed[axis] * smaller_speed_factor,
v_entry = current_speed[axis];
@@ -2381,12 +2459,22 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
COPY(previous_speed, current_speed);
previous_nominal_speed_sqr = block->nominal_speed_sqr;
// Update the position
static_assert(COUNT(target) > 1, "Parameter to _buffer_steps must be (&target)[XYZE]!");
COPY(position, target);
#if HAS_POSITION_FLOAT
COPY(position_float, target_float);
#endif
// Update the position (only when a move was queued)
static_assert(COUNT(target) > 1, "Parameter to _populate_block must be (&target)["
#if ENABLED(HANGPRINTER)
"ABCD"
#else
"XYZ"
#endif
"E]!"
);
if (COUNT_MOVE) {
COPY(position, target);
#if HAS_POSITION_FLOAT
COPY(position_float, target_float);
#endif
}
// Movement was accepted
return true;
@@ -2409,6 +2497,9 @@ void Planner::buffer_sync_block() {
block->position[A_AXIS] = position[A_AXIS];
block->position[B_AXIS] = position[B_AXIS];
block->position[C_AXIS] = position[C_AXIS];
#if ENABLED(HANGPRINTER)
block->position[D_AXIS] = position[D_AXIS];
#endif
block->position[E_AXIS] = position[E_AXIS];
// If this is the first added movement, reload the delay, otherwise, cancel it.
@@ -2438,7 +2529,15 @@ void Planner::buffer_sync_block() {
* extruder - target extruder
* millimeters - the length of the movement, if known
*/
bool Planner::buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/) {
bool Planner::buffer_segment(const float &a, const float &b, const float &c
#if ENABLED(HANGPRINTER)
, const float &d
#endif
, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, bool count_it /* = true */
#endif
) {
// If we are cleaning, do not accept queuing of movements
if (cleaning_buffer_counter) return false;
@@ -2453,23 +2552,40 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
// The target position of the tool in absolute steps
// Calculate target position in absolute steps
const int32_t target[ABCE] = {
LROUND(a * axis_steps_per_mm[A_AXIS]),
LROUND(b * axis_steps_per_mm[B_AXIS]),
LROUND(c * axis_steps_per_mm[C_AXIS]),
const int32_t target[NUM_AXIS] = {
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
LROUND(k0[A_AXIS] * (SQRT(k1[A_AXIS] + a * k2[A_AXIS]) - sqrtk1[A_AXIS])),
LROUND(k0[B_AXIS] * (SQRT(k1[B_AXIS] + b * k2[B_AXIS]) - sqrtk1[B_AXIS])),
LROUND(k0[C_AXIS] * (SQRT(k1[C_AXIS] + c * k2[C_AXIS]) - sqrtk1[C_AXIS])),
LROUND(k0[D_AXIS] * (SQRT(k1[D_AXIS] + d * k2[D_AXIS]) - sqrtk1[D_AXIS])),
#else
LROUND(a * axis_steps_per_mm[A_AXIS]),
LROUND(b * axis_steps_per_mm[B_AXIS]),
LROUND(c * axis_steps_per_mm[C_AXIS]),
#if ENABLED(HANGPRINTER)
LROUND(d * axis_steps_per_mm[D_AXIS]),
#endif
#endif
LROUND(e * axis_steps_per_mm[E_AXIS_N])
};
#if HAS_POSITION_FLOAT
const float target_float[XYZE] = { a, b, c, e };
const float target_float[NUM_AXIS] = { a, b, c
#if ENABLED(HANGPRINTER)
, d
#endif
, e
};
#endif
// DRYRUN prevents E moves from taking place
if (DEBUGGING(DRYRUN)) {
position[E_AXIS] = target[E_AXIS];
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = e;
#endif
if (COUNT_MOVE) {
position[E_AXIS] = target[E_AXIS];
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = e;
#endif
}
}
/* <-- add a slash to enable
@@ -2487,13 +2603,18 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
#endif
SERIAL_ECHOPAIR(" (", position[Y_AXIS]);
SERIAL_ECHOPAIR("->", target[Y_AXIS]);
#if ENABLED(DELTA)
#if ENABLED(DELTA) || ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(") C:", c);
#else
SERIAL_ECHOPAIR(") Z:", c);
#endif
SERIAL_ECHOPAIR(" (", position[Z_AXIS]);
SERIAL_ECHOPAIR("->", target[Z_AXIS]);
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(") D:", d);
SERIAL_ECHOPAIR(" (", position[D_AXIS]);
SERIAL_ECHOPAIR("->", target[D_AXIS]);
#endif
SERIAL_ECHOPAIR(") E:", e);
SERIAL_ECHOPAIR(" (", position[E_AXIS]);
SERIAL_ECHOPAIR("->", target[E_AXIS]);
@@ -2501,12 +2622,15 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
//*/
// Queue the movement
if (
if (
!_buffer_steps(target
#if HAS_POSITION_FLOAT
, target_float
#endif
, fr_mm_s, extruder, millimeters
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, count_it
#endif
)
) return false;
@@ -2521,18 +2645,41 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
* On CORE machines stepper ABC will be translated from the given XYZ.
*/
void Planner::_set_position_mm(const float &a, const float &b, const float &c, const float &e) {
void Planner::_set_position_mm(const float &a, const float &b, const float &c
#if ENABLED(HANGPRINTER)
, const float &d
#endif
, const float &e
) {
#if ENABLED(DISTINCT_E_FACTORS)
last_extruder = active_extruder;
#endif
position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]),
position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]),
position[C_AXIS] = LROUND(c * axis_steps_per_mm[C_AXIS]),
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
position[A_AXIS] = LROUND(k0[A_AXIS] * (SQRT(k1[A_AXIS] + a * k2[A_AXIS]) - sqrtk1[A_AXIS])),
position[B_AXIS] = LROUND(k0[B_AXIS] * (SQRT(k1[B_AXIS] + b * k2[B_AXIS]) - sqrtk1[B_AXIS])),
position[C_AXIS] = LROUND(k0[C_AXIS] * (SQRT(k1[C_AXIS] + c * k2[C_AXIS]) - sqrtk1[C_AXIS])),
position[D_AXIS] = LROUND(k0[D_AXIS] * (SQRT(k1[D_AXIS] + d * k2[D_AXIS]) - sqrtk1[D_AXIS])),
#else
position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]);
position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]);
position[C_AXIS] = LROUND(axis_steps_per_mm[C_AXIS] * (c + (
#if !IS_KINEMATIC && ENABLED(AUTO_BED_LEVELING_UBL)
leveling_active ? ubl.get_z_correction(a, b) :
#endif
0)
));
#if ENABLED(HANGPRINTER)
position[D_AXIS] = LROUND(d * axis_steps_per_mm[D_AXIS]),
#endif
#endif
position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]);
#if HAS_POSITION_FLOAT
position_float[A_AXIS] = a;
position_float[B_AXIS] = b;
position_float[C_AXIS] = c;
#if ENABLED(HANGPRINTER)
position_float[D_AXIS] = d;
#endif
position_float[E_AXIS] = e;
#endif
if (has_blocks_queued()) {
@@ -2541,21 +2688,32 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c
buffer_sync_block();
}
else
stepper.set_position(position[A_AXIS], position[B_AXIS], position[C_AXIS], position[E_AXIS]);
stepper.set_position(position[A_AXIS], position[B_AXIS], position[C_AXIS],
#if ENABLED(HANGPRINTER)
position[D_AXIS],
#endif
position[E_AXIS]
);
}
void Planner::set_position_mm_kinematic(const float (&cart)[XYZE]) {
#if PLANNER_LEVELING
float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
apply_leveling(raw);
#elif ENABLED(HANGPRINTER)
float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
#else
const float (&raw)[XYZE] = cart;
#endif
#if IS_KINEMATIC
inverse_kinematics(raw);
_set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS]);
#if ENABLED(HANGPRINTER)
_set_position_mm(line_lengths[A_AXIS], line_lengths[B_AXIS], line_lengths[C_AXIS], line_lengths[D_AXIS], cart[E_CART]);
#else
_set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_CART]);
#endif
#else
_set_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS]);
_set_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_CART]);
#endif
}
@@ -2569,14 +2727,17 @@ void Planner::set_position_mm(const AxisEnum axis, const float &v) {
#else
const uint8_t axis_index = axis;
#endif
position[axis] = LROUND(v * axis_steps_per_mm[axis_index]);
position[axis] = LROUND(axis_steps_per_mm[axis_index] * (v + (
#if ENABLED(AUTO_BED_LEVELING_UBL)
axis == Z_AXIS && leveling_active ? ubl.get_z_correction(current_position[X_AXIS], current_position[Y_AXIS]) :
#endif
0)
));
#if HAS_POSITION_FLOAT
position_float[axis] = v;
#endif
if (has_blocks_queued()) {
//previous_speed[axis] = 0.0;
if (has_blocks_queued())
buffer_sync_block();
}
else
stepper.set_position(axis, position[axis]);
}
@@ -2589,7 +2750,7 @@ void Planner::reset_acceleration_rates() {
#define AXIS_CONDITION true
#endif
uint32_t highest_rate = 1;
LOOP_XYZE_N(i) {
LOOP_NUM_AXIS_N(i) {
max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i];
if (AXIS_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]);
}
@@ -2601,7 +2762,7 @@ void Planner::reset_acceleration_rates() {
// Recalculate position, steps_to_mm if axis_steps_per_mm changes!
void Planner::refresh_positioning() {
LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / axis_steps_per_mm[i];
LOOP_NUM_AXIS_N(i) steps_to_mm[i] = 1.0f / axis_steps_per_mm[i];
set_position_mm_kinematic(current_position);
reset_acceleration_rates();
}
+93 -20
View File
@@ -76,6 +76,10 @@ typedef struct {
volatile uint8_t flag; // Block flags (See BlockFlag enum above) - Modified by ISR and main thread!
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
bool count_it;
#endif
// Fields used by the motion planner to manage acceleration
float nominal_speed_sqr, // The nominal speed for this block in (mm/sec)^2
entry_speed_sqr, // Entry speed at previous-current junction in (mm/sec)^2
@@ -188,12 +192,12 @@ class Planner {
// May be auto-adjusted by a filament width sensor
#endif
static uint32_t max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE
max_acceleration_steps_per_s2[XYZE_N], // (steps/s^2) Derived from mm_per_s2
min_segment_time_us; // (µs) M205 B
static float max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds
axis_steps_per_mm[XYZE_N], // (steps) M92 XYZE - Steps per millimeter
steps_to_mm[XYZE_N], // (mm) Millimeters per step
static uint32_t max_acceleration_mm_per_s2[NUM_AXIS_N], // (mm/s^2) M201 XYZE
max_acceleration_steps_per_s2[NUM_AXIS_N], // (steps/s^2) Derived from mm_per_s2
min_segment_time_us; // (µs) M205 Q
static float max_feedrate_mm_s[NUM_AXIS_N], // (mm/s) M203 XYZE - Max speeds
axis_steps_per_mm[NUM_AXIS_N], // (steps) M92 XYZE - Steps per millimeter
steps_to_mm[NUM_AXIS_N], // (mm) Millimeters per step
min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
@@ -210,7 +214,19 @@ class Planner {
#endif
#endif
#else
static float max_jerk[XYZE]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
static float max_jerk[NUM_AXIS]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
#endif
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
/*
* Parameters for calculating target[]
* See buildup compensation theory:
* https://vitana.se/opr3d/tbear/2017.html#hangprinter_project_29
*/
static float k0[MOV_AXIS],
k1[MOV_AXIS],
k2[MOV_AXIS],
sqrtk1[MOV_AXIS];
#endif
#if HAS_LEVELING
@@ -230,7 +246,7 @@ class Planner {
#endif
#if HAS_POSITION_FLOAT
static float position_float[XYZE];
static float position_float[NUM_AXIS];
#endif
#if ENABLED(SKEW_CORRECTION)
@@ -429,11 +445,17 @@ class Planner {
#define ARG_X float rx
#define ARG_Y float ry
#define ARG_Z float rz
#if ENABLED(HANGPRINTER)
#define ARG_E1 float re1
#endif
static void unapply_leveling(float raw[XYZ]);
#else
#define ARG_X const float &rx
#define ARG_Y const float &ry
#define ARG_Z const float &rz
#if ENABLED(HANGPRINTER)
#define ARG_E1 const float &re1
#endif
#endif
// Number of moves currently in the planner including the busy block, if any
@@ -477,14 +499,18 @@ class Planner {
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - apply this move to the counters (UNREGISTERED_MOVE_SUPPORT)
*
* Returns true if movement was buffered, false otherwise
*/
static bool _buffer_steps(const int32_t (&target)[XYZE]
static bool _buffer_steps(const int32_t (&target)[NUM_AXIS]
#if HAS_POSITION_FLOAT
, const float (&target_float)[XYZE]
, const float (&target_float)[NUM_AXIS]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, const bool count_it=true
#endif
);
/**
@@ -496,15 +522,19 @@ class Planner {
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - apply this move to the counters (UNREGISTERED_MOVE_SUPPORT)
*
* Returns true is movement is acceptable, false otherwise
*/
static bool _populate_block(block_t * const block, bool split_move,
const int32_t (&target)[XYZE]
const int32_t (&target)[NUM_AXIS]
#if HAS_POSITION_FLOAT
, const float (&target_float)[XYZE]
, const float (&target_float)[NUM_AXIS]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, const bool count_it=true
#endif
);
/**
@@ -521,13 +551,28 @@ class Planner {
* Leveling and kinematics should be applied ahead of calling this.
*
* a,b,c,e - target positions in mm and/or degrees
* (a, b, c, d, e for Hangprinter)
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - remember this move in its counters (UNREGISTERED_MOVE_SUPPORT)
*/
static bool buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0);
static bool buffer_segment(const float &a, const float &b, const float &c,
#if ENABLED(HANGPRINTER)
const float &d,
#endif
const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, bool count_it=true
#endif
);
static void _set_position_mm(const float &a, const float &b, const float &c, const float &e);
static void _set_position_mm(const float &a, const float &b, const float &c,
#if ENABLED(HANGPRINTER)
const float &d,
#endif
const float &e
);
/**
* Add a new linear movement to the buffer.
@@ -538,15 +583,26 @@ class Planner {
* (Cartesians may also call buffer_line_kinematic.)
*
* rx,ry,rz,e - target position in mm or degrees
* (rx, ry, rz, re1 for Hangprinter)
* fr_mm_s - (target) speed of the move (mm/s)
* extruder - target extruder
* millimeters - the length of the movement, if known
*/
FORCE_INLINE static bool buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters = 0.0) {
FORCE_INLINE static bool buffer_line(ARG_X, ARG_Y, ARG_Z,
#if ENABLED(HANGPRINTER)
ARG_E1,
#endif
const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters = 0.0
) {
#if PLANNER_LEVELING && IS_CARTESIAN
apply_leveling(rx, ry, rz);
#endif
return buffer_segment(rx, ry, rz, e, fr_mm_s, extruder, millimeters);
return buffer_segment(rx, ry, rz,
#if ENABLED(HANGPRINTER)
re1,
#endif
e, fr_mm_s, extruder, millimeters
);
}
/**
@@ -568,9 +624,16 @@ class Planner {
#endif
#if IS_KINEMATIC
inverse_kinematics(raw);
return buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters);
return buffer_segment(
#if ENABLED(HANGPRINTER)
line_lengths[A_AXIS], line_lengths[B_AXIS], line_lengths[C_AXIS], line_lengths[D_AXIS]
#else
delta[A_AXIS], delta[B_AXIS], delta[C_AXIS]
#endif
, cart[E_CART], fr_mm_s, extruder, millimeters
);
#else
return buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters);
return buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_CART], fr_mm_s, extruder, millimeters);
#endif
}
@@ -583,11 +646,21 @@ class Planner {
*
* Clears previous speed values.
*/
FORCE_INLINE static void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) {
FORCE_INLINE static void set_position_mm(ARG_X, ARG_Y, ARG_Z,
#if ENABLED(HANGPRINTER)
ARG_E1,
#endif
const float &e
) {
#if PLANNER_LEVELING && IS_CARTESIAN
apply_leveling(rx, ry, rz);
#endif
_set_position_mm(rx, ry, rz, e);
_set_position_mm(rx, ry, rz,
#if ENABLED(HANGPRINTER)
re1,
#endif
e
);
}
static void set_position_mm_kinematic(const float (&cart)[XYZE]);
static void set_position_mm(const AxisEnum axis, const float &v);
+19 -19
View File
@@ -105,17 +105,17 @@ inline static float dist1(float x1, float y1, float x2, float y2) { return ABS(x
* the mitigation offered by MIN_STEP and the small computational
* power available on Arduino, I think it is not wise to implement it.
*/
void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS], const float offset[4], float fr_mm_s, uint8_t extruder) {
void cubic_b_spline(const float pos[XYZE], const float cart_target[XYZE], const float offset[4], float fr_mm_s, uint8_t extruder) {
// Absolute first and second control points are recovered.
const float first0 = position[X_AXIS] + offset[0],
first1 = position[Y_AXIS] + offset[1],
second0 = target[X_AXIS] + offset[2],
second1 = target[Y_AXIS] + offset[3];
const float first0 = pos[X_AXIS] + offset[0],
first1 = pos[Y_AXIS] + offset[1],
second0 = cart_target[X_AXIS] + offset[2],
second1 = cart_target[Y_AXIS] + offset[3];
float t = 0;
float bez_target[4];
bez_target[X_AXIS] = position[X_AXIS];
bez_target[Y_AXIS] = position[Y_AXIS];
float bez_target[XYZE];
bez_target[X_AXIS] = pos[X_AXIS];
bez_target[Y_AXIS] = pos[Y_AXIS];
float step = MAX_STEP;
millis_t next_idle_ms = millis() + 200UL;
@@ -134,13 +134,13 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
bool did_reduce = false;
float new_t = t + step;
NOMORE(new_t, 1);
float new_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], new_t),
new_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], new_t);
float new_pos0 = eval_bezier(pos[X_AXIS], first0, second0, cart_target[X_AXIS], new_t),
new_pos1 = eval_bezier(pos[Y_AXIS], first1, second1, cart_target[Y_AXIS], new_t);
for (;;) {
if (new_t - t < (MIN_STEP)) break;
const float candidate_t = 0.5f * (t + new_t),
candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t),
candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t),
candidate_pos0 = eval_bezier(pos[X_AXIS], first0, second0, cart_target[X_AXIS], candidate_t),
candidate_pos1 = eval_bezier(pos[Y_AXIS], first1, second1, cart_target[Y_AXIS], candidate_t),
interp_pos0 = 0.5f * (bez_target[X_AXIS] + new_pos0),
interp_pos1 = 0.5f * (bez_target[Y_AXIS] + new_pos1);
if (dist1(candidate_pos0, candidate_pos1, interp_pos0, interp_pos1) <= (SIGMA)) break;
@@ -155,8 +155,8 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
if (new_t - t > MAX_STEP) break;
const float candidate_t = t + 2 * (new_t - t);
if (candidate_t >= 1) break;
const float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t),
candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t),
const float candidate_pos0 = eval_bezier(pos[X_AXIS], first0, second0, cart_target[X_AXIS], candidate_t),
candidate_pos1 = eval_bezier(pos[Y_AXIS], first1, second1, cart_target[Y_AXIS], candidate_t),
interp_pos0 = 0.5f * (bez_target[X_AXIS] + candidate_pos0),
interp_pos1 = 0.5f * (bez_target[Y_AXIS] + candidate_pos1);
if (dist1(new_pos0, new_pos1, interp_pos0, interp_pos1) > (SIGMA)) break;
@@ -184,14 +184,14 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
bez_target[Y_AXIS] = new_pos1;
// FIXME. The following two are wrong, since the parameter t is
// not linear in the distance.
bez_target[Z_AXIS] = interp(position[Z_AXIS], target[Z_AXIS], t);
bez_target[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t);
bez_target[Z_AXIS] = interp(pos[Z_AXIS], cart_target[Z_AXIS], t);
bez_target[E_CART] = interp(pos[E_CART], cart_target[E_CART], t);
clamp_to_software_endstops(bez_target);
#if HAS_UBL_AND_CURVES
float pos[XYZ] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS] };
planner.apply_leveling(pos);
if (!planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], bez_target[E_AXIS], fr_mm_s, active_extruder))
float bez_copy[XYZ] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS] };
planner.apply_leveling(bez_copy);
if (!planner.buffer_segment(bez_copy[X_AXIS], bez_copy[Y_AXIS], bez_copy[Z_AXIS], bez_target[E_CART], fr_mm_s, active_extruder))
break;
#else
if (!planner.buffer_line_kinematic(bez_target, fr_mm_s, extruder))
+19 -7
View File
@@ -49,27 +49,39 @@ bool Power::is_power_needed() {
if (controllerFanSpeed > 0) return true;
#endif
// If any of the drivers or the bed are enabled...
if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON
#if HAS_HEATED_BED
|| thermalManager.soft_pwm_amount_bed > 0
#if HAS_HEATED_BED
|| thermalManager.soft_pwm_amount_bed > 0
#endif
#if HAS_X2_ENABLE
|| X2_ENABLE_READ == X_ENABLE_ON
#endif
|| E0_ENABLE_READ == E_ENABLE_ON // If any of the drivers are enabled...
#if HAS_Y2_ENABLE
|| Y2_ENABLE_READ == Y_ENABLE_ON
#endif
#if HAS_Z2_ENABLE
|| Z2_ENABLE_READ == Z_ENABLE_ON
#endif
|| E0_ENABLE_READ == E_ENABLE_ON
#if E_STEPPERS > 1
|| E1_ENABLE_READ == E_ENABLE_ON
#if HAS_X2_ENABLE
|| X2_ENABLE_READ == X_ENABLE_ON
#endif
#if E_STEPPERS > 2
|| E2_ENABLE_READ == E_ENABLE_ON
#if E_STEPPERS > 3
|| E3_ENABLE_READ == E_ENABLE_ON
#if E_STEPPERS > 4
|| E4_ENABLE_READ == E_ENABLE_ON
#endif
#endif
#endif
#endif
) return true;
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0) return true;
if (thermalManager.degTargetBed() > 0) return true;
#if HAS_HEATED_BED
if (thermalManager.degTargetBed() > 0) return true;
#endif
return false;
}
+1 -1
View File
@@ -159,7 +159,7 @@ void check_print_job_recovery() {
#endif
dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1);
dtostrf(job_recovery_info.current_position[E_AXIS]
dtostrf(job_recovery_info.current_position[E_CART]
#if ENABLED(SAVE_EACH_CMD_MODE)
- 5
#endif
+23 -15
View File
@@ -395,7 +395,7 @@ void ST7920_Lite_Status_Screen::draw_degree_symbol(uint8_t x, uint8_t y, bool dr
const uint8_t x_word = x >> 1;
const uint8_t y_top = degree_symbol_y_top;
const uint8_t y_bot = y_top + sizeof(degree_symbol)/sizeof(degree_symbol[0]);
for(uint8_t i = y_top; i < y_bot; i++) {
for (uint8_t i = y_top; i < y_bot; i++) {
uint8_t byte = pgm_read_byte_near(p_bytes++);
set_gdram_address(x_word,i+y*16);
begin_data();
@@ -876,24 +876,32 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) {
}
void ST7920_Lite_Status_Screen::update_progress(const bool forceUpdate) {
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
uint8_t progress_bar_percent;
#endif
#if ENABLED(LCD_SET_PROGRESS_MANUALLY) || ENABLED(SDSUPPORT)
// Set current percentage from SD when actively printing
#if ENABLED(SDSUPPORT)
if (IS_SD_PRINTING) progress_bar_percent = card.percentDone();
#endif
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
uint8_t progress_bar_percent; //=0
#endif
// Since the progress bar involves writing
// quite a few bytes to GDRAM, only do this
// when an update is actually necessary.
#if ENABLED(SDSUPPORT)
// Progress bar % comes from SD when actively printing
if (IS_SD_PRINTING) progress_bar_percent = card.percentDone();
#endif
static uint8_t last_progress = 0;
if (!forceUpdate && last_progress == progress_bar_percent) return;
last_progress = progress_bar_percent;
// Since the progress bar involves writing
// quite a few bytes to GDRAM, only do this
// when an update is actually necessary.
draw_progress_bar(progress_bar_percent);
static uint8_t last_progress = 0;
if (!forceUpdate && last_progress == progress_bar_percent) return;
last_progress = progress_bar_percent;
draw_progress_bar(progress_bar_percent);
#else
UNUSED(forceUpdate);
#endif // LCD_SET_PROGRESS_MANUALLY || SDSUPPORT
}
void ST7920_Lite_Status_Screen::update(const bool forceUpdate) {
+131 -53
View File
@@ -135,9 +135,8 @@ uint8_t Stepper::steps_per_isr;
#endif
uint8_t Stepper::oversampling_factor;
int32_t Stepper::delta_error[XYZE] = { 0 };
uint32_t Stepper::advance_dividend[XYZE] = { 0 },
int32_t Stepper::delta_error[NUM_AXIS] = { 0 };
uint32_t Stepper::advance_dividend[NUM_AXIS] = { 0 },
Stepper::advance_divisor = 0,
Stepper::step_events_completed = 0, // The number of step events executed in the current block
Stepper::accelerate_until, // The point from where we need to stop acceleration
@@ -180,14 +179,19 @@ uint32_t Stepper::nextMainISR = 0;
#endif // LIN_ADVANCE
int32_t Stepper::ticks_nominal = -1;
#if DISABLED(S_CURVE_ACCELERATION)
uint32_t Stepper::acc_step_rate; // needed for deceleration start point
#endif
volatile int32_t Stepper::endstops_trigsteps[XYZ];
volatile int32_t Stepper::count_position[NUM_AXIS] = { 0 };
int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 };
volatile int32_t Stepper::endstops_trigsteps[XYZ],
Stepper::count_position[NUM_AXIS] = { 0 };
int8_t Stepper::count_direction[NUM_AXIS] = {
1, 1, 1, 1
#if ENABLED(HANGPRINTER)
, 1
#endif
};
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#define DUAL_ENDSTOP_APPLY_STEP(A,V) \
@@ -260,6 +264,28 @@ int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 };
#define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v)
#endif
/**
* Hangprinter's mapping {A,B,C,D} <-> {X,Y,Z,E1} happens here.
* If you have two extruders: {A,B,C,D} <-> {X,Y,Z,E2}
* ... etc up to max 4 extruders.
* Place D connector on your first "free" extruder output.
*/
#if ENABLED(HANGPRINTER)
#define A_APPLY_DIR(v,Q) X_APPLY_DIR(v,Q)
#define A_APPLY_STEP(v,Q) X_APPLY_STEP(v,Q)
#define B_APPLY_DIR(v,Q) Y_APPLY_DIR(v,Q)
#define B_APPLY_STEP(v,Q) Y_APPLY_STEP(v,Q)
#define C_APPLY_DIR(v,Q) Z_APPLY_DIR(v,Q)
#define C_APPLY_STEP(v,Q) Z_APPLY_STEP(v,Q)
#define __D_APPLY(I,T,v) E##I##_##T##_WRITE(v)
#define _D_APPLY(I,T,v) __D_APPLY(I,T,v)
#define D_APPLY_DIR(v,Q) _D_APPLY(EXTRUDERS, DIR, v)
#define D_APPLY_STEP(v,Q) _D_APPLY(EXTRUDERS, STEP, v)
#endif
#if DISABLED(MIXING_EXTRUDER)
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(active_extruder, v)
#endif
@@ -357,6 +383,9 @@ void Stepper::set_directions() {
#if HAS_Z_DIR
SET_STEP_DIR(Z); // C
#endif
#if ENABLED(HANGPRINTER)
SET_STEP_DIR(D);
#endif
#if DISABLED(LIN_ADVANCE)
#if ENABLED(MIXING_EXTRUDER)
@@ -1251,6 +1280,12 @@ void Stepper::isr() {
* call to this method that might cause variation in the timing. The aim
* is to keep pulse timing as regular as possible.
*/
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
#define COUNT_IT current_block->count_it
#else
#define COUNT_IT true
#endif
void Stepper::stepper_pulse_phase_isr() {
// If we must abort the current block, do so!
@@ -1289,7 +1324,7 @@ void Stepper::stepper_pulse_phase_isr() {
delta_error[_AXIS(AXIS)] += advance_dividend[_AXIS(AXIS)]; \
if (delta_error[_AXIS(AXIS)] >= 0) { \
_APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), 0); \
count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \
if (COUNT_IT) count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \
} \
}while(0)
@@ -1302,22 +1337,37 @@ void Stepper::stepper_pulse_phase_isr() {
}while(0)
// Pulse start
#if HAS_X_STEP
PULSE_START(X);
#endif
#if HAS_Y_STEP
PULSE_START(Y);
#endif
#if HAS_Z_STEP
PULSE_START(Z);
#endif
#if ENABLED(HANGPRINTER)
#if HAS_A_STEP
PULSE_START(A);
#endif
#if HAS_B_STEP
PULSE_START(B);
#endif
#if HAS_C_STEP
PULSE_START(C);
#endif
#if HAS_D_STEP
PULSE_START(D);
#endif
#else
#if HAS_X_STEP
PULSE_START(X);
#endif
#if HAS_Y_STEP
PULSE_START(Y);
#endif
#if HAS_Z_STEP
PULSE_START(Z);
#endif
#endif // HANGPRINTER
// Pulse E/Mixing extruders
#if ENABLED(LIN_ADVANCE)
// Tick the E axis, correct error term and update position
delta_error[E_AXIS] += advance_dividend[E_AXIS];
if (delta_error[E_AXIS] >= 0) {
count_position[E_AXIS] += count_direction[E_AXIS];
if (COUNT_IT) count_position[E_AXIS] += count_direction[E_AXIS];
delta_error[E_AXIS] -= advance_divisor;
// Don't step E here - But remember the number of steps to perform
@@ -1329,7 +1379,7 @@ void Stepper::stepper_pulse_phase_isr() {
// Tick the E axis
delta_error[E_AXIS] += advance_dividend[E_AXIS];
if (delta_error[E_AXIS] >= 0) {
count_position[E_AXIS] += count_direction[E_AXIS];
if (COUNT_IT) count_position[E_AXIS] += count_direction[E_AXIS];
delta_error[E_AXIS] -= advance_divisor;
}
@@ -1354,15 +1404,29 @@ void Stepper::stepper_pulse_phase_isr() {
// Add the delay needed to ensure the maximum driver rate is enforced
if (signed(added_step_ticks) > 0) pulse_end += hal_timer_t(added_step_ticks);
// Pulse stop
#if HAS_X_STEP
PULSE_STOP(X);
#endif
#if HAS_Y_STEP
PULSE_STOP(Y);
#endif
#if HAS_Z_STEP
PULSE_STOP(Z);
#if ENABLED(HANGPRINTER)
#if HAS_A_STEP
PULSE_STOP(A);
#endif
#if HAS_B_STEP
PULSE_STOP(B);
#endif
#if HAS_C_STEP
PULSE_STOP(C);
#endif
#if HAS_D_STEP
PULSE_STOP(D);
#endif
#else
#if HAS_X_STEP
PULSE_STOP(X);
#endif
#if HAS_Y_STEP
PULSE_STOP(Y);
#endif
#if HAS_Z_STEP
PULSE_STOP(Z);
#endif
#endif
#if DISABLED(LIN_ADVANCE)
@@ -1437,16 +1501,10 @@ uint32_t Stepper::stepper_block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (LA_use_advance_lead) {
// Wake up eISR on first acceleration loop and fire ISR if final adv_rate is reached
if (step_events_completed == steps_per_isr || (LA_steps && LA_isr_rate != current_block->advance_speed)) {
nextAdvanceISR = 0;
LA_isr_rate = current_block->advance_speed;
}
}
else {
LA_isr_rate = LA_ADV_NEVER;
if (LA_steps) nextAdvanceISR = 0;
// Fire ISR if final adv_rate is reached
if (LA_steps && LA_isr_rate != current_block->advance_speed) nextAdvanceISR = 0;
}
else if (LA_steps) nextAdvanceISR = 0;
#endif // LIN_ADVANCE
}
// Are we in Deceleration phase ?
@@ -1488,17 +1546,13 @@ uint32_t Stepper::stepper_block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (LA_use_advance_lead) {
if (step_events_completed <= decelerate_after + steps_per_isr ||
(LA_steps && LA_isr_rate != current_block->advance_speed)
) {
nextAdvanceISR = 0; // Wake up eISR on first deceleration loop
// Wake up eISR on first deceleration loop and fire ISR if final adv_rate is reached
if (step_events_completed <= decelerate_after + steps_per_isr || (LA_steps && LA_isr_rate != current_block->advance_speed)) {
nextAdvanceISR = 0;
LA_isr_rate = current_block->advance_speed;
}
}
else {
LA_isr_rate = LA_ADV_NEVER;
if (LA_steps) nextAdvanceISR = 0;
}
else if (LA_steps) nextAdvanceISR = 0;
#endif // LIN_ADVANCE
}
// We must be in cruise phase otherwise
@@ -1531,8 +1585,11 @@ uint32_t Stepper::stepper_block_phase_isr() {
// Sync block? Sync the stepper counts and return
while (TEST(current_block->flag, BLOCK_BIT_SYNC_POSITION)) {
_set_position(
current_block->position[A_AXIS], current_block->position[B_AXIS],
current_block->position[C_AXIS], current_block->position[E_AXIS]
current_block->position[A_AXIS], current_block->position[B_AXIS], current_block->position[C_AXIS],
#if ENABLED(HANGPRINTER)
current_block->position[D_AXIS],
#endif
current_block->position[E_AXIS]
);
planner.discard_current_block();
@@ -1678,7 +1735,11 @@ uint32_t Stepper::stepper_block_phase_isr() {
if ((LA_use_advance_lead = current_block->use_advance_lead)) {
LA_final_adv_steps = current_block->final_adv_steps;
LA_max_adv_steps = current_block->max_adv_steps;
//Start the ISR
nextAdvanceISR = 0;
LA_isr_rate = current_block->advance_speed;
}
else LA_isr_rate = LA_ADV_NEVER;
#endif
if (current_block->direction_bits != last_direction_bits
@@ -2015,7 +2076,12 @@ void Stepper::init() {
* This allows get_axis_position_mm to correctly
* derive the current XYZ position later on.
*/
void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) {
void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c,
#if ENABLED(HANGPRINTER)
const int32_t &d,
#endif
const int32_t &e
) {
#if CORE_IS_XY
// corexy positioning
// these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html
@@ -2037,6 +2103,9 @@ void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c
count_position[X_AXIS] = a;
count_position[Y_AXIS] = b;
count_position[Z_AXIS] = c;
#if ENABLED(HANGPRINTER)
count_position[D_AXIS] = d;
#endif
#endif
count_position[E_AXIS] = e;
}
@@ -2103,31 +2172,38 @@ void Stepper::report_positions() {
const int32_t xpos = count_position[X_AXIS],
ypos = count_position[Y_AXIS],
#if ENABLED(HANGPRINTER)
dpos = count_position[D_AXIS],
#endif
zpos = count_position[Z_AXIS];
if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
#if CORE_IS_XY || CORE_IS_XZ || IS_DELTA || IS_SCARA
#if CORE_IS_XY || CORE_IS_XZ || IS_DELTA || IS_SCARA || ENABLED(HANGPRINTER)
SERIAL_PROTOCOLPGM(MSG_COUNT_A);
#else
SERIAL_PROTOCOLPGM(MSG_COUNT_X);
#endif
SERIAL_PROTOCOL(xpos);
#if CORE_IS_XY || CORE_IS_YZ || IS_DELTA || IS_SCARA
#if CORE_IS_XY || CORE_IS_YZ || IS_DELTA || IS_SCARA || ENABLED(HANGPRINTER)
SERIAL_PROTOCOLPGM(" B:");
#else
SERIAL_PROTOCOLPGM(" Y:");
#endif
SERIAL_PROTOCOL(ypos);
#if CORE_IS_XZ || CORE_IS_YZ || IS_DELTA
#if CORE_IS_XZ || CORE_IS_YZ || IS_DELTA || ENABLED(HANGPRINTER)
SERIAL_PROTOCOLPGM(" C:");
#else
SERIAL_PROTOCOLPGM(" Z:");
#endif
SERIAL_PROTOCOL(zpos);
#if ENABLED(HANGPRINTER)
SERIAL_PROTOCOLPAIR(" D:", dpos);
#endif
SERIAL_EOL();
}
@@ -2171,7 +2247,7 @@ void Stepper::report_positions() {
const uint8_t old_dir = _READ_DIR(AXIS); \
_ENABLE(AXIS); \
_APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^DIR^INVERT); \
DELAY_NS(400); /* DRV8825 */ \
DELAY_NS(MINIMUM_STEPPER_DIR_DELAY); \
_SAVE_START; \
_APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), true); \
_PULSE_WAIT; \
@@ -2243,7 +2319,9 @@ void Stepper::report_positions() {
Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction);
Z_DIR_WRITE(INVERT_Z_DIR ^ z_direction);
DELAY_NS(400); // DRV8825
#if MINIMUM_STEPPER_DIR_DELAY > 0
DELAY_NS(MINIMUM_STEPPER_DIR_DELAY);
#endif
_SAVE_START;
+23 -5
View File
@@ -270,8 +270,8 @@ class Stepper {
#endif
// Delta error variables for the Bresenham line tracer
static int32_t delta_error[XYZE];
static uint32_t advance_dividend[XYZE],
static int32_t delta_error[NUM_AXIS];
static uint32_t advance_dividend[NUM_AXIS],
advance_divisor,
step_events_completed, // The number of step events executed in the current block
accelerate_until, // The point from where we need to stop acceleration
@@ -425,11 +425,21 @@ class Stepper {
#endif
// Set the current position in steps
inline static void set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) {
inline static void set_position(const int32_t &a, const int32_t &b, const int32_t &c
#if ENABLED(HANGPRINTER)
, const int32_t &d
#endif
, const int32_t &e
) {
planner.synchronize();
const bool was_enabled = STEPPER_ISR_ENABLED();
if (was_enabled) DISABLE_STEPPER_DRIVER_INTERRUPT();
_set_position(a, b, c, e);
_set_position(a, b, c
#if ENABLED(HANGPRINTER)
, d
#endif
, e
);
if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
}
@@ -447,11 +457,19 @@ class Stepper {
private:
// Set the current position in steps
static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e);
static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c
#if ENABLED(HANGPRINTER)
, const int32_t &d
#endif
, const int32_t &e
);
// Set direction bits for all steppers
static void set_directions();
// Allow reset_stepper_drivers to access private set_directions
friend void reset_stepper_drivers();
FORCE_INLINE static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t scale, uint8_t* loops) {
uint32_t timer;
+59 -13
View File
@@ -35,6 +35,8 @@
#include "MarlinConfig.h"
#include "stepper.h"
//
// TMC26X Driver objects and inits
//
@@ -288,8 +290,7 @@
#endif
#define _TMC2208_DEFINE_HARDWARE(ST) TMC2208Stepper stepper##ST(&ST##_HARDWARE_SERIAL)
#define _TMC2208_DEFINE_SOFTWARE(ST) SoftwareSerial ST##_HARDWARE_SERIAL = SoftwareSerial(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN); \
TMC2208Stepper stepper##ST(&ST##_HARDWARE_SERIAL, ST##_SERIAL_RX_PIN > -1)
#define _TMC2208_DEFINE_SOFTWARE(ST) TMC2208Stepper stepper##ST(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN, ST##_SERIAL_RX_PIN > -1)
// Stepper objects of TMC2208 steppers used
#if AXIS_DRIVER_TYPE(X, TMC2208)
@@ -372,37 +373,81 @@
void tmc2208_serial_begin() {
#if AXIS_DRIVER_TYPE(X, TMC2208)
X_HARDWARE_SERIAL.begin(115200);
#ifdef X_HARDWARE_SERIAL
X_HARDWARE_SERIAL.begin(115200);
#else
stepperX.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(X2, TMC2208)
X2_HARDWARE_SERIAL.begin(115200);
#ifdef X2_HARDWARE_SERIAL
X2_HARDWARE_SERIAL.begin(115200);
#else
stepperX2.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(Y, TMC2208)
Y_HARDWARE_SERIAL.begin(115200);
#ifdef Y_HARDWARE_SERIAL
Y_HARDWARE_SERIAL.begin(115200);
#else
stepperY.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(Y2, TMC2208)
Y2_HARDWARE_SERIAL.begin(115200);
#ifdef Y2_HARDWARE_SERIAL
Y2_HARDWARE_SERIAL.begin(115200);
#else
stepperY2.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(Z, TMC2208)
Z_HARDWARE_SERIAL.begin(115200);
#ifdef Z_HARDWARE_SERIAL
Z_HARDWARE_SERIAL.begin(115200);
#else
stepperZ.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(Z2, TMC2208)
Z2_HARDWARE_SERIAL.begin(115200);
#ifdef Z2_HARDWARE_SERIAL
Z2_HARDWARE_SERIAL.begin(115200);
#else
stepperZ2.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(E0, TMC2208)
E0_HARDWARE_SERIAL.begin(115200);
#ifdef E0_HARDWARE_SERIAL
E0_HARDWARE_SERIAL.begin(115200);
#else
stepperE0.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(E1, TMC2208)
E1_HARDWARE_SERIAL.begin(115200);
#ifdef E1_HARDWARE_SERIAL
E1_HARDWARE_SERIAL.begin(115200);
#else
stepperE1.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(E2, TMC2208)
E2_HARDWARE_SERIAL.begin(115200);
#ifdef E2_HARDWARE_SERIAL
E2_HARDWARE_SERIAL.begin(115200);
#else
stepperE2.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(E3, TMC2208)
E3_HARDWARE_SERIAL.begin(115200);
#ifdef E3_HARDWARE_SERIAL
E3_HARDWARE_SERIAL.begin(115200);
#else
stepperE3.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(E4, TMC2208)
E4_HARDWARE_SERIAL.begin(115200);
#ifdef E4_HARDWARE_SERIAL
E4_HARDWARE_SERIAL.begin(115200);
#else
stepperE4.beginSerial(115200);
#endif
#endif
}
@@ -535,6 +580,7 @@ void reset_stepper_drivers() {
#if HAS_DRIVER(L6470)
L6470_init_to_defaults();
#endif
stepper.set_directions();
}
//
+13 -17
View File
@@ -1743,6 +1743,10 @@ void Temperature::set_current_temp_raw() {
}
#endif // PINS_DEBUGGING
#if ENABLED(FILAMENT_WIDTH_SENSOR)
uint32_t raw_filwidth_value; // = 0
#endif
void Temperature::readings_ready() {
// Update the raw values if they've been read. Else we could be updating them during reading.
if (!temp_meas_ready) set_current_temp_raw();
@@ -1786,14 +1790,12 @@ void Temperature::readings_ready() {
for (uint8_t e = 0; e < COUNT(temp_dir); e++) {
const int16_t tdir = temp_dir[e], rawtemp = current_temperature_raw[e] * tdir;
const bool heater_on = 0 <
const bool heater_on = (target_temperature[e] > 0)
#if ENABLED(PIDTEMP)
soft_pwm_amount[e]
#else
target_temperature[e]
|| (soft_pwm_amount[e] > 0)
#endif
;
if (rawtemp > maxttemp_raw[e] * tdir && heater_on) max_temp_error(e);
if (rawtemp > maxttemp_raw[e] * tdir) max_temp_error(e);
if (rawtemp < minttemp_raw[e] * tdir && !is_preheating(e) && heater_on) {
#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED)
@@ -1812,20 +1814,18 @@ void Temperature::readings_ready() {
#else
#define GEBED >=
#endif
const bool bed_on = 0 <
const bool bed_on = (target_temperature_bed > 0)
#if ENABLED(PIDTEMPBED)
soft_pwm_amount_bed
#else
target_temperature_bed
|| (soft_pwm_amount_bed > 0)
#endif
;
if (current_temperature_bed_raw GEBED bed_maxttemp_raw && bed_on) max_temp_error(-1);
if (current_temperature_bed_raw GEBED bed_maxttemp_raw) max_temp_error(-1);
if (bed_minttemp_raw GEBED current_temperature_bed_raw && bed_on) min_temp_error(-1);
#endif
}
/**
* Timer 0 is shared with millies so don't change the prescaler.
* Timer 0 is shared with millis so don't change the prescaler.
*
* This ISR uses the compare method so it runs at the base
* frequency (16 MHz / 64 / 256 = 976.5625 Hz), but at the TCNT0 set
@@ -1887,10 +1887,6 @@ void Temperature::isr() {
ISR_STATICS(BED);
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
static unsigned long raw_filwidth_value = 0;
#endif
#if DISABLED(SLOW_PWM_HEATERS)
constexpr uint8_t pwm_mask =
#if ENABLED(SOFT_PWM_DITHER)
@@ -2245,8 +2241,8 @@ void Temperature::isr() {
if (!HAL_ADC_READY())
next_sensor_state = adc_sensor_state; // redo this state
else if (HAL_READ_ADC() > 102) { // Make sure ADC is reading > 0.5 volts, otherwise don't read.
raw_filwidth_value -= (raw_filwidth_value >> 7); // Subtract 1/128th of the raw_filwidth_value
raw_filwidth_value += ((unsigned long)HAL_READ_ADC() << 7); // Add new ADC reading, scaled by 128
raw_filwidth_value -= raw_filwidth_value >> 7; // Subtract 1/128th of the raw_filwidth_value
raw_filwidth_value += uint32_t(HAL_READ_ADC()) << 7; // Add new ADC reading, scaled by 128
}
break;
#endif
+2 -2
View File
@@ -28,8 +28,8 @@ const short temptable_501[][2] PROGMEM = {
{OV( 19), 280},
{OV( 23), 270},
{OV( 27), 260},
{OV( 32), 250},
{OV( 30), 240},
{OV( 31), 250},
{OV( 37), 240},
{OV( 47), 230},
{OV( 57), 220},
{OV( 68), 210},
+2 -80
View File
@@ -28,78 +28,26 @@
// R2 = 4700 Ohm
const short temptable_71[][2] PROGMEM = {
{ OV( 35), 300 },
{ OV( 51), 270 },
{ OV( 54), 265 },
{ OV( 58), 260 },
{ OV( 51), 269 },
{ OV( 59), 258 },
{ OV( 61), 256 },
{ OV( 63), 254 },
{ OV( 64), 252 },
{ OV( 66), 250 },
{ OV( 67), 249 },
{ OV( 68), 248 },
{ OV( 69), 247 },
{ OV( 70), 246 },
{ OV( 71), 245 },
{ OV( 72), 244 },
{ OV( 73), 243 },
{ OV( 74), 242 },
{ OV( 75), 241 },
{ OV( 76), 240 },
{ OV( 77), 239 },
{ OV( 78), 238 },
{ OV( 79), 237 },
{ OV( 80), 236 },
{ OV( 71), 244 },
{ OV( 81), 235 },
{ OV( 82), 234 },
{ OV( 84), 233 },
{ OV( 85), 232 },
{ OV( 86), 231 },
{ OV( 87), 230 },
{ OV( 89), 229 },
{ OV( 90), 228 },
{ OV( 91), 227 },
{ OV( 92), 226 },
{ OV( 94), 225 },
{ OV( 95), 224 },
{ OV( 97), 223 },
{ OV( 98), 222 },
{ OV( 99), 221 },
{ OV( 101), 220 },
{ OV( 102), 219 },
{ OV( 104), 218 },
{ OV( 106), 217 },
{ OV( 107), 216 },
{ OV( 109), 215 },
{ OV( 110), 214 },
{ OV( 112), 213 },
{ OV( 114), 212 },
{ OV( 115), 211 },
{ OV( 117), 210 },
{ OV( 119), 209 },
{ OV( 121), 208 },
{ OV( 123), 207 },
{ OV( 125), 206 },
{ OV( 126), 205 },
{ OV( 128), 204 },
{ OV( 130), 203 },
{ OV( 132), 202 },
{ OV( 134), 201 },
{ OV( 136), 200 },
{ OV( 139), 199 },
{ OV( 141), 198 },
{ OV( 143), 197 },
{ OV( 145), 196 },
{ OV( 147), 195 },
{ OV( 150), 194 },
{ OV( 152), 193 },
{ OV( 154), 192 },
{ OV( 157), 191 },
{ OV( 159), 190 },
{ OV( 162), 189 },
{ OV( 164), 188 },
{ OV( 167), 187 },
{ OV( 170), 186 },
{ OV( 172), 185 },
{ OV( 175), 184 },
{ OV( 178), 183 },
@@ -113,9 +61,7 @@ const short temptable_71[][2] PROGMEM = {
{ OV( 202), 175 },
{ OV( 205), 174 },
{ OV( 208), 173 },
{ OV( 212), 172 },
{ OV( 215), 171 },
{ OV( 219), 170 },
{ OV( 237), 165 },
{ OV( 256), 160 },
{ OV( 300), 150 },
@@ -123,46 +69,22 @@ const short temptable_71[][2] PROGMEM = {
{ OV( 470), 120 },
{ OV( 504), 115 },
{ OV( 538), 110 },
{ OV( 552), 108 },
{ OV( 566), 106 },
{ OV( 580), 104 },
{ OV( 594), 102 },
{ OV( 608), 100 },
{ OV( 622), 98 },
{ OV( 636), 96 },
{ OV( 650), 94 },
{ OV( 664), 92 },
{ OV( 678), 90 },
{ OV( 712), 85 },
{ OV( 745), 80 },
{ OV( 758), 78 },
{ OV( 770), 76 },
{ OV( 783), 74 },
{ OV( 795), 72 },
{ OV( 806), 70 },
{ OV( 818), 68 },
{ OV( 829), 66 },
{ OV( 840), 64 },
{ OV( 850), 62 },
{ OV( 860), 60 },
{ OV( 870), 58 },
{ OV( 879), 56 },
{ OV( 888), 54 },
{ OV( 897), 52 },
{ OV( 905), 50 },
{ OV( 924), 45 },
{ OV( 940), 40 },
{ OV( 955), 35 },
{ OV( 967), 30 },
{ OV( 970), 29 },
{ OV( 972), 28 },
{ OV( 974), 27 },
{ OV( 976), 26 },
{ OV( 978), 25 },
{ OV( 980), 24 },
{ OV( 982), 23 },
{ OV( 984), 22 },
{ OV( 985), 21 },
{ OV( 987), 20 },
{ OV( 995), 15 },
{ OV(1001), 10 },
+3 -3
View File
@@ -55,7 +55,7 @@ void TWIBus::address(const uint8_t adr) {
#endif
}
void TWIBus::addbyte(const char c) {
void TWIBus::addbyte(const byte c) {
if (this->buffer_s >= COUNT(this->buffer)) return;
this->buffer[this->buffer_s++] = c;
#if ENABLED(DEBUG_TWIBUS)
@@ -63,7 +63,7 @@ void TWIBus::addbyte(const char c) {
#endif
}
void TWIBus::addbytes(char src[], uint8_t bytes) {
void TWIBus::addbytes(byte src[], uint8_t bytes) {
#if ENABLED(DEBUG_TWIBUS)
debug(PSTR("addbytes"), bytes);
#endif
@@ -138,7 +138,7 @@ void TWIBus::relay(const uint8_t bytes) {
echodata(bytes, PSTR("i2c-reply"), this->addr);
}
uint8_t TWIBus::capture(char *dst, const uint8_t bytes) {
uint8_t TWIBus::capture(byte *dst, const uint8_t bytes) {
this->reset();
uint8_t count = 0;
while (count < bytes && Wire.available())
+10 -3
View File
@@ -33,6 +33,13 @@
typedef void (*twiReceiveFunc_t)(int bytes);
typedef void (*twiRequestFunc_t)();
#if ENABLED(MECHADUINO_I2C_COMMANDS)
typedef union {
float fval;
byte bval[sizeof(float)];
} i2cFloat;
#endif
#define TWIBUS_BUFFER_SIZE 32
/**
@@ -99,7 +106,7 @@ class TWIBus {
*
* @param c a data byte
*/
void addbyte(const char c);
void addbyte(const byte c);
/**
* @brief Add some bytes to the buffer
@@ -109,7 +116,7 @@ class TWIBus {
* @param src source data address
* @param bytes the number of bytes to add
*/
void addbytes(char src[], uint8_t bytes);
void addbytes(byte src[], uint8_t bytes);
/**
* @brief Add a null-terminated string to the buffer
@@ -172,7 +179,7 @@ class TWIBus {
* @param bytes the number of bytes to request
* @return the number of bytes captured to the buffer
*/
uint8_t capture(char *dst, const uint8_t bytes);
uint8_t capture(byte *dst, const uint8_t bytes);
/**
* @brief Flush the i2c bus.
+2 -2
View File
@@ -76,7 +76,7 @@
// ignore the status of the g26_debug_flag
if (*title != '!' && !g26_debug_flag) return;
const float de = destination[E_AXIS] - current_position[E_AXIS];
const float de = destination[E_CART] - current_position[E_CART];
if (de == 0.0) return; // Printing moves only
@@ -97,7 +97,7 @@
SERIAL_ECHOPGM(", ");
SERIAL_ECHO_F(current_position[Z_AXIS], 6);
SERIAL_ECHOPGM(", ");
SERIAL_ECHO_F(current_position[E_AXIS], 6);
SERIAL_ECHO_F(current_position[E_CART], 6);
SERIAL_ECHOPGM(" ) destination=( ");
debug_echo_axis(X_AXIS);
SERIAL_ECHOPGM(", ");
+3 -3
View File
@@ -1559,12 +1559,12 @@
incremental_LSF(&lsf_results, PROBE_PT_3_X, PROBE_PT_3_Y, measured_z);
}
}
STOW_PROBE();
#ifdef Z_AFTER_PROBING
move_z_after_probing();
#endif
if (abort_flag) {
SERIAL_ECHOPGM("?Error probing point. Aborting operation.\n");
return;
@@ -1625,7 +1625,7 @@
#ifdef Z_AFTER_PROBING
move_z_after_probing();
#endif
if (abort_flag || finish_incremental_LSF(&lsf_results)) {
SERIAL_ECHOPGM("Could not complete LSF!");
return;
+25 -20
View File
@@ -46,8 +46,8 @@
*/
#if ENABLED(SKEW_CORRECTION)
// For skew correction just adjust the destination point and we're done
float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS] },
end[XYZE] = { destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS] };
float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_CART] },
end[XYZE] = { destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_CART] };
planner.skew(start[X_AXIS], start[Y_AXIS], start[Z_AXIS]);
planner.skew(end[X_AXIS], end[Y_AXIS], end[Z_AXIS]);
#else
@@ -64,7 +64,7 @@
SERIAL_ECHOPAIR(" ubl.line_to_destination_cartesian(xe=", destination[X_AXIS]);
SERIAL_ECHOPAIR(", ye=", destination[Y_AXIS]);
SERIAL_ECHOPAIR(", ze=", destination[Z_AXIS]);
SERIAL_ECHOPAIR(", ee=", destination[E_AXIS]);
SERIAL_ECHOPAIR(", ee=", destination[E_CART]);
SERIAL_CHAR(')');
SERIAL_EOL();
debug_current_and_destination(PSTR("Start of ubl.line_to_destination_cartesian()"));
@@ -85,7 +85,7 @@
+ UBL_Z_RAISE_WHEN_OFF_MESH
#endif
;
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z_raise, end[E_AXIS], feed_rate, extruder);
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z_raise, end[E_CART], feed_rate, extruder);
set_current_from_destination();
if (g26_debug_flag)
@@ -112,7 +112,7 @@
// Undefined parts of the Mesh in z_values[][] are NAN.
// Replace NAN corrections with 0.0 to prevent NAN propagation.
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + (isnan(z0) ? 0.0 : z0), end[E_AXIS], feed_rate, extruder);
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + (isnan(z0) ? 0.0 : z0), end[E_CART], feed_rate, extruder);
if (g26_debug_flag)
debug_current_and_destination(PSTR("FINAL_MOVE in ubl.line_to_destination_cartesian()"));
@@ -149,7 +149,7 @@
const bool use_x_dist = adx > ady;
float on_axis_distance = use_x_dist ? dx : dy,
e_position = end[E_AXIS] - start[E_AXIS],
e_position = end[E_CART] - start[E_CART],
z_position = end[Z_AXIS] - start[Z_AXIS];
const float e_normalized_dist = e_position / on_axis_distance,
@@ -198,11 +198,11 @@
if (ry != start[Y_AXIS]) {
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
e_position = start[E_CART] + on_axis_distance * e_normalized_dist;
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
else {
e_position = end[E_AXIS];
e_position = end[E_CART];
z_position = end[Z_AXIS];
}
@@ -249,11 +249,11 @@
if (rx != start[X_AXIS]) {
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move
e_position = start[E_CART] + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
else {
e_position = end[E_AXIS];
e_position = end[E_CART];
z_position = end[Z_AXIS];
}
@@ -308,11 +308,11 @@
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : next_mesh_line_y - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
e_position = start[E_CART] + on_axis_distance * e_normalized_dist;
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
else {
e_position = end[E_AXIS];
e_position = end[E_CART];
z_position = end[Z_AXIS];
}
if (!planner.buffer_segment(rx, next_mesh_line_y, z_position + z0, e_position, feed_rate, extruder))
@@ -331,11 +331,11 @@
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? next_mesh_line_x - start[X_AXIS] : ry - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
e_position = start[E_CART] + on_axis_distance * e_normalized_dist;
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
else {
e_position = end[E_AXIS];
e_position = end[E_CART];
z_position = end[Z_AXIS];
}
@@ -378,7 +378,12 @@
#if ENABLED(DELTA) // apply delta inverse_kinematics
DELTA_IK(raw);
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], fr, active_extruder);
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_CART], fr, active_extruder);
#elif ENABLED(HANGPRINTER) // apply hangprinter inverse_kinematics
HANGPRINTER_IK(raw);
planner.buffer_segment(line_lengths[A_AXIS], line_lengths[B_AXIS], line_lengths[C_AXIS], line_lengths[D_AXIS], in_raw[E_CART], fr, active_extruder);
#elif IS_SCARA // apply scara inverse_kinematics (should be changed to save raw->logical->raw)
@@ -391,11 +396,11 @@
scara_oldB = delta[B_AXIS];
float s_feedrate = MAX(adiff, bdiff) * scara_feed_factor;
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], s_feedrate, active_extruder);
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_CART], s_feedrate, active_extruder);
#else // CARTESIAN
planner.buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], in_raw[E_AXIS], fr, active_extruder);
planner.buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], in_raw[E_CART], fr, active_extruder);
#endif
}
@@ -427,7 +432,7 @@
rtarget[X_AXIS] - current_position[X_AXIS],
rtarget[Y_AXIS] - current_position[Y_AXIS],
rtarget[Z_AXIS] - current_position[Z_AXIS],
rtarget[E_AXIS] - current_position[E_AXIS]
rtarget[E_CART] - current_position[E_CART]
};
const float cartesian_xy_mm = HYPOT(total[X_AXIS], total[Y_AXIS]); // total horizontal xy distance
@@ -454,7 +459,7 @@
total[X_AXIS] * inv_segments,
total[Y_AXIS] * inv_segments,
total[Z_AXIS] * inv_segments,
total[E_AXIS] * inv_segments
total[E_CART] * inv_segments
};
// Note that E segment distance could vary slightly as z mesh height
@@ -464,7 +469,7 @@
current_position[X_AXIS],
current_position[Y_AXIS],
current_position[Z_AXIS],
current_position[E_AXIS]
current_position[E_CART]
};
// Only compute leveling per segment if ubl active and target below z_fade_height.
+17 -6
View File
@@ -874,7 +874,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
lcd_return_to_status();
// Turn leveling off and home
enqueue_and_echo_commands_P(PSTR("M420 S0\nG28"
enqueue_and_echo_commands_P(PSTR("M420 S0\nG28 R0"
#if ENABLED(MARLIN_DEV_MODE)
" S"
#elif !IS_KINEMATIC
@@ -1462,6 +1462,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
#endif
#endif
#endif // FAN_COUNT > 0
//
// Laser ON/OFF:
//
@@ -1469,6 +1470,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
MENU_ITEM(gcode, MSG_LASER_ON, PSTR(" M3 "));
MENU_ITEM(gcode, MSG_LASER_OFF, PSTR(" M5 "));
#endif
//
// Flow:
// Flow [1-5]:
@@ -2681,6 +2683,13 @@ void lcd_quick_feedback(const bool clear_buttons) {
MENU_ITEM(gcode, MSG_AUTO_HOME_Z, PSTR("G28 Z"));
#endif
//
// TMC Z Calibration
//
#if ENABLED(TMC_Z_CALIBRATION)
MENU_ITEM(gcode, MSG_TMC_Z_CALIBRATION, PSTR("G28\nM915"));
#endif
//
// Level Bed
//
@@ -3076,7 +3085,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
#if IS_KINEMATIC
manual_move_offset += diff;
#else
current_position[E_AXIS] += diff;
current_position[E_CART] += diff;
#endif
manual_move_to_current(E_AXIS
#if E_MANUAL > 1
@@ -3106,7 +3115,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
#endif // E_MANUAL > 2
}
#endif // E_MANUAL > 1
lcd_implementation_drawedit(pos_label, ftostr41sign(current_position[E_AXIS]
lcd_implementation_drawedit(pos_label, ftostr41sign(current_position[E_CART]
#if IS_KINEMATIC
+ manual_move_offset
#endif
@@ -3513,10 +3522,12 @@ void lcd_quick_feedback(const bool clear_buttons) {
#endif
#endif
#endif // FAN_COUNT > 0
#if ENABLED(FAN_AS_LASER)
MENU_ITEM(gcode, MSG_LASER_ON, PSTR("M3"));
MENU_ITEM(gcode, MSG_LASER_OFF, PSTR("M5"));
#if ENABLED(FAN_AS_LASER)
MENU_ITEM(gcode, MSG_LASER_ON, PSTR("M3"));
MENU_ITEM(gcode, MSG_LASER_OFF, PSTR("M5"));
#endif
//
// Autotemp, Min, Max, Fact
//
+3 -5
View File
@@ -356,10 +356,8 @@ static void lcd_implementation_init() {
OUT_WRITE(LCD_BACKLIGHT_PIN, HIGH);
#endif
#if ENABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306)
OUT_WRITE(LCD_PINS_RS, LOW);
_delay_ms(500);
OUT_WRITE(LCD_PINS_RS, HIGH);
#if !defined(LCD_RESET_PIN) && (ENABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306))
#define LCD_RESET_PIN LCD_PINS_RS
#endif
#if PIN_EXISTS(LCD_RESET)
@@ -369,7 +367,7 @@ static void lcd_implementation_init() {
_delay_ms(5); // delay to allow the display to initalize
#endif
#if PIN_EXISTS(LCD_RESET) || ENABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306)
#if PIN_EXISTS(LCD_RESET)
u8g.begin();
#endif