Applied master branch bug fixes.

- Planner was under-estimating maximum speeds through straight
junctions in certain cases. The calculations have been updated to be
more accurate.

- Strange sizeof() bug in the most recent releases. Manifested as an
alarm upon a power up even when homing was disabled. Fixed by declaring
sizeof() with struct types, rather than variable names, even though
they were validated to give the same value.

- Spindle speed zero should disable the spindle. Now fixed.

- New configuration option for inverting certain limit pins. Handy for
mixed NO and NC switch machines. See config.h for details.
This commit is contained in:
Sonny Jeon 2016-03-04 13:39:29 -07:00
parent 5eee10845b
commit 111d28dc9a
9 changed files with 79 additions and 36 deletions

View File

@ -0,0 +1,25 @@
----------------
Date: 2015-11-09
Author: Sonny Jeon
Subject: Pin state reporting of all pins. Flash optimization.
- New pin state realtime reporting feature. Instead of `Lim:000` for
limit state reports, the new feature shows `Pin:000|0|0000`, or
something similar. The `|` delimited fields indicate xyz limits, probe,
and control pin states, where 0 is always not triggered, and 1 is
triggered. Invert masks ARE accounted for.
Each field may be enabled or disabled via the `$10` status report
setting. The probe and control pin flags are bits 5 and 6, respectively.
- Remove the now deprecated `REPORT_CONTROL_PIN_STATE` option in
config.h
- The old limit pin reports `Lim:000` may be re-enabled by commenting
out `REPORT_ALL_PIN_STATES` in config.h.
- Incremented the version letter (v1.0c) to indicate the change in
reporting style.
- Replaced all bit_true_atomic and bit_false_atomic macros with
function calls. This saved a couple hundred bytes of flash.

View File

@ -127,7 +127,7 @@
#define MESSAGE_PROBE_COORDINATES // Enabled by default. Comment to disable. #define MESSAGE_PROBE_COORDINATES // Enabled by default. Comment to disable.
// Enables a second coolant control pin via the mist coolant g-code command M7 on the Arduino Uno // Enables a second coolant control pin via the mist coolant g-code command M7 on the Arduino Uno
// analog pin 5. Only use this option if you require a second coolant control pin. // analog pin 4. Only use this option if you require a second coolant control pin.
// NOTE: The M8 flood coolant control pin on analog pin 4 will still be functional regardless. // NOTE: The M8 flood coolant control pin on analog pin 4 will still be functional regardless.
// #define ENABLE_M7 // Disabled by default. Uncomment to enable. // #define ENABLE_M7 // Disabled by default. Uncomment to enable.
@ -157,6 +157,15 @@
// the CONTROL_INVERT_MASK definition in cpu_map.h files. // the CONTROL_INVERT_MASK definition in cpu_map.h files.
// #define INVERT_ALL_CONTROL_PINS // Default disabled. Uncomment to enable. // #define INVERT_ALL_CONTROL_PINS // Default disabled. Uncomment to enable.
// Inverts select limit pin states based on the following mask. This effects all limit pin functions,
// such as hard limits and homing. However, this is different from overall invert limits setting.
// This build option will invert only the limit pins defined here, and then the invert limits setting
// will be applied to all of them. This is useful when a user has a mixed set of limit pins with both
// normally-open(NO) and normally-closed(NC) switches installed on their machine.
// NOTE: PLEASE DO NOT USE THIS, unless you have a situation that needs it.
// #define INVERT_LIMIT_PIN_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)) // Default disabled. Uncomment to enable.
// Inverts the spindle enable pin from low-disabled/high-enabled to low-enabled/high-disabled. Useful // Inverts the spindle enable pin from low-disabled/high-enabled to low-enabled/high-disabled. Useful
// for some pre-built electronic boards. // for some pre-built electronic boards.
// NOTE: If VARIABLE_SPINDLE is enabled(default), this option has no effect as the PWM output and // NOTE: If VARIABLE_SPINDLE is enabled(default), this option has no effect as the PWM output and

View File

