diff --git a/README.md b/README.md index a478954..5aff7e8 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa --- -Latest build date is 20221101, see the [changelog](changelog.md) for details. +Latest build date is 20221115, see the [changelog](changelog.md) for details. __NOTE:__ A settings reset will be performed on an update for versions earlier than 20211122. Backup and restore of settings is recommended. __IMPORTANT!__ A new setting has been introduced for ganged axes motors in version 20211121. I have only bench tested this for a couple of drivers, correct function should be verified after updating by those who have more than three motors configured. diff --git a/changelog.md b/changelog.md index 54a9c41..65a5a2a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,24 @@ ## grblHAL changelog +Build 20221115 + +Core: + +* Updated settings reports to output correct units and descriptions for settings related to axes configured as rotary. +__Note:__ Senders may have to be restarted to display these after a configuration change \($376 - rotatational axes\) and even then they might not display them correctly. + +* Internal change to allow flagging settings to have a minimum value or length different from 0 and still allow to them to be 0 or have length 0. + +Plugins: + +* Some: updated for core settings change. + +Drivers: + +* Some: updated for core settings change. + +--- + Build 20221101 Core: @@ -396,7 +415,7 @@ __Note:__ NVS storage of settings has been moved to the end of flash, backup and Core: -* Addded virtual file system \(VFS\) handler, Linux/Unix style with mount directories. +* Added virtual file system \(VFS\) handler, Linux/Unix style with mount directories. * Now raises alarm if homed state becomes invalid on settings changes when homing on startup is required. Issue #173. Plugins: diff --git a/grbl.h b/grbl.h index c305d27..e2b475a 100644 --- a/grbl.h +++ b/grbl.h @@ -38,7 +38,7 @@ #else #define GRBL_VERSION "1.1f" #endif -#define GRBL_BUILD 20221101 +#define GRBL_BUILD 20221115 #define GRBL_URL "https://github.com/grblHAL" diff --git a/nuts_bolts.c b/nuts_bolts.c index c55dbcb..ceab01e 100644 --- a/nuts_bolts.c +++ b/nuts_bolts.c @@ -42,17 +42,17 @@ static char buf[STRLEN_COORDVALUE + 1]; static const float froundvalues[MAX_PRECISION + 1] = { - 0.5, // 0 - 0.05, // 1 - 0.005, // 2 - 0.0005, // 3 - 0.00005, // 4 - 0.000005, // 5 - 0.0000005, // 6 - 0.00000005, // 7 - 0.000000005, // 8 - 0.0000000005, // 9 - 0.00000000005 // 10 + 0.5f, // 0 + 0.05f, // 1 + 0.005f, // 2 + 0.0005f, // 3 + 0.00005f, // 4 + 0.000005f, // 5 + 0.0000005f, // 6 + 0.00000005f, // 7 + 0.000000005f, // 8 + 0.0000000005f, // 9 + 0.00000000005f // 10 }; #if N_AXIS > 6 && defined(AXIS_REMAP_ABC2UVW) diff --git a/report.c b/report.c index de5f3cf..55ec566 100644 --- a/report.c +++ b/report.c @@ -1504,13 +1504,13 @@ static void report_settings_detail (settings_format_t format, const setting_deta } } - if(setting->reboot_required) + if(setting->flags.reboot_required) hal.stream.write(", reboot required"); #ifndef NO_SETTINGS_DESCRIPTIONS // Add description if driver is capable of outputting it... if(hal.stream.write_n) { - const char *description = setting_get_description(setting->id); + const char *description = setting_get_description(setting->id + offset); if(description && *description != '\0') { char *lf; hal.stream.write(ASCII_EOL); @@ -1525,7 +1525,7 @@ static void report_settings_detail (settings_format_t format, const setting_deta hal.stream.write(description); } } - if(setting->reboot_required) { + if(setting->flags.reboot_required) { if(description && *description != '\0') hal.stream.write(ASCII_EOL ASCII_EOL); hal.stream.write(SETTINGS_HARD_RESET_REQUIRED + 4); @@ -1558,7 +1558,7 @@ static void report_settings_detail (settings_format_t format, const setting_deta if(setting->max_value) hal.stream.write(setting->max_value); hal.stream.write(vbar); - hal.stream.write(uitoa(setting->reboot_required)); + hal.stream.write(uitoa(setting->flags.reboot_required)); hal.stream.write("]"); break; @@ -1676,7 +1676,7 @@ static void report_settings_detail (settings_format_t format, const setting_deta #ifndef NO_SETTINGS_DESCRIPTIONS const char *description = setting_get_description((setting_id_t)(setting->id + offset)); hal.stream.write(description ? description : ""); - if(setting->reboot_required) + if(setting->flags.reboot_required) hal.stream.write(SETTINGS_HARD_RESET_REQUIRED + (description && *description != '\0' ? 0 : 4)); #endif hal.stream.write("\t"); @@ -1691,7 +1691,7 @@ static void report_settings_detail (settings_format_t format, const setting_deta hal.stream.write("\t"); - hal.stream.write(uitoa(setting->reboot_required)); + hal.stream.write(uitoa(setting->flags.reboot_required)); } break; } @@ -1816,7 +1816,7 @@ status_code_t report_setting_description (settings_format_t format, setting_id_t } // hal.stream.write(description == NULL ? (is_setting_available(setting_get_details(id, NULL)) ? "" : "N/A") : description); // TODO? hal.stream.write(description ? description : (setting ? "" : "N/A")); - if(setting && setting->reboot_required) + if(setting && setting->flags.reboot_required) hal.stream.write(SETTINGS_HARD_RESET_REQUIRED + (description && *description != '\0' ? 0 : 4)); if(format == SettingsFormat_MachineReadable) diff --git a/settings.c b/settings.c index 2ff7b59..4f01f17 100644 --- a/settings.c +++ b/settings.c @@ -413,6 +413,10 @@ static char spindle_signals[] = "Spindle enable,Spindle direction,PWM"; static char coolant_signals[] = "Flood,Mist"; static char ganged_axes[] = "X-Axis,Y-Axis,Z-Axis"; static char spindle_types[100] = ""; +static char axis_dist[4] = "mm"; +static char axis_rate[8] = "mm/min"; +static char axis_accel[10] = "mm/sec^2"; +static char axis_steps[9] = "step/mm"; PROGMEM static const setting_detail_t setting_detail[] = { { Setting_PulseMicroseconds, Group_Stepper, "Step pulse time", "microseconds", Format_Decimal, "#0.0", "2.0", NULL, Setting_IsLegacy, &settings.steppers.pulse_microseconds, NULL, NULL }, @@ -520,12 +524,12 @@ PROGMEM static const setting_detail_t setting_detail[] = { { Setting_PositionIGain, Group_Spindle_Sync, "Spindle sync I-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.i_gain, NULL, is_group_available }, { Setting_PositionDGain, Group_Spindle_Sync, "Spindle sync D-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.d_gain, NULL, is_group_available }, { Setting_PositionIMaxError, Group_Spindle_Sync, "Spindle sync PID max I error", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.i_max_error, NULL, is_group_available }, - { Setting_AxisStepsPerMM, Group_Axis0, "?-axis travel resolution", "step/mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, - { Setting_AxisMaxRate, Group_Axis0, "?-axis maximum rate", "mm/min", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, - { Setting_AxisAcceleration, Group_Axis0, "?-axis acceleration", "mm/sec^2", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, - { Setting_AxisMaxTravel, Group_Axis0, "?-axis maximum travel", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, + { Setting_AxisStepsPerMM, Group_Axis0, "?-axis travel resolution", axis_steps, Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, + { Setting_AxisMaxRate, Group_Axis0, "?-axis maximum rate", axis_rate, Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, + { Setting_AxisAcceleration, Group_Axis0, "?-axis acceleration", axis_accel, Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, + { Setting_AxisMaxTravel, Group_Axis0, "?-axis maximum travel", axis_dist, Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, #ifdef ENABLE_BACKLASH_COMPENSATION - { Setting_AxisBacklash, Group_Axis0, "?-axis backlash compensation", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtendedFn, set_axis_setting, get_float, NULL }, + { Setting_AxisBacklash, Group_Axis0, "?-axis backlash compensation", axis_dist, Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtendedFn, set_axis_setting, get_float, NULL }, #endif { Setting_AxisAutoSquareOffset, Group_Axis0, "?-axis dual axis offset", "mm", Format_Decimal, "-0.000", "-10", "10", Setting_IsExtendedFn, set_axis_setting, get_float, is_setting_available }, { Setting_SpindleAtSpeedTolerance, Group_Spindle, "Spindle at speed tolerance", "percent", Format_Decimal, "##0.0", NULL, NULL, Setting_IsExtended, &settings.spindle.at_speed_tolerance, NULL, is_setting_available }, @@ -569,7 +573,7 @@ PROGMEM static const setting_detail_t setting_detail[] = { { Setting_SpindleOnDelay, Group_Spindle, "Spindle on delay", "s", Format_Decimal, "#0.0", "0.5", "20", Setting_IsExtended, &settings.safety_door.spindle_on_delay, NULL, is_setting_available }, { Setting_SpindleType, Group_Spindle, "Default spindle", NULL, Format_RadioButtons, spindle_types, NULL, NULL, Setting_IsExtendedFn, set_spindle_type, get_int, is_setting_available }, #ifdef BLOCK_BUFFER_DYNAMIC - { Setting_PlannerBlocks, Group_General, "Planner buffer blocks", NULL, Format_Int16, "####0", "30", "1000", Setting_IsExtended, &settings.planner_buffer_blocks, NULL, NULL, true }, + { Setting_PlannerBlocks, Group_General, "Planner buffer blocks", NULL, Format_Int16, "####0", "30", "1000", Setting_IsExtended, &settings.planner_buffer_blocks, NULL, NULL, { .reboot_required = On } }, #endif }; @@ -686,6 +690,7 @@ PROGMEM static const setting_descr_t setting_descr[] = { { Setting_PositionDGain, "" }, { Setting_PositionIMaxError, "Spindle sync PID max integrator error." }, { Setting_AxisStepsPerMM, "Travel resolution in steps per millimeter." }, + { Setting_AxisStepsPerMM + 1, "Travel resolution in steps per degree." }, // "Hack" to get correct description for rotary axes { Setting_AxisMaxRate, "Maximum rate. Used as G0 rapid rate." }, { Setting_AxisAcceleration, "Acceleration. Used for motion planning to not exceed motor torque and lose steps." }, { Setting_AxisMaxTravel, "Maximum axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances." }, @@ -2062,6 +2067,39 @@ setting_group_t settings_get_parent_group (setting_group_t group) } */ +static inline bool axis_is_rotary (uint_fast8_t axis_idx) +{ + return bit_istrue(settings.steppers.is_rotational.mask, bit(axis_idx)); +} + +static void set_axis_setting_unit (const setting_detail_t *setting, uint_fast8_t axis_idx) +{ + bool is_rotary = axis_is_rotary(axis_idx); + + switch(setting->id) { + + case Setting_AxisStepsPerMM: + strcpy((char *)setting->unit, is_rotary ? "step/deg" : "step/mm"); + break; + + case Setting_AxisMaxRate: + strcpy((char *)setting->unit, is_rotary ? "deg/min" : "mm/min"); + break; + + case Setting_AxisAcceleration: + strcpy((char *)setting->unit, is_rotary ? "deg/sec^2" : "mm/sec^2"); + break; + + case Setting_AxisMaxTravel: + case Setting_AxisBacklash: + strcpy((char *)setting->unit, is_rotary ? "deg" : "mm"); + break; + + default: + break; + } +} + bool settings_iterator (const setting_detail_t *setting, setting_output_ptr callback, void *data) { bool ok = false; @@ -2089,6 +2127,7 @@ bool settings_iterator (const setting_detail_t *setting, setting_output_ptr call { uint_fast8_t axis_idx = 0; for(axis_idx = 0; axis_idx < N_AXIS; axis_idx++) { + set_axis_setting_unit(setting, axis_idx); if(callback(setting, axis_idx, data)) ok = true; } @@ -2126,6 +2165,8 @@ const setting_detail_t *setting_get_details (setting_id_t id, setting_details_t do { for(idx = 0; idx < details->n_settings; idx++) { if(details->settings[idx].id == id && is_available(&details->settings[idx])) { + if(details->settings[idx].group == Group_Axis0) + set_axis_setting_unit(&details->settings[idx], offset); if(offset && offset >= (details->settings[idx].group == Group_Encoder0 ? hal.encoder.get_n_encoders() : N_AXIS)) return NULL; if(set) @@ -2152,8 +2193,11 @@ const char *setting_get_description (setting_id_t id) if(settings->descriptions) { idx = settings->n_descriptions; do { - if(settings->descriptions[--idx].id == setting->id) + if(settings->descriptions[--idx].id == setting->id) { + if(setting->id == Setting_AxisStepsPerMM && axis_is_rotary(id - setting->id)) + idx++; description = settings->descriptions[idx].description; + } } while(idx && description == NULL); } } while(description == NULL && (settings = settings->next)); @@ -2188,13 +2232,13 @@ static status_code_t validate_value (const setting_detail_t *setting, float valu if(!read_float((char *)setting->min_value, &set_idx, &val)) return Status_BadNumberFormat; - if(value < val) + if(!(value >= val || (setting->flags.allow_null && value == 0.0f))) return Status_SettingValueOutOfRange; } else if(value < 0.0f) return Status_NegativeValue; - if (setting->max_value) { + if(setting->max_value) { set_idx = 0; if(!read_float((char *)setting->max_value, &set_idx, &val)) diff --git a/settings.h b/settings.h index 3bfd268..1f97541 100644 --- a/settings.h +++ b/settings.h @@ -714,6 +714,15 @@ typedef union { float fvalue; } setting_limit_t; +typedef union { + uint8_t value; + struct { + uint8_t reboot_required :1, + allow_null: 1, + unused :6; + }; +} setting_detail_flags_t; + typedef struct setting_detail { setting_id_t id; setting_group_t group; @@ -727,7 +736,7 @@ typedef struct setting_detail { void *value; void *get_value; bool (*is_available)(const struct setting_detail *setting); - bool reboot_required; + setting_detail_flags_t flags; } setting_detail_t; typedef struct {