diff --git a/config.h b/config.h index ccba270..214c8e5 100644 --- a/config.h +++ b/config.h @@ -84,10 +84,26 @@ // parser state depending on user preferences. #define N_STARTUP_LINE 2 // Integer (1-3) -// Allows GRBL to tranck and report gcode line numbers. Enabling this means that the planning buffer +// Number of floating decimal points printed by Grbl for certain value types. These settings are +// determined by realistic and commonly values observed in CNC machines. For example, position +// values cannot be less than 0.001mm or 0.0001in, because machines are never more precise than +// this. So, there is likely no need to change these, but you can if you need to here. +// NOTE: Must be an integer value from 0 to ~4. More than 4 may exhibit round-off errors. +#define N_DECIMAL_COORDVALUE_INCH 4 // Coordinate or position value in inches +#define N_DECIMAL_COORDVALUE_MM 3 // Coordinate or position value in mm +#define N_DECIMAL_RATEVALUE_INCH 1 // Rate or velocity value in in/min +#define N_DECIMAL_RATEVALUE_MM 0 // Rate or velocity value in mm/min +#define N_DECIMAL_SETTINGVALUE 3 // Decimals for floating point setting values + +// Allows GRBL to track and report gcode line numbers. Enabling this means that the planning buffer // goes from 18 or 16 to make room for the additional line number data in the plan_block_t struct // #define USE_LINE_NUMBERS // Disabled by default. Uncomment to enable. +// Allows GRBL to report the real-time feed rate. Enabling this means that GRBL will be reporting more +// data with each status update. +// NOTE: This is experimental and doesn't quite work 100%. Maybe fixed or refactored later. +// #define REPORT_REALTIME_RATE // Disabled by default. Uncomment to enable. + // 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. // NOTE: The M8 flood coolant control pin on analog pin 4 will still be functional regardless. diff --git a/eeprom.h b/eeprom.h index cffbcde..d93deee 100644 --- a/eeprom.h +++ b/eeprom.h @@ -1,7 +1,7 @@ #ifndef eeprom_h #define eeprom_h -char eeprom_get_char(unsigned int addr); +unsigned char eeprom_get_char(unsigned int addr); void eeprom_put_char(unsigned int addr, unsigned char new_value); void memcpy_to_eeprom_with_checksum(unsigned int destination, char *source, unsigned int size); int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size); diff --git a/gcode.c b/gcode.c index 8557956..89e9756 100644 --- a/gcode.c +++ b/gcode.c @@ -634,7 +634,7 @@ uint8_t gc_execute_line(char *line) // Calculate the change in position along each selected axis float x = gc_block.values.xyz[axis_0]-gc_state.position[axis_0]; // Delta x between current position and target float y = gc_block.values.xyz[axis_1]-gc_state.position[axis_1]; // Delta y between current position and target - + if (value_words & bit(WORD_R)) { // Arc Radius Mode bit_false(value_words,bit(WORD_R)); if (gc_check_same_position(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target] diff --git a/print.c b/print.c index 6fe8c2d..a3c46cd 100644 --- a/print.c +++ b/print.c @@ -129,14 +129,14 @@ void printInteger(long n) // may be set by the user. The integer is then efficiently converted to a string. // NOTE: AVR '%' and '/' integer operations are very efficient. Bitshifting speed-up // techniques are actually just slightly slower. Found this out the hard way. -void printFloat(float n) +void printFloat(float n, uint8_t decimal_places) { if (n < 0) { serial_write('-'); n = -n; } - uint8_t decimals = settings.decimal_places; + uint8_t decimals = decimal_places; while (decimals >= 2) { // Quickly convert values expected to be E0 to E-4. n *= 100; decimals -= 2; @@ -148,16 +148,16 @@ void printFloat(float n) unsigned char buf[10]; uint8_t i = 0; uint32_t a = (long)n; - buf[settings.decimal_places] = '.'; // Place decimal point, even if decimal places are zero. + buf[decimal_places] = '.'; // Place decimal point, even if decimal places are zero. while(a > 0) { - if (i == settings.decimal_places) { i++; } // Skip decimal point location + if (i == decimal_places) { i++; } // Skip decimal point location buf[i++] = (a % 10) + '0'; // Get digit a /= 10; } - while (i < settings.decimal_places) { + while (i < decimal_places) { buf[i++] = '0'; // Fill in zeros to decimal point for (n < 1) } - if (i == settings.decimal_places) { // Fill in leading zero, if needed. + if (i == decimal_places) { // Fill in leading zero, if needed. i++; buf[i++] = '0'; } @@ -166,3 +166,27 @@ void printFloat(float n) for (; i > 0; i--) serial_write(buf[i-1]); } + + +// Floating value printing handlers for special variables types used in Grbl and are defined +// in the config.h. +// - CoordValue: Handles all position or coordinate values in inches or mm reporting. +// - RateValue: Handles feed rate and current velocity in inches or mm reporting. +// - SettingValue: Handles all floating point settings values (always in mm.) +void printFloat_CoordValue(float n) { + if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { + printFloat(n*INCH_PER_MM,N_DECIMAL_COORDVALUE_INCH); + } else { + printFloat(n,N_DECIMAL_COORDVALUE_MM); + } +} + +void printFloat_RateValue(float n) { + if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { + printFloat(n*INCH_PER_MM,N_DECIMAL_RATEVALUE_INCH); + } else { + printFloat(n,N_DECIMAL_RATEVALUE_MM); + } +} + +void printFloat_SettingValue(float n) { printFloat(n,N_DECIMAL_SETTINGVALUE); } diff --git a/print.h b/print.h index 273a554..616b98d 100644 --- a/print.h +++ b/print.h @@ -37,6 +37,16 @@ void print_uint8_base2(uint8_t n); void print_uint8_base10(uint8_t n); -void printFloat(float n); +void printFloat(float n, uint8_t decimal_places); + +// Floating value printing handlers for special variables types used in Grbl. +// - CoordValue: Handles all position or coordinate values in inches or mm reporting. +// - RateValue: Handles feed rate and current velocity in inches or mm reporting. +// - SettingValue: Handles all floating point settings values (always in mm.) +void printFloat_CoordValue(float n); + +void printFloat_RateValue(float n); + +void printFloat_SettingValue(float n); #endif \ No newline at end of file diff --git a/report.c b/report.c index bed9661..926593c 100644 --- a/report.c +++ b/report.c @@ -34,6 +34,7 @@ #include "coolant_control.h" #include "planner.h" #include "spindle_control.h" +#include "stepper.h" // Handles the primary confirmation protocol response for streaming interfaces and human-feedback. @@ -157,28 +158,27 @@ void report_grbl_help() { // Grbl global settings print out. // NOTE: The numbering scheme here must correlate to storing in settings.c void report_grbl_settings() { - printPgmString(PSTR("$0=")); printFloat(settings.steps_per_mm[X_AXIS]); - printPgmString(PSTR(" (x, step/mm)\r\n$1=")); printFloat(settings.steps_per_mm[Y_AXIS]); - printPgmString(PSTR(" (y, step/mm)\r\n$2=")); printFloat(settings.steps_per_mm[Z_AXIS]); - printPgmString(PSTR(" (z, step/mm)\r\n$3=")); printFloat(settings.max_rate[X_AXIS]); - printPgmString(PSTR(" (x max rate, mm/min)\r\n$4=")); printFloat(settings.max_rate[Y_AXIS]); - printPgmString(PSTR(" (y max rate, mm/min)\r\n$5=")); printFloat(settings.max_rate[Z_AXIS]); - printPgmString(PSTR(" (z max rate, mm/min)\r\n$6=")); printFloat(settings.acceleration[X_AXIS]/(60*60)); // Convert from mm/min^2 for human readability - printPgmString(PSTR(" (x accel, mm/sec^2)\r\n$7=")); printFloat(settings.acceleration[Y_AXIS]/(60*60)); // Convert from mm/min^2 for human readability - printPgmString(PSTR(" (y accel, mm/sec^2)\r\n$8=")); printFloat(settings.acceleration[Z_AXIS]/(60*60)); // Convert from mm/min^2 for human readability - printPgmString(PSTR(" (z accel, mm/sec^2)\r\n$9=")); printFloat(-settings.max_travel[X_AXIS]); // Grbl internally store this as negative. - printPgmString(PSTR(" (x max travel, mm)\r\n$10=")); printFloat(-settings.max_travel[Y_AXIS]); // Grbl internally store this as negative. - printPgmString(PSTR(" (y max travel, mm)\r\n$11=")); printFloat(-settings.max_travel[Z_AXIS]); // Grbl internally store this as negative. + printPgmString(PSTR("$0=")); printFloat_SettingValue(settings.steps_per_mm[X_AXIS]); + printPgmString(PSTR(" (x, step/mm)\r\n$1=")); printFloat_SettingValue(settings.steps_per_mm[Y_AXIS]); + printPgmString(PSTR(" (y, step/mm)\r\n$2=")); printFloat_SettingValue(settings.steps_per_mm[Z_AXIS]); + printPgmString(PSTR(" (z, step/mm)\r\n$3=")); printFloat_SettingValue(settings.max_rate[X_AXIS]); + printPgmString(PSTR(" (x max rate, mm/min)\r\n$4=")); printFloat_SettingValue(settings.max_rate[Y_AXIS]); + printPgmString(PSTR(" (y max rate, mm/min)\r\n$5=")); printFloat_SettingValue(settings.max_rate[Z_AXIS]); + printPgmString(PSTR(" (z max rate, mm/min)\r\n$6=")); printFloat_SettingValue(settings.acceleration[X_AXIS]/(60*60)); // Convert from mm/min^2 for human readability + printPgmString(PSTR(" (x accel, mm/sec^2)\r\n$7=")); printFloat_SettingValue(settings.acceleration[Y_AXIS]/(60*60)); // Convert from mm/min^2 for human readability + printPgmString(PSTR(" (y accel, mm/sec^2)\r\n$8=")); printFloat_SettingValue(settings.acceleration[Z_AXIS]/(60*60)); // Convert from mm/min^2 for human readability + printPgmString(PSTR(" (z accel, mm/sec^2)\r\n$9=")); printFloat_SettingValue(-settings.max_travel[X_AXIS]); // Grbl internally store this as negative. + printPgmString(PSTR(" (x max travel, mm)\r\n$10=")); printFloat_SettingValue(-settings.max_travel[Y_AXIS]); // Grbl internally store this as negative. + printPgmString(PSTR(" (y max travel, mm)\r\n$11=")); printFloat_SettingValue(-settings.max_travel[Z_AXIS]); // Grbl internally store this as negative. printPgmString(PSTR(" (z max travel, mm)\r\n$12=")); print_uint8_base10(settings.pulse_microseconds); printPgmString(PSTR(" (step pulse, usec)\r\n$13=")); print_uint8_base10(settings.step_invert_mask); printPgmString(PSTR(" (step port invert mask:")); print_uint8_base2(settings.step_invert_mask); printPgmString(PSTR(")\r\n$14=")); print_uint8_base10(settings.dir_invert_mask); printPgmString(PSTR(" (dir port invert mask:")); print_uint8_base2(settings.dir_invert_mask); printPgmString(PSTR(")\r\n$15=")); print_uint8_base10(settings.stepper_idle_lock_time); - printPgmString(PSTR(" (step idle delay, msec)\r\n$16=")); printFloat(settings.junction_deviation); - printPgmString(PSTR(" (junction deviation, mm)\r\n$17=")); printFloat(settings.arc_tolerance); - printPgmString(PSTR(" (arc tolerance, mm)\r\n$18=")); print_uint8_base10(settings.decimal_places); - printPgmString(PSTR(" (n-decimals, int)\r\n$19=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); + printPgmString(PSTR(" (step idle delay, msec)\r\n$16=")); printFloat_SettingValue(settings.junction_deviation); + printPgmString(PSTR(" (junction deviation, mm)\r\n$17=")); printFloat_SettingValue(settings.arc_tolerance); + printPgmString(PSTR(" (arc tolerance, mm)\r\n$19=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); printPgmString(PSTR(" (report inches, bool)\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_AUTO_START)); printPgmString(PSTR(" (auto start, bool)\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); printPgmString(PSTR(" (invert step enable, bool)\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); @@ -187,10 +187,10 @@ void report_grbl_settings() { printPgmString(PSTR(" (hard limits, bool)\r\n$25=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); printPgmString(PSTR(" (homing cycle, bool)\r\n$26=")); print_uint8_base10(settings.homing_dir_mask); printPgmString(PSTR(" (homing dir invert mask:")); print_uint8_base2(settings.homing_dir_mask); - printPgmString(PSTR(")\r\n$27=")); printFloat(settings.homing_feed_rate); - printPgmString(PSTR(" (homing feed, mm/min)\r\n$28=")); printFloat(settings.homing_seek_rate); + printPgmString(PSTR(")\r\n$27=")); printFloat_SettingValue(settings.homing_feed_rate); + printPgmString(PSTR(" (homing feed, mm/min)\r\n$28=")); printFloat_SettingValue(settings.homing_seek_rate); printPgmString(PSTR(" (homing seek, mm/min)\r\n$29=")); print_uint8_base10(settings.homing_debounce_delay); - printPgmString(PSTR(" (homing debounce, msec)\r\n$30=")); printFloat(settings.homing_pulloff); + printPgmString(PSTR(" (homing debounce, msec)\r\n$30=")); printFloat_SettingValue(settings.homing_pulloff); printPgmString(PSTR(" (homing pull-off, mm)\r\n")); } @@ -207,8 +207,7 @@ void report_probe_parameters() printPgmString(PSTR("[Probe:")); for (i=0; i< N_AXIS; i++) { print_position[i] = sys.probe_position[i]/settings.steps_per_mm[i]; - if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { print_position[i] *= INCH_PER_MM; } - printFloat(print_position[i]); + printFloat_CoordValue(print_position[i]); if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); } } printPgmString(PSTR("]\r\n")); @@ -233,16 +232,14 @@ void report_ngc_parameters() } printPgmString(PSTR(":")); for (i=0; i\r\n")); } diff --git a/settings.c b/settings.c index 5876da1..88df8ef 100644 --- a/settings.c +++ b/settings.c @@ -90,7 +90,6 @@ void settings_reset() { settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY; settings.homing_pulloff = DEFAULT_HOMING_PULLOFF; settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME; - settings.decimal_places = DEFAULT_DECIMAL_PLACES; settings.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL); settings.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL); settings.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL); @@ -181,7 +180,6 @@ uint8_t settings_store_global_setting(int parameter, float value) { case 15: settings.stepper_idle_lock_time = round(value); break; case 16: settings.junction_deviation = fabs(value); break; case 17: settings.arc_tolerance = value; break; - case 18: settings.decimal_places = round(value); break; case 19: if (value) { settings.flags |= BITFLAG_REPORT_INCHES; } else { settings.flags &= ~BITFLAG_REPORT_INCHES; } diff --git a/settings.h b/settings.h index 12bbba3..7d7d4fc 100644 --- a/settings.h +++ b/settings.h @@ -70,7 +70,6 @@ typedef struct { uint8_t stepper_idle_lock_time; // If max value 255, steppers do not disable. float junction_deviation; float arc_tolerance; - uint8_t decimal_places; uint8_t flags; // Contains default boolean settings uint8_t homing_dir_mask; float homing_feed_rate; diff --git a/stepper.c b/stepper.c index 58ec9c1..496f916 100644 --- a/stepper.c +++ b/stepper.c @@ -821,6 +821,21 @@ void st_prep_buffer() } } + +// Called by runtime status reporting to fetch the current speed being executed. This value +// however is not exactly the current speed, but the speed computed in the last step segment +// in the segment buffer. It will always be behind by up to the number of segment blocks (-1) +// divided by the ACCELERATION TICKS PER SECOND in seconds. +#ifdef REPORT_REALTIME_RATE +float st_get_realtime_rate() +{ + if (sys.state & (STATE_CYCLE | STATE_HOMING)){ + return prep.current_speed; + } + return 0.0f; +} +#endif + /* TODO: With feedrate overrides, increases to the override value will not significantly change the current planner and stepper operation. When the value increases, we simply diff --git a/stepper.h b/stepper.h index 1cc06d9..a9ea766 100644 --- a/stepper.h +++ b/stepper.h @@ -44,4 +44,9 @@ void st_prep_buffer(); // Called by planner_recalculate() when the executing block is updated by the new plan. void st_update_plan_block_parameters(); +// Called by runtime status reporting if realtime rate reporting is enabled in config.h. +#ifdef REPORT_REALTIME_RATE +float st_get_realtime_rate(); +#endif + #endif