From 9739382da951bb80981a1c37d72ee3438025a710 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Fri, 6 Dec 2013 01:11:59 +0100 Subject: [PATCH] dda.c: remember steps per m of the fast axis for rampup calculation. For now this is for the initial rampup calculation, only, notably for moving the Z axis (which else gets far to few rampup steps on a typical mendel-like printer). The used macro was verified with this test code (in mendel.c): [...] int main (void) { init(); uint32_t speed, spm; char string[128]; for (spm = 2000; spm < 4099000; spm <<= 1) { for (speed = 11; speed < 65536; speed *= 8) { sersendf_P(PSTR("spm = %lu speed %lu ==> macro %lu "), spm, speed, ACCELERATE_RAMP_LEN_SPM(speed, spm)); delay_ms(10); sprintf(string, "double %f\n", (double)speed * (double)speed / ((double)7200000 * (double)ACCELERATION / (double)spm)); serial_writestr((uint8_t *)string); delay_ms(10); } } [...] Note: to link the test code, this linker flag is required to add the full printf library (which does print doubles): LDFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm --- dda.c | 7 ++++++- dda.h | 1 + dda_maths.h | 8 +++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/dda.c b/dda.c index fa66d21..e946c95 100644 --- a/dda.c +++ b/dda.c @@ -187,17 +187,21 @@ void dda_create(DDA *dda, TARGET *target) { dda->total_steps = dda->x_delta; dda->fast_um = x_delta_um; + dda->fast_spm = STEPS_PER_M_X; if (dda->y_delta > dda->total_steps) { dda->total_steps = dda->y_delta; dda->fast_um = y_delta_um; + dda->fast_spm = STEPS_PER_M_Y; } if (dda->z_delta > dda->total_steps) { dda->total_steps = dda->z_delta; dda->fast_um = z_delta_um; + dda->fast_spm = STEPS_PER_M_Z; } if (dda->e_delta > dda->total_steps) { dda->total_steps = dda->e_delta; dda->fast_um = e_delta_um; + dda->fast_spm = STEPS_PER_M_E; } if (DEBUG_DDA && (debug_flags & DEBUG_DDA)) @@ -356,7 +360,8 @@ void dda_create(DDA *dda, TARGET *target) { // Acceleration ramps are based on the fast axis, not the combined speed. dda->rampup_steps = - ACCELERATE_RAMP_LEN(muldiv(dda->fast_um, dda->endpoint.F, distance)); + ACCELERATE_RAMP_LEN_SPM(muldiv(dda->fast_um, dda->endpoint.F, distance), + dda->fast_spm); if (dda->rampup_steps > dda->total_steps / 2) dda->rampup_steps = dda->total_steps / 2; diff --git a/dda.h b/dda.h index cc35eb7..9ea0620 100644 --- a/dda.h +++ b/dda.h @@ -128,6 +128,7 @@ typedef struct { uint32_t total_steps; ///< steps of the "fast" axis uint32_t fast_um; ///< movement length of this fast axis + uint32_t fast_spm; ///< steps per meter of the fast axis uint32_t c; ///< time until next step, 24.8 fixed point diff --git a/dda_maths.h b/dda_maths.h index 14ea1cd..192ccd1 100644 --- a/dda_maths.h +++ b/dda_maths.h @@ -68,7 +68,13 @@ const uint8_t msbloc (uint32_t v); // s = 1/2 * a * t^2, v = a * t ==> s = v^2 / (2 * a) // 7200000 = 60 * 60 * 1000 * 2 (mm/min -> mm/s, steps/m -> steps/mm, factor 2) -// Note: the floating point bit is optimized away during compilation. +// Note: this macro has shown to be accurate between 10 and 10'000 mm/s2 and +// 2000 to 4096000 steps/m (and higher). The numbers are a few percent +// too high at very low acceleration. Test code see commit message. +#define ACCELERATE_RAMP_LEN_SPM(speed, spm) \ + (((speed) * (speed)) / \ + (uint32_t)((7200000UL * ACCELERATION) / (spm))) +// For X axis only, should become obsolete: #define ACCELERATE_RAMP_LEN(speed) (((speed)*(speed)) / (uint32_t)((7200000.0f * ACCELERATION) / (float)STEPS_PER_M_X)) // Initialization constant for the ramping algorithm.