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.
This commit is contained in:
parent
d3be216931
commit
79e0fd594b
41
config.h
Normal file → Executable file
41
config.h
Normal file → Executable file
@ -75,7 +75,7 @@
|
|||||||
// entering g-code into grbl, i.e. locating part zero or simple manual machining. If the axes drift,
|
// 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
|
// 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.
|
// 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
|
#define STEPPER_IDLE_LOCK_TIME 25 // (milliseconds) - Integer > 0
|
||||||
|
|
||||||
// The temporal resolution of the acceleration management subsystem. Higher number give smoother
|
// 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.
|
// 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)
|
#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
|
// FOR ADVANCED USERS ONLY:
|
||||||
// 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
|
// Toggles XON/XOFF software flow control for serial communications. Not officially supported
|
||||||
// standard terminal programs. However, using specifically-programmed UI's to manage this latency
|
// due to problems involving the Atmega8U2 USB-to-serial chips on current Arduinos. The firmware
|
||||||
// problem has been confirmed to work, as well as, using older FTDI FT232RL-based Arduinos
|
// on these chips do not support XON/XOFF flow control characters and the intermediate buffer
|
||||||
// (Duemilanove) since their firmaware correctly manage the XON/XOFF characters. Other unconfirmed
|
// in the chips cause latency and overflow problems with standard terminal programs. However,
|
||||||
// methods include using an FTDI board/cable or directly communicate on the RX/TX pins on the
|
// using specifically-programmed UI's to manage this latency problem has been confirmed to work.
|
||||||
// Arduino, both of which circumvent the Atmega8U2 chip altogether. In any case, please report any
|
// As well as, older FTDI FT232RL-based Arduinos(Duemilanove) are known to work with standard
|
||||||
// successes to grbl administrators!
|
// 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.
|
#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
|
// TODO: The following options are set as compile-time options for now, until the next EEPROM
|
||||||
// settings version has solidified.
|
// settings version has solidified.
|
||||||
|
8
readme.textile
Normal file → Executable file
8
readme.textile
Normal file → Executable file
@ -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.
|
- 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.
|
- 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.
|
- 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.
|
- Reduced serial read buffer to 128 characters and increased write buffer to 64 characters.
|
||||||
- Reduce serial read buffer to 128 characters and increased write buffer to 64 characters.
|
- Misc bug fixes and removed deprecated acceleration enabled code.
|
||||||
- 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.
|
*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.
|
||||||
|
|
||||||
|
44
stepper.c
Normal file → Executable file
44
stepper.c
Normal file → Executable file
@ -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 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.
|
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
|
// Initialize stepper output bits
|
||||||
out_bits = (0) ^ (settings.invert_mask);
|
out_bits = (0) ^ (settings.invert_mask);
|
||||||
// Set step pulse time. Ad hoc computation from oscilloscope.
|
// Initialize step pulse timing from settings. Here to ensure updating after re-writing.
|
||||||
step_pulse_time = -(((settings.pulse_microseconds-2)*TICKS_PER_MICROSECOND) >> 3);
|
#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
|
// Enable steppers by resetting the stepper disable port
|
||||||
STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT);
|
STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT);
|
||||||
// Enable stepper driver interrupt
|
// Enable stepper driver interrupt
|
||||||
@ -101,7 +113,7 @@ void st_go_idle()
|
|||||||
TIMSK1 &= ~(1<<OCIE1A);
|
TIMSK1 &= ~(1<<OCIE1A);
|
||||||
// Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete
|
// Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete
|
||||||
// stop and not drift from residual inertial forces at the end of the last movement.
|
// stop and not drift from residual inertial forces at the end of the last movement.
|
||||||
#ifdef STEPPER_IDLE_LOCK_TIME
|
#if STEPPER_IDLE_LOCK_TIME > 0
|
||||||
_delay_ms(STEPPER_IDLE_LOCK_TIME);
|
_delay_ms(STEPPER_IDLE_LOCK_TIME);
|
||||||
#endif
|
#endif
|
||||||
// Disable steppers by setting stepper disable
|
// 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
|
// Set the direction pins a couple of nanoseconds before we step the steppers
|
||||||
STEPPING_PORT = (STEPPING_PORT & ~DIRECTION_MASK) | (out_bits & DIRECTION_MASK);
|
STEPPING_PORT = (STEPPING_PORT & ~DIRECTION_MASK) | (out_bits & DIRECTION_MASK);
|
||||||
// Then pulse the stepping pins
|
// 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
|
// 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.
|
// exactly settings.pulse_microseconds microseconds, independent of the main Timer1 prescaler.
|
||||||
TCNT2 = step_pulse_time; // Reload timer counter
|
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.
|
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
|
// Reset and clear stepper subsystem variables
|
||||||
void st_reset()
|
void st_reset()
|
||||||
{
|
{
|
||||||
@ -314,7 +342,7 @@ void st_init()
|
|||||||
STEPPING_DDR |= STEPPING_MASK;
|
STEPPING_DDR |= STEPPING_MASK;
|
||||||
STEPPING_PORT = (STEPPING_PORT & ~STEPPING_MASK) | settings.invert_mask;
|
STEPPING_PORT = (STEPPING_PORT & ~STEPPING_MASK) | settings.invert_mask;
|
||||||
STEPPERS_DISABLE_DDR |= 1<<STEPPERS_DISABLE_BIT;
|
STEPPERS_DISABLE_DDR |= 1<<STEPPERS_DISABLE_BIT;
|
||||||
|
|
||||||
// waveform generation = 0100 = CTC
|
// waveform generation = 0100 = CTC
|
||||||
TCCR1B &= ~(1<<WGM13);
|
TCCR1B &= ~(1<<WGM13);
|
||||||
TCCR1B |= (1<<WGM12);
|
TCCR1B |= (1<<WGM12);
|
||||||
@ -329,7 +357,11 @@ void st_init()
|
|||||||
TCCR2A = 0; // Normal operation
|
TCCR2A = 0; // Normal operation
|
||||||
TCCR2B = 0; // Disable timer until needed.
|
TCCR2B = 0; // Disable timer until needed.
|
||||||
TIMSK2 |= (1<<TOIE2);
|
TIMSK2 |= (1<<TOIE2);
|
||||||
|
|
||||||
|
#if STEP_PULSE_DELAY > 0
|
||||||
|
TIMSK2 |= (1<<OCIE2A); // Enable Timer2 Compare Match A interrupt
|
||||||
|
#endif
|
||||||
|
|
||||||
// Start in the idle state
|
// Start in the idle state
|
||||||
st_go_idle();
|
st_go_idle();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user