@ -40,7 +40,7 @@ parser_block_t gc_block;
void gc_init() void gc_init()
{ {
memset(&gc_state, 0, sizeof(gc_state)); memset(&gc_state, 0, sizeof(parser_state_t));
// Load default G54 coordinate system. // Load default G54 coordinate system.
if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) { if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) {
@ -80,7 +80,7 @@ uint8_t gc_execute_line(char *line)
values struct, word tracking variables, and a non-modal commands tracker for the new values struct, word tracking variables, and a non-modal commands tracker for the new
block. This struct contains all of the necessary information to execute the block. */ block. This struct contains all of the necessary information to execute the block. */
memset(&gc_block, 0, sizeof(gc_block)); // Initialize the parser block struct. memset(&gc_block, 0, sizeof(parser_block_t)); // Initialize the parser block struct.
memcpy(&gc_block.modal,&gc_state.modal,sizeof(gc_modal_t)); // Copy current modes memcpy(&gc_block.modal,&gc_state.modal,sizeof(gc_modal_t)); // Copy current modes
uint8_t axis_command = AXIS_COMMAND_NONE; uint8_t axis_command = AXIS_COMMAND_NONE;
uint8_t axis_0, axis_1, axis_linear; uint8_t axis_0, axis_1, axis_linear;

View File

@ -23,7 +23,7 @@
// Grbl versioning system // Grbl versioning system
#define GRBL_VERSION "1.0c" #define GRBL_VERSION "1.0c"
#define GRBL_VERSION_BUILD "20151109" #define GRBL_VERSION_BUILD "20160304"
// Define standard libraries used by Grbl. // Define standard libraries used by Grbl.
#include <avr/io.h> #include <avr/io.h>

View File

@ -70,6 +70,9 @@ uint8_t limits_get_state()
{ {
uint8_t limit_state = 0; uint8_t limit_state = 0;
uint8_t pin = (LIMIT_PIN & LIMIT_MASK); uint8_t pin = (LIMIT_PIN & LIMIT_MASK);
#ifdef INVERT_LIMIT_PIN_MASK
pin ^= INVERT_LIMIT_PIN_MASK;
#endif
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { pin ^= LIMIT_MASK; } if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { pin ^= LIMIT_MASK; }
if (pin) { if (pin) {
uint8_t idx; uint8_t idx;

View File

@ -34,7 +34,7 @@ int main(void)
stepper_init(); // Configure stepper pins and interrupt timers stepper_init(); // Configure stepper pins and interrupt timers
system_init(); // Configure pinout pins and pin-change interrupt system_init(); // Configure pinout pins and pin-change interrupt
memset(&sys, 0, sizeof(sys)); // Clear all system variables memset(&sys, 0, sizeof(system_t)); // Clear all system variables
sys.abort = true; // Set abort to complete initialization sys.abort = true; // Set abort to complete initialization
sei(); // Enable interrupts sei(); // Enable interrupts

View File

@ -200,7 +200,7 @@ static void planner_recalculate()
void plan_reset() void plan_reset()
{ {
memset(&pl, 0, sizeof(pl)); // Clear planner struct memset(&pl, 0, sizeof(planner_t)); // Clear planner struct
block_buffer_tail = 0; block_buffer_tail = 0;
block_buffer_head = 0; // Empty = tail block_buffer_head = 0; // Empty = tail
next_buffer_head = 1; // plan_next_block_index(block_buffer_head) next_buffer_head = 1; // plan_next_block_index(block_buffer_head)
@ -394,11 +394,11 @@ uint8_t plan_check_full_buffer()
change the overall maximum entry speed conditions of all blocks. change the overall maximum entry speed conditions of all blocks.
*/ */
// NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta). // NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta).
if (junction_cos_theta > 0.99) { if (junction_cos_theta > 0.999999) {
// For a 0 degree acute junction, just set minimum junction speed. // For a 0 degree acute junction, just set minimum junction speed.
block->max_junction_speed_sqr = MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED; block->max_junction_speed_sqr = MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED;
} else { } else {
junction_cos_theta = max(junction_cos_theta,-0.99); // Check for numerical round-off to avoid divide by zero. junction_cos_theta = max(junction_cos_theta,-0.999999); // Check for numerical round-off to avoid divide by zero.
float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive. float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive.
// TODO: Technically, the acceleration used in calculation needs to be limited by the minimum of the // TODO: Technically, the acceleration used in calculation needs to be limited by the minimum of the

View File

@ -106,40 +106,46 @@ void spindle_set_state(uint8_t state, float rpm)
#endif #endif
// Calculate PWM register value based on rpm max/min settings and programmed rpm. // Calculate PWM register value based on rpm max/min settings and programmed rpm.
if (settings.rpm_max <= settings.rpm_min) { if (rpm <= 0.0) { spindle_stop(); } // RPM should never be negative, but check anyway.
// No PWM range possible. Set simple on/off spindle control pin state. else {
current_pwm = PWM_MAX_VALUE; if (settings.rpm_max <= settings.rpm_min) {
} else { // No PWM range possible. Set simple on/off spindle control pin state.
if (rpm > settings.rpm_max) { rpm = settings.rpm_max; } current_pwm = PWM_MAX_VALUE;
if (rpm < settings.rpm_min) { rpm = settings.rpm_min; } } else {
#ifdef SPINDLE_MINIMUM_PWM if (rpm > settings.rpm_max) { rpm = settings.rpm_max; }
float pwm_gradient = (PWM_MAX_VALUE-SPINDLE_MINIMUM_PWM)/(settings.rpm_max-settings.rpm_min); if (rpm < settings.rpm_min) { rpm = settings.rpm_min; }
current_pwm = floor( (rpm-settings.rpm_min)*pwm_gradient + (SPINDLE_MINIMUM_PWM+0.5)); #ifdef SPINDLE_MINIMUM_PWM
#else float pwm_gradient = (PWM_MAX_VALUE-SPINDLE_MINIMUM_PWM)/(settings.rpm_max-settings.rpm_min);
float pwm_gradient = (PWM_MAX_VALUE)/(settings.rpm_max-settings.rpm_min); current_pwm = floor( (rpm-settings.rpm_min)*pwm_gradient + (SPINDLE_MINIMUM_PWM+0.5));
current_pwm = floor( (rpm-settings.rpm_min)*pwm_gradient + 0.5); #else
float pwm_gradient = (PWM_MAX_VALUE)/(settings.rpm_max-settings.rpm_min);
current_pwm = floor( (rpm-settings.rpm_min)*pwm_gradient + 0.5);
#endif
}
OCR_REGISTER = current_pwm; // Set PWM output level.
TCCRA_REGISTER |= (1<<COMB_BIT); // Ensure PWM output is enabled.
// On the Uno, spindle enable and PWM are shared, unless otherwise specified.
#if defined(CPU_MAP_ATMEGA2560) || defined(USE_SPINDLE_DIR_AS_ENABLE_PIN)
#ifdef INVERT_SPINDLE_ENABLE_PIN
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
#else
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
#endif
#endif #endif
} }
OCR_REGISTER = current_pwm; // Set PWM output level. #else
TCCRA_REGISTER |= (1<<COMB_BIT); // Ensure PWM output is enabled.
// On the Uno, spindle enable and PWM are shared, unless otherwise specified. if (rpm <= 0.0) { spindle_stop(); } // RPM should never be negative, but check anyway.
#if defined(CPU_MAP_ATMEGA2560) || defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) else {
#ifdef INVERT_SPINDLE_ENABLE_PIN #ifdef INVERT_SPINDLE_ENABLE_PIN
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT); SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
#else #else
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT); SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
#endif #endif
#endif }
#else
#ifdef INVERT_SPINDLE_ENABLE_PIN
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
#else
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
#endif
#endif #endif

View File

@ -462,8 +462,8 @@ void st_reset()
st_go_idle(); st_go_idle();
// Initialize stepper algorithm variables. // Initialize stepper algorithm variables.
memset(&prep, 0, sizeof(prep)); memset(&prep, 0, sizeof(st_prep_t));
memset(&st, 0, sizeof(st)); memset(&st, 0, sizeof(stepper_t));
st.exec_segment = NULL; st.exec_segment = NULL;
pl_block = NULL; // Planner block pointer used by segment buffer pl_block = NULL; // Planner block pointer used by segment buffer
segment_buffer_tail = 0; segment_buffer_tail = 0;