From be274a561c805b40b2ee9154cb30349a82f007cf Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Thu, 31 Mar 2016 16:47:56 +0200 Subject: [PATCH 1/2] Integrate G2/G3 support from Tkkrlab. ZIP file found here: https://tkkrlab.nl/wiki/Cnc_machine#Firmware --- dda.c | 11 ++ dda.h | 6 +- debug.h | 2 + gcode_parse.c | 24 +++- gcode_parse.h | 4 + gcode_process.c | 74 ++++++++++- home.c | 12 ++ home.h | 1 + motion_control.c | 328 +++++++++++++++++++++++++++++++++++++++++++++++ motion_control.h | 31 +++++ pinio.h | 14 ++ 11 files changed, 502 insertions(+), 5 deletions(-) create mode 100644 motion_control.c create mode 100644 motion_control.h diff --git a/dda.c b/dda.c index 8fdc78095..ad0e24e92 100644 --- a/dda.c +++ b/dda.c @@ -830,6 +830,17 @@ void dda_clock() { } #endif + #if defined RESUME_PIN + if (dda->endstop_check & 0x8) { + if (e_min() == dda->endstop_stop_cond) + move_state.debounce_count_e++; + else + move_state.debounce_count_e = 0; + + endstop_stop = move_state.debounce_count_e >= ENDSTOP_STEPS; + } + #endif + // If an endstop is definitely triggered, stop the movement. if (endstop_trigger) { #ifdef ACCELERATION_RAMPING diff --git a/dda.h b/dda.h index a1a45db56..42003ad08 100644 --- a/dda.h +++ b/dda.h @@ -69,6 +69,7 @@ typedef struct { /// Endstop handling. uint8_t endstop_stop; ///< Stop due to endstop trigger uint8_t debounce_count_x, debounce_count_y, debounce_count_z; + uint8_t debounce_count_e; } MOVE_STATE; /** @@ -160,7 +161,7 @@ typedef struct { uint8_t fast_axis; ///< number of the fast axis /// Endstop homing - uint8_t endstop_check; ///< Do we need to check endstops? 0x1=Check X, 0x2=Check Y, 0x4=Check Z + uint8_t endstop_check; ///< Do we need to check endstops? 0x1=Check X, 0x2=Check Y, 0x4=Check Z, 0x8=Check E uint8_t endstop_stop_cond; ///< Endstop condition on which to stop motion: 0=Stop on detrigger, 1=Stop on trigger } DDA; @@ -202,4 +203,7 @@ void dda_clock(void); // update current_position void update_current_position(void); +//integer square root algorithm +uint16_t int_sqrt(uint32_t a); + #endif /* _DDA_H */ diff --git a/debug.h b/debug.h index f0cd481cf..b5ba571b0 100644 --- a/debug.h +++ b/debug.h @@ -24,6 +24,7 @@ #define DEBUG_PID 16 #define DEBUG_DDA 32 #define DEBUG_POSITION 64 + #define DEBUG_ARC 128 #else // by setting these to zero, the compiler should optimise the relevant code out #define DEBUG_PID 0 @@ -32,6 +33,7 @@ #define DEBUG_ECHO 0 #define DEBUG_INFO 0 #define DEBUG_DRYRUN 0 + #define DEBUG_ARC 0 #endif diff --git a/gcode_parse.c b/gcode_parse.c index 56c38e2fd..6c9663f07 100644 --- a/gcode_parse.c +++ b/gcode_parse.c @@ -165,6 +165,22 @@ uint8_t gcode_parse_char(uint8_t c) { if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) serwrite_uint8(next_target.M); break; + case 'I': + if (next_target.option_inches) + next_target.I = decfloat_to_int(&read_digit, 25400); + else + next_target.I = decfloat_to_int(&read_digit, 1000); + if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) + serwrite_int32(next_target.I); + break; + case 'J': + if (next_target.option_inches) + next_target.J = decfloat_to_int(&read_digit, 25400); + else + next_target.J = decfloat_to_int(&read_digit, 1000); + if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) + serwrite_int32(next_target.J); + break; case 'X': if (next_target.option_inches) next_target.target.axis[X] = decfloat_to_int(&read_digit, 25400); @@ -282,6 +298,12 @@ uint8_t gcode_parse_char(uint8_t c) { next_target.seen_G = 0; next_target.G = 0; break; + case 'I': + next_target.seen_I = 1; + break; + case 'J': + next_target.seen_J = 1; + break; case 'X': next_target.seen_X = 1; break; @@ -340,7 +362,6 @@ uint8_t gcode_parse_char(uint8_t c) { // ignore break; #endif - default: #ifdef DEBUG // invalid @@ -406,6 +427,7 @@ uint8_t gcode_parse_char(uint8_t c) { } // reset variables + next_target.seen_I = next_target.seen_J = \ next_target.seen_X = next_target.seen_Y = next_target.seen_Z = \ next_target.seen_E = next_target.seen_F = next_target.seen_S = \ next_target.seen_P = next_target.seen_T = next_target.seen_N = \ diff --git a/gcode_parse.h b/gcode_parse.h index 84c48202f..f66326f5f 100644 --- a/gcode_parse.h +++ b/gcode_parse.h @@ -31,6 +31,8 @@ typedef struct { uint8_t seen_Y :1; uint8_t seen_Z :1; uint8_t seen_E :1; + uint8_t seen_I :1; ///< ARC center X at startpoint +I. + uint8_t seen_J :1; ///< ARC center Y at startpoint +I. uint8_t seen_F :1; uint8_t seen_S :1; uint8_t seen_P :1; @@ -54,6 +56,8 @@ typedef struct { uint8_t G; ///< G command number uint8_t M; ///< M command number TARGET target; ///< target position: X, Y, Z, E and F + int32_t I; ///< In micrometers unless explicitely stated. + int32_t J; ///< In micrometers unless explicitely stated. uint8_t T; ///< T word (tool index) diff --git a/gcode_process.c b/gcode_process.c index 778c8e51f..7fe864238 100644 --- a/gcode_process.c +++ b/gcode_process.c @@ -5,12 +5,14 @@ */ #include +#include // For ARC hypot function. #include "gcode_parse.h" #include "cpu.h" #include "dda.h" #include "dda_queue.h" +#include "dda_maths.h" #include "watchdog.h" #include "delay.h" #include "serial.h" @@ -24,6 +26,7 @@ #include "clock.h" #include "config_wrapper.h" #include "home.h" +#include "motion_control.h" #include "sd.h" @@ -130,7 +133,51 @@ void process_gcode_command() { // G3 - Arc Counter-clockwise // unimplemented - + case 2: + case 3: + //? --- G2: Arc Clockwise --- + //? --- G3: Arc Counter-clockwise --- + //? + //? Example: G02 X47.4 Y13.3 I-21.6 J12.4 + //? + //? Go in an Arc with center (X-21.6, Y+12.4) from the current (X, Y) point to the point (47.4, 13.3) + //?; + { + uint8_t clockwise = 0; + // if we didn't see an I or J word, set it to zero. This is for Incremental Arc Distance Mode (G91.1 the default and currently only supported mode) + if (next_target.seen_I == 0){ //ARC support + next_target.I = 0; + if (next_target.seen_J == 0){ + //both are 0, this is an error for G2/3 because radius is 0. + //we generate an error message and just do a linear motion to the target point + sersendf_P(PSTR("E: missing offsets in G-code %d"), next_target.G); + enqueue(&next_target.target); + break; + } + } + if (next_target.seen_J == 0) + next_target.J = 0; + if (next_target.G==2) clockwise=1; + //for radius_mode implementation see file gcode.c in gbrl sourcecode + //for now only offset implementation + + //calculate radius + //the integer variant will be off by 8% or so for a radius of 250mm but the radius is + //only used to calculate the number of segments the arc is to be drawn in so this + //good enough for our use. + + uint32_t r = approx_distance(labs(next_target.I),labs(next_target.J)); +// float r = hypot(next_target.I/1000.0,next_target.J/1000.0); + +// serial_writestr_P(PSTR("\n\rArc Radius: (float,int) ")); +// serwrite_uint32(hypot(next_target.I/1000.0,next_target.J/1000.0)*1000.0); +// serial_writestr_P(PSTR(", ")); +// serwrite_uint32(r); + + // Trace the arc + mc_arc(r, clockwise); //motion_control.h + } + break; case 4: //? --- G4: Dwell --- //? @@ -370,7 +417,27 @@ void process_gcode_command() { //? --- M6: tool change --- //? //? Undocumented. - tool = next_tool; + tool = next_tool; //tom: seems the var tool is never used + sersendf_P(PSTR("next tool: T%u"),tool); + //tom 04-08-2014: after a tool change we need to wait until the user presses + //the resume button: + //? --- M6: Pause machine until RESUME button pressed --- + // Fake Home E command to pause machine until RESUME_PIN=low + // This can for example be used to change tools manually + // in PCB_Gcode there is an option "Do toolchange with zero step" which calls m6 2 times: + // - go to X0, Y0, Z 35 (X,Y & Z options in PCB-Gcode) + // - M6 Tx (x is the next tool) then we wait until the resume switch is pressed (user has time to change the tool) + // - G01 Z0.0000 F75.00 this moves the head back to Z0, make sure the tool is high up in the spindle and + // make sure that if you have tools of different length the longest one is not lower then the one that started our drilling + // Todo: use other switches to manualy adjust the Z height (or maybe other software commands) + // -M6 second time, we are at Z0 and the user can lower the tool onto the surface so it is at the actual Z0 again. + // Press the resume button to resume drilling after this. +// queue_wait(); + #if defined RESUME_PIN //the resume pin is in config.h and could be the same as Z-Min since the tool should be in High (Z++) now + home_e_negative(); + #endif + + break; #ifdef SD @@ -562,12 +629,13 @@ void process_gcode_command() { //? //? Example: M111 S6 //? - //? Set the level of debugging information transmitted back to the host to level 6. The level is the OR of three bits: + //? Set the level of debugging information transmitted back to the host to level 6. The level is the OR of four bits: //? //?
 				//? #define         DEBUG_PID       1
 				//? #define         DEBUG_DDA       2
 				//? #define         DEBUG_POSITION  4
