From d8e844bb67e2d80a65d7fe4eda235e9ee558eeee Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Thu, 23 Sep 2010 13:34:02 +0200 Subject: [PATCH 1/8] Allow compilation without any acceleration again. --- machine.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/machine.h b/machine.h index 1bcec16..720406c 100644 --- a/machine.h +++ b/machine.h @@ -41,9 +41,7 @@ Each movement starts at the speed of the previous command and accelerates or decelerates linearly to reach target speed at the end of the movement. Can also be set in Makefile */ -#ifndef ACCELERATION_RAMPING #define ACCELERATION_REPRAP -#endif /* acceleration and deceleration ramping. From 696baea16a944660bbbee46d63435b4e54a072ef Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Fri, 24 Sep 2010 16:02:50 +0200 Subject: [PATCH 2/8] Implement better machine speed limits checking. Do it for each axis individually, as the combined speed of two or more axes can be higher than the limit of a single one. While this is tested to work well for all three acceleration types, I'm not enthusiastic about the code, as it adds almost 500 bytes. Perhaps an efficient-coding-geek can help :-) --- dda.c | 30 +++++++++++++++++++++++++++--- gcode.c | 8 -------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/dda.c b/dda.c index 24b465b..a4557cb 100644 --- a/dda.c +++ b/dda.c @@ -106,7 +106,7 @@ const uint8_t msbloc (uint32_t v) { */ void dda_create(DDA *dda, TARGET *target) { - uint32_t distance; + uint32_t distance, c_limit, c_limit_calc; // initialise DDA to a known state dda->allflags = 0; @@ -199,16 +199,37 @@ void dda_create(DDA *dda, TARGET *target) { // distance * 2400 .. * F_CPU / 40000 so we can move a distance of up to 1800mm without overflowing uint32_t move_duration = ((distance * 2400) / dda->total_steps) * (F_CPU / 40000); + // similarly, find out how fast we can run our axes. + // do this for each axis individually, as the combined speed of two or more axes can be higher than the capabilities of a single one. + c_limit = 0; + c_limit_calc = ((dda->x_delta * UM_PER_STEP_X * 2400) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_X) << 8; + if (c_limit_calc > c_limit) + c_limit = c_limit_calc; + c_limit_calc = ((dda->y_delta * UM_PER_STEP_Y * 2400) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_Y) << 8; + if (c_limit_calc > c_limit) + c_limit = c_limit_calc; + c_limit_calc = ((dda->z_delta * UM_PER_STEP_Z * 2400) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_Z) << 8; + if (c_limit_calc > c_limit) + c_limit = c_limit_calc; + c_limit_calc = ((dda->e_delta * UM_PER_STEP_E * 2400) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_E) << 8; + if (c_limit_calc > c_limit) + c_limit = c_limit_calc; + #ifdef ACCELERATION_REPRAP // c is initial step time in IOclk ticks dda->c = (move_duration / startpoint.F) << 8; + if (dda->c < c_limit) + dda->c = c_limit; + dda->end_c = (move_duration / target->F) << 8; + if (dda->end_c < c_limit) + dda->end_c = c_limit; if (debug_flags & DEBUG_DDA) { serial_writestr_P(PSTR(",md:")); serwrite_uint32(move_duration); serial_writestr_P(PSTR(",c:")); serwrite_uint32(dda->c >> 8); } - if (startpoint.F != target->F) { + if (dda->c != dda->end_c) { uint32_t stF = startpoint.F / 4; uint32_t enF = target->F / 4; // now some constant acceleration stuff, courtesy of http://www.embedded.com/columns/technicalinsights/56800129?printable=true @@ -219,7 +240,6 @@ void dda_create(DDA *dda, TARGET *target) { uint8_t msb_ssq = msbloc(ssq); uint8_t msb_tot = msbloc(dda->total_steps); - dda->end_c = (move_duration / target->F) << 8; // the raw equation WILL overflow at high step rates, but 64 bit math routines take waay too much space // at 65536 mm/min (1092mm/s), ssq/esq overflows, and dsq is also close to overflowing if esq/ssq is small // but if ssq-esq is small, ssq/dsq is only a few bits @@ -257,10 +277,14 @@ void dda_create(DDA *dda, TARGET *target) { // c is initial step time in IOclk ticks dda->c = ACCELERATION_STEEPNESS << 8; dda->c_min = (move_duration / target->F) << 8; + if (dda->c_min < c_limit) + dda->c_min = c_limit; dda->n = 1; dda->ramp_state = RAMP_UP; #else dda->c = (move_duration / target->F) << 8; + if (dda->c < c_limit) + dda->c = c_limit; #endif } diff --git a/gcode.c b/gcode.c index 7e3b4ea..4f07078 100644 --- a/gcode.c +++ b/gcode.c @@ -393,14 +393,6 @@ void process_gcode_command(GCODE_COMMAND *gcmd) { // G1 - synchronised motion case 1: - // check speeds here - if (gcmd->seen_Z) { - if (gcmd->target.F > MAXIMUM_FEEDRATE_Z) - gcmd->target.F = MAXIMUM_FEEDRATE_Z; - } - else if (gcmd->target.F > MAXIMUM_FEEDRATE_X) - gcmd->target.F = MAXIMUM_FEEDRATE_X; - enqueue(&gcmd->target); break; From 4679b45ac80699104ff466c31f5485c193d938a8 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Fri, 24 Sep 2010 20:08:08 +0200 Subject: [PATCH 3/8] Send lowercase ok on init as well. --- mendel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mendel.c b/mendel.c index 600074a..0ccf7f9 100644 --- a/mendel.c +++ b/mendel.c @@ -108,7 +108,7 @@ void init(void) { wd_reset(); // say hi to host - serial_writestr_P(PSTR("Start\nOK\n")); + serial_writestr_P(PSTR("Start\nok\n")); } From 64683e6b6a9df5bdbe6897c31641b7b1011b9dc8 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Sat, 25 Sep 2010 12:02:57 +0200 Subject: [PATCH 4/8] Remove timer reset, as this doesn't play well. See http://github.com/triffid/FiveD_on_Arduino/issues#issue/2/comment/428863 . --- timer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/timer.c b/timer.c index 6cafbcf..b04be2a 100644 --- a/timer.c +++ b/timer.c @@ -104,7 +104,6 @@ void setTimer(uint32_t delay) // the result is the timer counts up to the appropriate time and then fires an interrupt. setTimerResolution(0); // stop timer - TCNT1 = 0; // reset timer GTCCR = MASK(PSRSYNC); // reset prescaler - affects timer 0 too but since it's doing PWM, it's not using the prescaler setTimerCeiling(getTimerCeiling(delay)); // set timeout From f5258ef9fc70be51b11d1e3b06f649a63adcbe36 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Fri, 24 Sep 2010 20:41:31 +0200 Subject: [PATCH 5/8] Assume a G1 by default. This is expected by some GCode generators. --- gcode.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gcode.c b/gcode.c index 4f07078..46bc019 100644 --- a/gcode.c +++ b/gcode.c @@ -341,13 +341,16 @@ void scan_char(uint8_t c) { // reset variables next_target.seen_X = next_target.seen_Y = next_target.seen_Z = \ - next_target.seen_E = next_target.seen_F = next_target.seen_G = \ - next_target.seen_S = next_target.seen_P = next_target.seen_N = \ - next_target.seen_M = next_target.seen_checksum = \ - next_target.seen_semi_comment = next_target.seen_parens_comment = \ - next_target.checksum_read = next_target.checksum_calculated = 0; + next_target.seen_E = next_target.seen_F = next_target.seen_S = \ + next_target.seen_P = next_target.seen_N = next_target.seen_M = \ + next_target.seen_checksum = next_target.seen_semi_comment = \ + next_target.seen_parens_comment = next_target.checksum_read = \ + next_target.checksum_calculated = 0; last_field = 0; read_digit.sign = read_digit.mantissa = read_digit.exponent = 0; + // assume a G1 by default + next_target.seen_G = 1; + next_target.G = 1; } } From 903baad3d102d75f5f1cb2d6bae44a065a28e124 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Sat, 25 Sep 2010 15:56:52 +0200 Subject: [PATCH 6/8] As we assume a G1 by default now, there's no longer a point in writing "huh?". Included question marks for debugging instead. --- gcode.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/gcode.c b/gcode.c index 46bc019..1126120 100644 --- a/gcode.c +++ b/gcode.c @@ -271,6 +271,14 @@ void scan_char(uint8_t c) { if (read_digit.exponent == 0) read_digit.exponent = 1; break; + #ifdef DEBUG + case ' ': + case '\t': + case 10: + case 13; + // ignore + break; + #endif default: // can't do ranges in switch..case, so process actual digits here @@ -280,7 +288,14 @@ void scan_char(uint8_t c) { if (read_digit.exponent) read_digit.exponent++; } - // everything else is ignored + #ifdef DEBUG + else { + // invalid + serial_writechar('?'); + serial_writechar(c); + serial_writechar('?'); + } + #endif } } else if ( next_target.seen_parens_comment == 1 && c == ')') next_target.seen_parens_comment = 0; // recognize stuff after a (comment) @@ -311,15 +326,8 @@ void scan_char(uint8_t c) { #endif ) { // process - if (next_target.seen_G || next_target.seen_M) { - process_gcode_command(&next_target); - - serial_writestr_P(PSTR("ok\n")); - } - else { - // write "OK" for invalid/unknown commands as well - serial_writestr_P(PSTR("ok huh?\n")); - } + process_gcode_command(&next_target); + serial_writestr_P(PSTR("ok\n")); // expect next line number if (next_target.seen_N == 1) From f6f2b7f44f41850977319ab5c2fdf397217885f0 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Sat, 25 Sep 2010 17:58:15 +0200 Subject: [PATCH 7/8] Enhance ACCELERATION_RAMPING on short moves. Problem was: For short moves, you have to ramp down before reaching target speed. The point of return was set to half of the number of total steps. Now, what happens is there's an uneven number of steps? In integer math, 3 / 2 = 1, so the move would ramp one step up, one step down and ... well, one step even further down, resulting in a really sloooow step. Slow, like a full second or so. Adding one to the first half, the movement ramps two steps up, one down and would do another step at minimum speed, if it wasn't already at target position. This is about as accurate as we can get it without introducing more code at interrupt time. --- dda.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dda.c b/dda.c index a4557cb..5b7ef8c 100644 --- a/dda.c +++ b/dda.c @@ -272,7 +272,8 @@ void dda_create(DDA *dda, TARGET *target) { else dda->accel = 0; #elif defined ACCELERATION_RAMPING - dda->ramp_steps = dda->total_steps / 2; + // add the last bit of dda->total_steps to always round up + dda->ramp_steps = dda->total_steps / 2 + (dda->total_steps & 1); dda->step_no = 0; // c is initial step time in IOclk ticks dda->c = ACCELERATION_STEEPNESS << 8; From ba84d1de609c3420163dc24196a2a70d397c519f Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Sun, 26 Sep 2010 01:39:13 +0200 Subject: [PATCH 8/8] Fix a typo. --- gcode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcode.c b/gcode.c index 1126120..23cefee 100644 --- a/gcode.c +++ b/gcode.c @@ -275,7 +275,7 @@ void scan_char(uint8_t c) { case ' ': case '\t': case 10: - case 13; + case 13: // ignore break; #endif