From 79e0fd594b4481fc74eac9c6669fef1a994c6b48 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Tue, 26 Jun 2012 21:48:42 -0600 Subject: [PATCH] Added step pulse delay after direction set (Compile-time option only). Updated read me. Added a compile-time only experimental feature that creates a user-specified time delay between a step pulse and a direction pin set (in config.h). This is for users with hardware-specific issues (opto-couplers) that need more than a few microseconds between events, which can lead to slowly progressing step drift after many many direction changes. We suggest to try the hack/fix posted in the Wiki before using this, as this experimental feature may cause Grbl to take a performance hit at high step rates and about complex curves. --- config.h | 41 +++++++++++++++++++++++++++++------------ readme.textile | 8 +++++--- stepper.c | 44 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 72 insertions(+), 21 deletions(-) mode change 100644 => 100755 config.h mode change 100644 => 100755 readme.textile mode change 100644 => 100755 stepper.c diff --git a/config.h b/config.h old mode 100644 new mode 100755 index 0128be8..69290f7 --- a/config.h +++ b/config.h @@ -75,7 +75,7 @@ // entering g-code into grbl, i.e. locating part zero or simple manual machining. If the axes drift, // grbl has no way to know this has happened, since stepper motors are open-loop control. Depending // on the machine, this parameter may need to be larger or smaller than the default time. -// NOTE: If commented out, the delay will not be compiled. +// NOTE: If set to zero, the delay will not be compiled. #define STEPPER_IDLE_LOCK_TIME 25 // (milliseconds) - Integer > 0 // The temporal resolution of the acceleration management subsystem. Higher number give smoother @@ -114,19 +114,36 @@ // time step. Also, keep in mind that the Arduino delay timer is not very accurate for long delays. #define DWELL_TIME_STEP 50 // Integer (1-255) (milliseconds) -// FOR ADVANCED USERS ONLY: Toggles XON/XOFF software flow control for serial communications. -// Officially not supported due to problems involving the Atmega8U2 USB-to-serial chips on all -// new and future Arduinos. The firmware on these chips do not support XON/XOFF flow control -// characters and the intermediate buffer in the chips cause latency and overflow problems with -// standard terminal programs. However, using specifically-programmed UI's to manage this latency -// problem has been confirmed to work, as well as, using older FTDI FT232RL-based Arduinos -// (Duemilanove) since their firmaware correctly manage the XON/XOFF characters. Other unconfirmed -// methods include using an FTDI board/cable or directly communicate on the RX/TX pins on the -// Arduino, both of which circumvent the Atmega8U2 chip altogether. In any case, please report any -// successes to grbl administrators! +// --------------------------------------------------------------------------------------- +// FOR ADVANCED USERS ONLY: + +// Toggles XON/XOFF software flow control for serial communications. Not officially supported +// due to problems involving the Atmega8U2 USB-to-serial chips on current Arduinos. The firmware +// on these chips do not support XON/XOFF flow control characters and the intermediate buffer +// in the chips cause latency and overflow problems with standard terminal programs. However, +// using specifically-programmed UI's to manage this latency problem has been confirmed to work. +// As well as, older FTDI FT232RL-based Arduinos(Duemilanove) are known to work with standard +// terminal programs since their firmware correctly manage these XON/XOFF characters. In any +// case, please report any successes to grbl administrators! #define ENABLE_XONXOFF 0 // Boolean. Default disabled. -// ----------------------------------------------- +// Creates a delay between the direction pin setting and corresponding step pulse by creating +// another interrupt (Timer2 compare) to manage it. The main Grbl interrupt (Timer1 compare) +// sets the direction pins, and does not immediately set the stepper pins, as it would in +// normal operation. The Timer2 compare fires next to set the stepper pins after the step +// pulse delay time, and Timer2 overflow will complete the step pulse, except now delayed +// by the step pulse time plus the step pulse delay. (Thanks langwadt for the idea!) +// This is an experimental feature that should only be used if your setup requires a longer +// delay between direction and step pin settings (some opto coupler based drivers), as it may +// adversely effect Grbl's high-end performance (>10kHz). Please notify Grbl administrators +// of your successes or difficulties, as we will monitor this and possibly integrate this as a +// standard feature for future releases. However, we suggest to first try our direction delay +// hack/solution posted in the Wiki involving inverting the stepper pin mask. +// NOTE: If set greater than zero, step pulse delay will be compiled and enabled. Also, the +// total delay added with the Grbl settings pulse microseconds must not exceed 127 ms. +#define STEP_PULSE_DELAY 0 // Step pulse delay in microseconds. Default disabled. + +// --------------------------------------------------------------------------------------- // TODO: The following options are set as compile-time options for now, until the next EEPROM // settings version has solidified. diff --git a/readme.textile b/readme.textile old mode 100644 new mode 100755 index ad06c0f..9bcc8ea --- a/readme.textile +++ b/readme.textile @@ -19,9 +19,11 @@ Grbl includes full acceleration management with look ahead. That means the contr - Program stop(M0,M1*,M2,M30) initial support. Optional stop to do. - System reset re-initializes grbl without resetting the Arduino and retains machine/home position and work coordinates. - Restructured planner and stepper modules to become independent and ready for future features. - - Planned features: Jog mode, status reporting, runtime settings such as toggling block delete, XON/XOFF flow control. - - Reduce serial read buffer to 128 characters and increased write buffer to 64 characters. - - Misc bug fixes and removed deprecated acceleration enabled code. + - Reduced serial read buffer to 128 characters and increased write buffer to 64 characters. + - Misc bug fixes and removed deprecated acceleration enabled code. + - Planned features: Jog mode, full-featured status reporting, runtime settings such as toggling block delete. + - Advanced compile-time options: Up to 6 work coordinate systems(G54-G59), XON/XOFF flow control (limited support), direction and step pulse time delay. + *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. diff --git a/stepper.c b/stepper.c old mode 100644 new mode 100755 index c340b61..5ba9eda --- a/stepper.c +++ b/stepper.c @@ -62,6 +62,10 @@ static uint8_t step_pulse_time; // Step pulse reset time after step rise static uint8_t out_bits; // The next stepping-bits to be output static volatile uint8_t busy; // True when SIG_OUTPUT_COMPARE1A is being serviced. Used to avoid retriggering that handler. +#if STEP_PULSE_DELAY > 0 + static uint8_t step_bits; // Stores out_bits output to complete the step pulse delay +#endif + // __________________________ // /| |\ _________________ ^ // / | | \ /| |\ | @@ -86,8 +90,16 @@ static void st_wake_up() { // Initialize stepper output bits out_bits = (0) ^ (settings.invert_mask); - // Set step pulse time. Ad hoc computation from oscilloscope. - step_pulse_time = -(((settings.pulse_microseconds-2)*TICKS_PER_MICROSECOND) >> 3); + // Initialize step pulse timing from settings. Here to ensure updating after re-writing. + #if STEP_PULSE_DELAY > 0 + // Set total step pulse time after direction pin set. Ad hoc computation from oscilloscope. + step_pulse_time = -(((settings.pulse_microseconds+STEP_PULSE_DELAY-2)*TICKS_PER_MICROSECOND) >> 3); + // Set delay between direction pin write and step command. + OCR2A = -(((settings.pulse_microseconds)*TICKS_PER_MICROSECOND) >> 3); + #else // Normal operation + // Set step pulse time. Ad hoc computation from oscilloscope. Uses two's complement. + step_pulse_time = -(((settings.pulse_microseconds-2)*TICKS_PER_MICROSECOND) >> 3); + #endif // Enable steppers by resetting the stepper disable port STEPPERS_DISABLE_PORT &= ~(1< 0 _delay_ms(STEPPER_IDLE_LOCK_TIME); #endif // Disable steppers by setting stepper disable @@ -133,7 +145,11 @@ ISR(TIMER1_COMPA_vect) // Set the direction pins a couple of nanoseconds before we step the steppers STEPPING_PORT = (STEPPING_PORT & ~DIRECTION_MASK) | (out_bits & DIRECTION_MASK); // Then pulse the stepping pins - STEPPING_PORT = (STEPPING_PORT & ~STEP_MASK) | out_bits; + #if STEP_PULSE_DELAY > 0 + step_bits = (STEPPING_PORT & ~STEP_MASK) | out_bits; // Store out_bits to prevent overwriting. + #else // Normal operation + STEPPING_PORT = (STEPPING_PORT & ~STEP_MASK) | out_bits; + #endif // Enable step pulse reset timer so that The Stepper Port Reset Interrupt can reset the signal after // exactly settings.pulse_microseconds microseconds, independent of the main Timer1 prescaler. TCNT2 = step_pulse_time; // Reload timer counter @@ -298,6 +314,18 @@ ISR(TIMER2_OVF_vect) TCCR2B = 0; // Disable Timer2 to prevent re-entering this interrupt when it's not needed. } +#if STEP_PULSE_DELAY > 0 + // This interrupt is used only when STEP_PULSE_DELAY is enabled. Here, the step pulse is + // initiated after the STEP_PULSE_DELAY time period has elapsed. The ISR TIMER2_OVF interrupt + // will then trigger after the appropriate settings.pulse_microseconds, as in normal operation. + // The new timing between direction, step pulse, and step complete events are setup in the + // st_wake_up() routine. + ISR(TIMER2_COMPA_vect) + { + STEPPING_PORT = step_bits; // Begin step pulse. + } +#endif + // Reset and clear stepper subsystem variables void st_reset() { @@ -314,7 +342,7 @@ void st_init() STEPPING_DDR |= STEPPING_MASK; STEPPING_PORT = (STEPPING_PORT & ~STEPPING_MASK) | settings.invert_mask; STEPPERS_DISABLE_DDR |= 1< 0 + TIMSK2 |= (1<