+				//? #define         DEBUG_ARC		8
 				//? 
//? //? This command is only available in DEBUG builds of Teacup. diff --git a/home.c b/home.c index 0c3e36576..a51d2566e 100644 --- a/home.c +++ b/home.c @@ -67,6 +67,18 @@ void home() { home_z_positive(); } +/// find E MIN endstop (Fake, just waits for RESUME_PIN to get low) +void home_e_negative() { + #if defined RESUME_PIN + TARGET t = startpoint; + +// t.X = -1000000; //no change in t.x, we stay in same position as we wait for RESUME_PIN + enqueue_home(&t, 0x8, 1); + +// queue_wait(); // we have to wait here, see G92 + #endif +} + /// find X MIN endstop void home_x_negative() { #if defined X_MIN_PIN diff --git a/home.h b/home.h index 1c572abc9..38215fc1d 100644 --- a/home.h +++ b/home.h @@ -3,6 +3,7 @@ void home(void); +void home_e_negative(void); void home_x_negative(void); void home_x_positive(void); void home_y_negative(void); diff --git a/motion_control.c b/motion_control.c new file mode 100644 index 000000000..8a0d84f61 --- /dev/null +++ b/motion_control.c @@ -0,0 +1,328 @@ +/* + motion_control.c - high level interface for issuing motion commands + Part of Grbl + + Copyright (c) 2009-2011 Simen Svale Skogsrud + Copyright (c) 2011 Sungeun K. Jeon + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grbl. If not, see . +*/ + +//#include "Marlin.h" +//#include "stepper.h" +//#include "planner.h" +#include +#include +#include +#include + +#include "dda.h" +#include "dda_queue.h" +#include "dda_maths.h" +#include "gcode_parse.h" +#include "serial.h" //for debugging +#include "sermsg.h" //for debugging +#include "debug.h" //for debugging + +void prt_int(int32_t number) +{ + if (number/1000==0 && number<0) serial_writestr_P(PSTR("-")); + serwrite_int32(number/1000); + serial_writestr_P(PSTR(".")); + uint16_t rem=abs(number%1000); + if (rem<100) serial_writestr_P(PSTR("0")); + if (rem<10) serial_writestr_P(PSTR("0")); + serwrite_int32(abs(number%1000)); +} + + +// The arc is approximated by generating a huge number of tiny, linear segments. The length of each +// segment is configured in settings.mm_per_arc_segment. +//void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8_t axis_1, +// uint8_t axis_linear, float feed_rate, float radius, uint8_t isclockwise, uint8_t extruder) +//void mc_arc(float radius, uint8_t isclockwise) +void mc_arc(uint32_t radius, uint8_t isclockwise) +{ + if (DEBUG_ARC && (debug_flags & DEBUG_ARC)){ + serial_writestr_P(PSTR("\n\rArc Radius: ")); + prt_int(radius); + serial_writestr_P(PSTR(" start X,Y,Z: ")); + prt_int(startpoint.axis[X]); + serial_writestr_P(PSTR(", ")); + prt_int(startpoint.axis[Y]); + serial_writestr_P(PSTR(", ")); + prt_int(startpoint.axis[Z]); + serial_writestr_P(PSTR(" end X,Y,Z: ")); + prt_int(next_target.target.axis[X]); + serial_writestr_P(PSTR(", ")); + prt_int(next_target.target.axis[Y]); + serial_writestr_P(PSTR(", ")); + prt_int(next_target.target.axis[Z]); + serial_writestr_P(PSTR(" offset I,J: ")); + prt_int(next_target.I); + serial_writestr_P(PSTR(", ")); + prt_int(next_target.J); + serial_writestr_P(PSTR("\n\r")); + } + int32_t center_axis0 = startpoint.axis[X] + next_target.I; //center x + int32_t center_axis1 = startpoint.axis[Y] + next_target.J; //center y + int32_t linear_travel = next_target.target.axis[Z] - startpoint.axis[Z]; //helical + int32_t extruder_travel = next_target.target.axis[E] - startpoint.axis[E]; //extruder +/* + int32_t r_axis0 = -next_target.I; // Radius vector from center to current location + int32_t r_axis1 = -next_target.J; + int32_t rt_axis0 = next_target.target.axis[X] - center_axis0; + int32_t rt_axis1 = next_target.target.axis[Y] - center_axis1; +*/ + float r_axis0 = -next_target.I/1000.0; + float r_axis1 = -next_target.J/1000.0; + float rt_axis0 = (next_target.target.axis[X] - center_axis0)/1000.0; + float rt_axis1 = (next_target.target.axis[Y] - center_axis1)/1000.0; + + if (DEBUG_ARC && (debug_flags & DEBUG_ARC)){ + serial_writestr_P(PSTR(" r_axis0: ")); + prt_int((int32_t)(r_axis0*1000.0)); + serial_writestr_P(PSTR(" r_axis1: ")); + prt_int((int32_t)(r_axis1*1000.0)); + serial_writestr_P(PSTR(" rt_axis0: ")); + prt_int((int32_t)(rt_axis0*1000.0)); + serial_writestr_P(PSTR(" rt_axis1: ")); + prt_int((int32_t)(rt_axis1*1000.0)); + serial_writestr_P(PSTR(" linear_travel: ")); + prt_int(linear_travel); + serial_writestr_P(PSTR("\n\r")); + } + + // int acceleration_manager_was_enabled = plan_is_acceleration_manager_enabled(); + // plan_set_acceleration_manager_enabled(false); // disable acceleration management for the duration of the arc +// float center_axis0 = position[axis_0] + offset[axis_0]; +// float center_axis1 = position[axis_1] + offset[axis_1]; +// float linear_travel = target[axis_linear] - position[axis_linear]; +// float extruder_travel = target[E_AXIS] - position[E_AXIS]; +// float r_axis0 = -offset[axis_0]; // Radius vector from center to current location +// float r_axis1 = -offset[axis_1]; +// float rt_axis0 = target[axis_0] - center_axis0; +// float rt_axis1 = target[axis_1] - center_axis1; +// +//#define M_PI 3.14159265358979323846 /* pi */ +//#define MC_PI 3141 /* pi */ + // CCW angle between position and target from circle center. Only one atan2() trig computation required. + float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1); +// uint16_t angular_travel = 1000*atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1); + if (angular_travel < 0) { angular_travel += 2*M_PI; } //<0: -3141..0 --> 3141..6282 ; 0..6282 + if (isclockwise) { angular_travel -= 2*M_PI; } // -6282..0 + +// float millimeters_of_travel = hypot(angular_travel*radius, fabs(linear_travel/1000.0)); + //the next integer approx will overflow if the radius is very large combined with a large angular travel. + //example: maximum angular travel =2xPI then overflow at radius>=683mm. + //the radius was already aproximated, at a radius of 250mm the aprox already differs 8mm (258mm) about 3% + //meaning millimeters_of_travel (actually micrometers here) will be off by some % too. + //This only has effect for calculating the number of segments and for this the approx is accurate enough + uint32_t millimeters_of_travel = approx_distance(labs((uint32_t)(angular_travel*radius)), labs(linear_travel)); +// if (millimeters_of_travel < 0.001) { return; } +// if (millimeters_of_travel < 1) { return; } //todo: just enqueue to target instead.. maybe already if <10?? + if (millimeters_of_travel < 10) { // 0,01 mm , just go there and return + if (millimeters_of_travel >0) + enqueue(&next_target.target); + return; } // integer value = 0 then. todo: just enqueue to target if <10?? + //todo: comment on this +// float mm_per_arc_segment; +// if (radius>5) mm_per_arc_segment=1+radius/50; +// else mm_per_arc_segment=radius/5; + uint16_t mm_per_arc_segment; + if (radius>5000) mm_per_arc_segment=1000+radius/50; + else mm_per_arc_segment=radius/5; + +// uint16_t segments = floor(millimeters_of_travel/mm_per_arc_segment); + uint16_t segments = millimeters_of_travel/mm_per_arc_segment; + if(segments == 0) segments = 1; + + if (DEBUG_ARC && (debug_flags & DEBUG_ARC)){ + serial_writestr_P(PSTR(" millimeters_of_travel: ")); + prt_int(millimeters_of_travel); + serial_writestr_P(PSTR(" angular travel (radians): ")); + prt_int((int32_t)(angular_travel*1000.0)); + serial_writestr_P(PSTR(" segments: ")); + serwrite_uint16(segments); + serial_writestr_P(PSTR(" mm_per_arc_segment: ")); + prt_int((int32_t)mm_per_arc_segment); + serial_writestr_P(PSTR("\n\r")); + } + + /* + // Multiply inverse feed_rate to compensate for the fact that this movement is approximated + // by a number of discrete segments. The inverse feed_rate should be correct for the sum of + // all segments. + if (invert_feed_rate) { feed_rate *= segments; } + */ + float theta_per_segment = angular_travel/segments; + int32_t linear_per_segment = linear_travel/segments; + int32_t extruder_per_segment = extruder_travel/segments; + + /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector, + and phi is the angle of rotation. Based on the solution approach by Jens Geisler. + r_T = [cos(phi) -sin(phi); + sin(phi) cos(phi] * r ; + + For arc generation, the center of the circle is the axis of rotation and the radius vector is + defined from the circle center to the initial position. Each line segment is formed by successive + vector rotations. This requires only two cos() and sin() computations to form the rotation + matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since + all double numbers are single precision on the Arduino. (True double precision will not have + round off issues for CNC applications.) Single precision error can accumulate to be greater than + tool precision in some cases. Therefore, arc path correction is implemented. + + Small angle approximation may be used to reduce computation overhead further. This approximation + holds for everything, but very small circles and large mm_per_arc_segment values. In other words, + theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large + to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for + numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an + issue for CNC machines with the single precision Arduino calculations. + + This approximation also allows mc_arc to immediately insert a line segment into the planner + without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied + a correction, the planner should have caught up to the lag caused by the initial mc_arc overhead. + This is important when there are successive arc motions. + */ + // Vector rotation matrix values + float cos_T = 1-0.5*theta_per_segment*theta_per_segment; // Small angle approximation + float sin_T = theta_per_segment; + float sin_Ti; + float cos_Ti; + float r_axisi; + uint16_t i; + int8_t count = 0; + TARGET arc_target; ///< target position: X, Y, Z, E and F for next arc part + + if (DEBUG_ARC && (debug_flags & DEBUG_ARC)){ + serial_writestr_P(PSTR(" cos_T: ")); + prt_int((int32_t)(cos_T*1000)); + serial_writestr_P(PSTR(" sin_T: ")); + prt_int((int32_t)(sin_T*1000)); + serial_writestr_P(PSTR("\n\r")); + } + + // Initialize the linear axis + arc_target.axis[Z] = startpoint.axis[Z]; + + // Initialize the extruder axis + arc_target.axis[E] = startpoint.axis[E]; + + // Initialize F + arc_target.F = next_target.target.F; + + // if (DEBUG_ARC && (debug_flags & DEBUG_ARC)){ + int32_t Xold=startpoint.axis[X]; + int32_t Yold=startpoint.axis[Y]; +// } + + for (i = 1; i X_MAX_LENGTH) arc_target.axis[X] = X_MAX_LENGTH; +// if (arc_target.axis[Y] > Y_MAX_LENGTH) arc_target.axis[Y] = Y_MAX_LENGTH; +// if (arc_target.axis[Z] > Z_MAX_LENGTH) arc_target.axis[Z] = Z_MAX_LENGTH; +// } +// plan_buffer_line(arc_target.axis[X], arc_target.axis[Y], arc_target.axis[Z], arc_target.axis[E], feed_rate, extruder); + enqueue(&arc_target); + + if (DEBUG_ARC && (debug_flags & DEBUG_ARC)){ + +/* + serial_writestr_P(PSTR(" goto X,Y,Z: ")); + prt_int(arc_target.axis[X]); + serial_writestr_P(PSTR(", ")); + prt_int(arc_target.axis[Y]); + serial_writestr_P(PSTR(", ")); + prt_int(arc_target.axis[Z]); + serial_writestr_P(PSTR("\n\r")); +*/ + + serial_writestr_P(PSTR("\n\r")); + + Xold=arc_target.axis[X]; + Yold=arc_target.axis[Y]; + } + + + } + // Ensure last segment arrives at target location. + enqueue(&next_target.target); + if (DEBUG_ARC && (debug_flags & DEBUG_ARC)){ + serial_writestr_P(PSTR("\n\r")); + } +/* + serial_writestr_P(PSTR("lgoto X,Y,Z: ")); + prt_int(next_target.target.axis[X]); + serial_writestr_P(PSTR(", ")); + prt_int(next_target.target.axis[Y]); + serial_writestr_P(PSTR(", ")); + prt_int(next_target.target.axis[Z]); + serial_writestr_P(PSTR("\n\r")); +*/ +} + diff --git a/motion_control.h b/motion_control.h new file mode 100644 index 000000000..2a95c236e --- /dev/null +++ b/motion_control.h @@ -0,0 +1,31 @@ +/* + motion_control.h - high level interface for issuing motion commands + Part of Grbl + + Copyright (c) 2009-2011 Simen Svale Skogsrud + Copyright (c) 2011 Sungeun K. Jeon + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grbl. If not, see . +*/ + +#ifndef motion_control_h +#define motion_control_h + +// Execute an arc in offset mode format. position == current xyz, target == target xyz, +// offset == offset from current xyz, axis_XXX defines circle plane in tool space, axis_linear is +// the direction of helical travel, radius == circle radius, isclockwise boolean. Used +// for vector transformation direction. +void mc_arc(uint32_t radius, unsigned char isclockwise); + +#endif diff --git a/pinio.h b/pinio.h index cd3e53138..e59fa801f 100644 --- a/pinio.h +++ b/pinio.h @@ -156,6 +156,20 @@ void pinio_init(void); void power_on(void); void power_off(void); +/* +Resume pin +*/ + +#ifdef RESUME_PIN + #ifndef RESUME_INVERT + #define e_min() (READ(RESUME_PIN)?1:0) + #else + #define e_min() (READ(RESUME_PIN)?0:1) + #endif +#else + #define e_min() (0) +#endif + /* X Stepper */ From 29edced8673ce326abca79bb74640694cf45f844 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Thu, 31 Mar 2016 17:21:17 +0200 Subject: [PATCH 2/2] motion_control.c: add defaults for segmentation settings. --- motion_control.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/motion_control.c b/motion_control.c index 8a0d84f61..310890e6d 100644 --- a/motion_control.c +++ b/motion_control.c @@ -35,6 +35,23 @@ #include "sermsg.h" //for debugging #include "debug.h" //for debugging + +// Arc interpretation settings: +#ifndef MM_PER_ARC_SEGMENT + #define MM_PER_ARC_SEGMENT 1 + #warning MM_PER_ARC_SEGMENT not user defined, defaulting to 1. +#endif +// Number of arc generation iterations by small angle approximation before exact arc trajectory +// correction. This parameter maybe decreased if there are issues with the accuracy of the arc +// generations. In general, the default value is more than enough for the intended CNC applications +// of grbl, and should be on the order or greater than the size of the buffer to help with the +// computational efficiency of generating arcs. +#ifndef N_ARC_CORRECTION + #define N_ARC_CORRECTION 25 // Integer (1-255) + #warning N_ARC_CORRECTION not user defined, defaulting to 25. +#endif + + void prt_int(int32_t number) { if (number/1000==0 && number<0) serial_writestr_P(PSTR("-"));