diff --git a/readme.textile b/readme.textile index fab1580..c4d2b97 100644 --- a/readme.textile +++ b/readme.textile @@ -4,12 +4,20 @@ Grbl is a no-compromise, high performance, low cost alternative to parallel-port The controller is written in highly optimized C utilizing every clever feature of the AVR-chips to achieve precise timing and asynchronous operation. It is able to maintain more than 30kHz of stable, jitter free control pulses. -It accepts standards-compliant G-code and has been tested with the output of several CAM tools with no problems. Arcs, circles and helical motion are fully supported - but no support for tool offsets, functions or variables as these are apocryphal and fell into disuse after humans left G-code authoring to machines some time in the 80s. +It accepts standards-compliant G-code and has been tested with the output of several CAM tools with no problems. Arcs, circles and helical motion are fully supported, as well as, other basic functional g-code commands. Functions and variables are not currently supported, but may be included in future releases in a form of a pre-processor. -Grbl includes full acceleration management with look ahead. That means the controller will look up to 20 motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering. +Grbl includes full acceleration management with look ahead. That means the controller will look up to 16 to 20 motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering. -*Important note for Atmega 168 users:* Grbl used to be compatible with both the older Ardunios running atmega 168 and the newer with 328p. The full version of Grbl now compiles without support for circles/arcs if you target 168. If you need arcs, but not acceleration-management I am still maintaining Grbl 0.51 "in the branch called 'v0_51'":https://github.com/simen/grbl/tree/v0_51. +*Changelog for v0.7 from v0.6:* + - Significantly improved and optimized planner re-factoring. + - New robust cornering algorithm, enabling smoother and faster motions. + - Arc acceleration planning enabled by efficient vector transformation implementation. + - Stepper subsystem re-factoring to help remove some motion issues from pre-v0.7 builds. + - Increased dwell times. + - G92 Coordinate offset support. + - (Beta) Limit switch and homing cycle support. + - Many other bug fixes and efficiency improvements. -*Note for users upgrading from 0.51 to 0.6:* The new version has new and improved default pin-out. If nothing works when you upgrade, that is because the pulse trains are coming from the wrong pins. This is a simple matter of editing config.h – the whole legacy pin assignment is there for you to uncomment. +*Important note for Atmega 168 users:* Going forward, support for Atmega 168 will be dropped due to its limited memory and speed. However, legacy Grbl v0.51 "in the branch called 'v0_51' is still available for use. _The project was initially inspired by the Arduino GCode Interpreter by Mike Ellery_ diff --git a/stepper.c b/stepper.c index b810259..d8110e5 100644 --- a/stepper.c +++ b/stepper.c @@ -49,7 +49,7 @@ static int32_t counter_x, // Counter variables for the bresenham line trac counter_y, counter_z; static uint32_t step_events_completed; // The number of step events executed in the current block -static volatile int busy; // true when SIG_OUTPUT_COMPARE1A is being serviced. Used to avoid retriggering that handler. +static volatile uint8_t busy; // true when SIG_OUTPUT_COMPARE1A is being serviced. Used to avoid retriggering that handler. // Variables used by the trapezoid generation static uint32_t cycles_per_step_event; // The number of machine cycles between each step event @@ -79,7 +79,8 @@ static uint8_t cycle_start; // Cycle start flag to indicate program start an static void set_step_events_per_minute(uint32_t steps_per_minute); // Stepper state initialization -void st_wake_up() { +void st_wake_up() +{ // Initialize stepper output bits out_bits = (0) ^ (settings.invert_mask); // Enable steppers by resetting the stepper disable port @@ -89,7 +90,8 @@ void st_wake_up() { } // Stepper shutdown -static void st_go_idle() { +void st_go_idle() +{ // Cycle finished. Set flag to false. cycle_start = false; // Disable stepper driver interrupt @@ -105,7 +107,8 @@ static void st_go_idle() { // Initializes the trapezoid generator from the current block. Called whenever a new // block begins. -static void trapezoid_generator_reset() { +static void trapezoid_generator_reset() +{ trapezoid_adjusted_rate = current_block->initial_rate; min_safe_rate = current_block->rate_delta + (current_block->rate_delta >> 1); // 1.5 x rate_delta trapezoid_tick_cycle_counter = CYCLES_PER_ACCELERATION_TICK/2; // Start halfway for midpoint rule. @@ -115,7 +118,8 @@ static void trapezoid_generator_reset() { // This function determines an acceleration velocity change every CYCLES_PER_ACCELERATION_TICK by // keeping track of the number of elapsed cycles during a de/ac-celeration. The code assumes that // step_events occur significantly more often than the acceleration velocity iterations. -static uint8_t iterate_trapezoid_cycle_counter() { +static uint8_t iterate_trapezoid_cycle_counter() +{ trapezoid_tick_cycle_counter += cycles_per_step_event; if(trapezoid_tick_cycle_counter > CYCLES_PER_ACCELERATION_TICK) { trapezoid_tick_cycle_counter -= CYCLES_PER_ACCELERATION_TICK; @@ -186,16 +190,13 @@ SIGNAL(TIMER1_COMPA_vect) // While in block steps, check for de/ac-celeration events and execute them accordingly. if (step_events_completed < current_block->step_event_count) { - // The trapezoid generator always checks step event location to ensure de/ac-celerations are // executed and terminated at exactly the right time. This helps prevent over/under-shooting // the target position and speed. - // NOTE: By increasing the ACCELERATION_TICKS_PER_SECOND in config.h, the resolution of the // discrete velocity changes increase and accuracy can increase as well to a point. Numerical // round-off errors can effect this, if set too high. This is important to note if a user has // very high acceleration and/or feedrate requirements for their machine. - if (step_events_completed < current_block->accelerate_until) { // Iterate cycle counter and check if speeds need to be increased. if ( iterate_trapezoid_cycle_counter() ) { @@ -248,9 +249,7 @@ SIGNAL(TIMER1_COMPA_vect) current_block = NULL; plan_discard_current_block(); } - } - out_bits ^= settings.invert_mask; // Apply stepper invert mask busy=false; } @@ -306,33 +305,33 @@ static uint32_t config_step_timer(uint32_t cycles) uint16_t ceiling; uint16_t prescaler; uint32_t actual_cycles; - if (cycles <= 0xffffL) { - ceiling = cycles; - prescaler = 0; // prescaler: 0 - actual_cycles = ceiling; - } else if (cycles <= 0x7ffffL) { - ceiling = cycles >> 3; - prescaler = 1; // prescaler: 8 - actual_cycles = ceiling * 8L; - } else if (cycles <= 0x3fffffL) { - ceiling = cycles >> 6; - prescaler = 2; // prescaler: 64 - actual_cycles = ceiling * 64L; - } else if (cycles <= 0xffffffL) { - ceiling = (cycles >> 8); - prescaler = 3; // prescaler: 256 - actual_cycles = ceiling * 256L; - } else if (cycles <= 0x3ffffffL) { - ceiling = (cycles >> 10); - prescaler = 4; // prescaler: 1024 - actual_cycles = ceiling * 1024L; - } else { - // Okay, that was slower than we actually go. Just set the slowest speed - ceiling = 0xffff; - prescaler = 4; - actual_cycles = 0xffff * 1024; - } - // Set prescaler + if (cycles <= 0xffffL) { + ceiling = cycles; + prescaler = 0; // prescaler: 0 + actual_cycles = ceiling; + } else if (cycles <= 0x7ffffL) { + ceiling = cycles >> 3; + prescaler = 1; // prescaler: 8 + actual_cycles = ceiling * 8L; + } else if (cycles <= 0x3fffffL) { + ceiling = cycles >> 6; + prescaler = 2; // prescaler: 64 + actual_cycles = ceiling * 64L; + } else if (cycles <= 0xffffffL) { + ceiling = (cycles >> 8); + prescaler = 3; // prescaler: 256 + actual_cycles = ceiling * 256L; + } else if (cycles <= 0x3ffffffL) { + ceiling = (cycles >> 10); + prescaler = 4; // prescaler: 1024 + actual_cycles = ceiling * 1024L; + } else { + // Okay, that was slower than we actually go. Just set the slowest speed + ceiling = 0xffff; + prescaler = 4; + actual_cycles = 0xffff * 1024; + } + // Set prescaler TCCR1B = (TCCR1B & ~(0x07<