Skip to content

Commit 5825b36

Browse files
committed
Fix for M62 - M68 regression. Ref. issue #600.
Fixed incorrect handling of G65 call parameters, axis words had offsets added. Ref. issue #594. Refactored handling of multiple spindles. There are still some limitations but should work better now. Disabled override delays for now, needs investigation. Ref. issue #598. NOTE: Please report any erratic behaviour after installing this version since it is a rather major change.
1 parent 323dd84 commit 5825b36

15 files changed

+367
-216
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa
1313

1414
---
1515

16-
Latest build date is 20240928, see the [changelog](changelog.md) for details.
16+
Latest build date is 20241006, see the [changelog](changelog.md) for details.
1717

1818
__NOTE:__ Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured.
1919
The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds.

changelog.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,33 @@
11
## grblHAL changelog
22

3+
<a name="2024106">Build 2024106
4+
5+
Core:
6+
7+
* Fix for `M62` - `M68` regression. Ref. [issue #600](https://github.com/grblHAL/core/issues/600).
8+
9+
* Fixed incorrect handling of `G65` call parameters, axis words had offsets added. Ref. [issue #594](https://github.com/grblHAL/core/issues/594).
10+
11+
* Refactored handling of multiple spindles. There are still some limitations but should work better now. Disabled override delays for now, needs investigation. Ref. [issue #598](https://github.com/grblHAL/core/issues/598).
12+
__NOTE:__ Please report any erratic behaviour after installing this version since it is a rather major change.
13+
14+
Drivers:
15+
16+
* ESP32: fix for compilation error. Ref. [issue #122](https://github.com/grblHAL/ESP32/issues/122).
17+
Fixes for handling multiple devices on a single SPI port. Fixed xPro v5 map for Modbus comms. Ref. [issue #121](https://github.com/grblHAL/ESP32/issues/121).
18+
19+
* STM32F4xx: fix for compilation error for some boards when configured for Trinamic drivers.
20+
21+
Plugins:
22+
23+
* BLTouch: implemented `$BLTEST` command, verified.
24+
25+
---
26+
327
<a name="20240928">Build 20240928
428

29+
Core:
30+
531
* Added `(PRINT, <msg>)` support and parameter formatting for `DEBUG` and `PRINT` commands. Available when expression support is enabled.
632

733
* Added named parameters for getting absolute \(G53\) position: `_abs_x`, `abs_y`, ... Available when expression support is enabled.

gcode.c

Lines changed: 265 additions & 152 deletions
Large diffs are not rendered by default.

gcode.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,17 @@ typedef struct {
498498
} gc_value_ptr_t;
499499

500500
typedef struct {
501+
float rpm; //!< Spindle speed
501502
spindle_state_t state; //!< {M3,M4,M5}
502503
spindle_rpm_mode_t rpm_mode; //!< {G96,G97}
503-
} spindle_mode_t;
504+
spindle_css_data_t *css; //!< Data used for Constant Surface Speed Mode calculations
505+
spindle_ptrs_t *hal; //!< Spindle function pointers etc. Must be last!
506+
} spindle_t;
507+
508+
typedef struct {
509+
spindle_state_t state; //!< {M3,M4,M5}
510+
spindle_rpm_mode_t rpm_mode; //!< {G96,G97}
511+
} spindle_modal_t;
504512

505513
// NOTE: When this struct is zeroed, the above defines set the defaults for the system.
506514
typedef struct {
@@ -519,7 +527,11 @@ typedef struct {
519527
#endif
520528
program_flow_t program_flow; //!< {M0,M1,M2,M30,M60}
521529
coolant_state_t coolant; //!< {M7,M8,M9}
522-
spindle_mode_t spindle; //!< {M3,M4,M5 and G96,G97}
530+
#if N_SYS_SPINDLE > 1
531+
spindle_t spindle[N_SYS_SPINDLE];
532+
#else
533+
spindle_t spindle; //!< {M3,M4,M5 and G96,G97}
534+
#endif
523535
gc_override_flags_t override_ctrl; //!< {M48,M49,M50,M51,M53,M56}
524536
cc_retract_mode_t retract_mode; //!< {G98,G99}
525537
bool scaling_active; //!< {G50,G51}
@@ -528,7 +540,6 @@ typedef struct {
528540
#if NGC_PARAMETERS_ENABLE
529541
bool auto_restore;
530542
float feed_rate; //!< {F} NOTE: only set when saving modal state
531-
float rpm; //!< {S} NOTE: only set when saving modal state
532543
#endif
533544
} gc_modal_t;
534545

@@ -575,20 +586,13 @@ typedef struct {
575586
tool_id_t tool_id; //!< Tool number
576587
} tool_data_t;
577588

578-
typedef struct {
579-
float rpm; //!< Spindle speed
580-
spindle_state_t state;
581-
spindle_css_data_t *css; //!< Data used for Constant Surface Speed Mode calculations
582-
spindle_ptrs_t *hal;
583-
} spindle_t;
584-
585589
/*! \brief Parser state
586590
587591
*/
588592
typedef struct {
589593
gc_modal_t modal;
590594
gc_canned_t canned;
591-
spindle_t spindle; //!< RPM
595+
spindle_t *spindle; //!< Last referenced spindle
592596
float feed_rate; //!< Millimeters/min
593597
float distance_per_rev; //!< Millimeters/rev
594598
float position[N_AXIS]; //!< Where the interpreter considers the tool to be at this point in the code
@@ -636,11 +640,11 @@ typedef struct {
636640
user_mcode_t user_mcode; //!< Set > #UserMCode_Ignore if a user M-code is found.
637641
bool user_mcode_sync; //!< Set to \a true by M-code validation handler if M-code is to be executed after synchronization.
638642
gc_modal_t modal; //!< The current modal state is copied here before parsing starts.
643+
spindle_modal_t spindle_modal;
639644
gc_values_t values; //!< Parameter values for block.
640645
parameter_words_t words; //!< Bitfield for tracking found parameter values.
641646
output_command_t output_command; //!< Details about M62-M68 output command to execute if present in block.
642647
uint32_t arc_turns; //
643-
spindle_ptrs_t *spindle; //!< Spindle to control, NULL for all
644648
#if NGC_PARAMETERS_ENABLE
645649
modal_state_action_t state_action; //!< M70-M73 modal state action
646650
#endif
@@ -676,7 +680,7 @@ float *gc_get_scaling (void);
676680
// Get current axis offset.
677681
float gc_get_offset (uint_fast8_t idx, bool real_time);
678682

679-
spindle_ptrs_t *gc_spindle_get (void);
683+
spindle_t *gc_spindle_get (spindle_num_t spindle);
680684

681685
void gc_spindle_off (void);
682686
void gc_coolant (coolant_state_t state);

grbl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
#else
4343
#define GRBL_VERSION "1.1f"
4444
#endif
45-
#define GRBL_BUILD 20240928
45+
#define GRBL_BUILD 20241006
4646

4747
#define GRBL_URL "https://github.com/grblHAL"
4848

motion_control.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ void mc_canned_drill (motion_mode_t motion, float *target, plan_line_data_t *pl_
627627
return;
628628

629629
if(canned->spindle_off)
630-
spindle_sync(pl_data->spindle.hal, gc_state.modal.spindle.state, pl_data->spindle.rpm);
630+
spindle_sync(pl_data->spindle.hal, pl_data->spindle.state, pl_data->spindle.rpm);
631631
}
632632

633633
pl_data->condition.rapid_motion = On; // Set rapid motion condition flag.

ngc_params.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -488,11 +488,11 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
488488
break;
489489

490490
case NGCParam_spindle_rpm_mode:
491-
value = gc_state.modal.spindle.rpm_mode == SpindleSpeedMode_RPM ? 1.0f : 0.0f;
491+
value = gc_spindle_get(0)->rpm_mode == SpindleSpeedMode_RPM ? 1.0f : 0.0f;
492492
break;
493493

494494
case NGCParam_spindle_css_mode:
495-
value = gc_state.modal.spindle.rpm_mode == SpindleSpeedMode_CSS ? 1.0f : 0.0f;
495+
value = gc_spindle_get(0)->rpm_mode == SpindleSpeedMode_CSS ? 1.0f : 0.0f;
496496
break;
497497

498498
case NGCParam_ijk_absolute_mode:
@@ -508,11 +508,11 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
508508
break;
509509

510510
case NGCParam_spindle_on:
511-
value = gc_state.modal.spindle.state.on ? 1.0f : 0.0f;
511+
value = gc_spindle_get(0)->state.on ? 1.0f : 0.0f;
512512
break;
513513

514514
case NGCParam_spindle_cw:
515-
value = gc_state.modal.spindle.state.ccw ? 1.0f : 0.0f;
515+
value = gc_spindle_get(0)->state.ccw ? 1.0f : 0.0f;
516516
break;
517517

518518
case NGCParam_mist:
@@ -544,7 +544,7 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
544544
break;
545545

546546
case NGCParam_rpm:
547-
value = gc_state.spindle.rpm;
547+
value = gc_spindle_get(0)->rpm;
548548
break;
549549

550550
case NGCParam_x:

planner.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ void plan_data_init (plan_line_data_t *plan_data)
691691
{
692692
memset(plan_data, 0, sizeof(plan_line_data_t));
693693
plan_data->offset_id = gc_state.offset_id;
694-
plan_data->spindle.hal = gc_state.spindle.hal ? gc_state.spindle.hal : spindle_get(0);
694+
plan_data->spindle.hal = gc_spindle_get(-1)->hal;
695695
plan_data->condition.target_validated = plan_data->condition.target_valid = sys.soft_limits.mask == 0;
696696
#ifdef KINEMATICS_API
697697
plan_data->rate_multiplier = 1.0f;

protocol.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,6 @@ bool protocol_exec_rt_system (void)
566566
sys.override.control = gc_state.modal.override_ctrl;
567567

568568
gc_state.tool_change = false;
569-
gc_state.modal.spindle.rpm_mode = SpindleSpeedMode_RPM;
570569

571570
// Tell driver/plugins about reset.
572571
hal.driver_reset();
@@ -684,7 +683,7 @@ bool protocol_exec_rt_system (void)
684683
if(!sys.override_delay.spindle && (rt_exec = get_spindle_override())) {
685684

686685
bool spindle_stop = false;
687-
spindle_ptrs_t *spindle = gc_spindle_get();
686+
spindle_ptrs_t *spindle = gc_spindle_get(-1)->hal;
688687
override_t last_s_override = spindle->param->override_pct;
689688

690689
do {
@@ -727,7 +726,7 @@ bool protocol_exec_rt_system (void)
727726

728727
spindle_set_override(spindle, last_s_override);
729728

730-
if (spindle_stop && state_get() == STATE_HOLD && gc_state.modal.spindle.state.on) {
729+
if (spindle_stop && state_get() == STATE_HOLD && gc_spindle_get(-1)->state.on) {
731730
// Spindle stop override allowed only while in HOLD state.
732731
// NOTE: Report flag is set in spindle_set_state() when spindle stop is executed.
733732
if (!sys.override.spindle_stop.value)

report.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -724,8 +724,8 @@ void report_gcode_modes (void)
724724
hal.stream.write(" G");
725725
hal.stream.write(uitoa((uint32_t)(93 + (gc_state.modal.feed_mode == FeedMode_UnitsPerRev ? 2 : gc_state.modal.feed_mode ^ 1))));
726726

727-
if(settings.mode == Mode_Lathe && gc_spindle_get()->cap.variable)
728-
hal.stream.write(gc_state.modal.spindle.rpm_mode == SpindleSpeedMode_RPM ? " G97" : " G96");
727+
if(settings.mode == Mode_Lathe && gc_spindle_get(0)->hal->cap.variable)
728+
hal.stream.write(gc_spindle_get(0)->rpm_mode == SpindleSpeedMode_RPM ? " G97" : " G96");
729729

730730
#if COMPATIBILITY_LEVEL < 10
731731

@@ -777,7 +777,7 @@ void report_gcode_modes (void)
777777
}
778778
}
779779

780-
hal.stream.write(gc_state.modal.spindle.state.on ? (gc_state.modal.spindle.state.ccw ? " M4" : " M3") : " M5");
780+
hal.stream.write(gc_spindle_get(0)->state.on ? (gc_spindle_get(0)->state.ccw ? " M4" : " M3") : " M5");
781781

782782
if(gc_state.tool_change)
783783
hal.stream.write(" M6");
@@ -809,8 +809,8 @@ void report_gcode_modes (void)
809809

810810
hal.stream.write(appendbuf(2, " F", get_rate_value(gc_state.feed_rate)));
811811

812-
if(gc_spindle_get()->cap.variable)
813-
hal.stream.write(appendbuf(2, " S", ftoa(gc_state.spindle.rpm, N_DECIMAL_RPMVALUE)));
812+
if(gc_spindle_get(0)->hal->cap.variable)
813+
hal.stream.write(appendbuf(2, " S", ftoa(gc_spindle_get(0)->rpm, N_DECIMAL_RPMVALUE)));
814814

815815
hal.stream.write("]" ASCII_EOL);
816816
}
@@ -1450,12 +1450,13 @@ void report_realtime_status (void)
14501450
static gc_modal_t last_state;
14511451
static bool g92_active;
14521452

1453-
bool is_changed = feed_rate != gc_state.feed_rate || spindle_rpm != gc_state.spindle.rpm || tool_id != gc_state.tool->tool_id;
1453+
spindle_t *spindle = gc_spindle_get(0);
1454+
bool is_changed = feed_rate != gc_state.feed_rate || spindle_rpm != spindle->rpm || tool_id != gc_state.tool->tool_id;
14541455

14551456
if(is_changed) {
14561457
feed_rate = gc_state.feed_rate;
14571458
tool_id = gc_state.tool->tool_id;
1458-
spindle_rpm = gc_state.spindle.rpm;
1459+
spindle_rpm = spindle->rpm;
14591460
} else if ((is_changed = g92_active != is_g92_active()))
14601461
g92_active = !g92_active;
14611462
else if(memcmp(&last_state, &gc_state.modal, sizeof(gc_modal_t))) {
@@ -2199,12 +2200,12 @@ status_code_t report_current_home_signal_state (sys_state_t state, char *args)
21992200
// Prints spindle data (encoder pulse and index count, angular position).
22002201
status_code_t report_spindle_data (sys_state_t state, char *args)
22012202
{
2202-
spindle_ptrs_t *spindle = gc_spindle_get();
2203+
spindle_t *spindle = gc_spindle_get(-1);
22032204

2204-
if(spindle->get_data) {
2205+
if(spindle->hal->get_data) {
22052206

2206-
float apos = spindle->get_data(SpindleData_AngularPosition)->angular_position;
2207-
spindle_data_t *data = spindle->get_data(SpindleData_Counters);
2207+
float apos = spindle->hal->get_data(SpindleData_AngularPosition)->angular_position;
2208+
spindle_data_t *data = spindle->hal->get_data(SpindleData_Counters);
22082209

22092210
hal.stream.write("[SPINDLEENCODER:");
22102211
hal.stream.write(uitoa(data->index_count));
@@ -2217,7 +2218,7 @@ status_code_t report_spindle_data (sys_state_t state, char *args)
22172218
hal.stream.write("]" ASCII_EOL);
22182219
}
22192220

2220-
return spindle->get_data ? Status_OK : Status_InvalidStatement;
2221+
return spindle->hal->get_data ? Status_OK : Status_InvalidStatement;
22212222
}
22222223

22232224
// Prints info about registered pins.

sleep.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ void sleep_check (void)
7575
// has any powered components enabled.
7676
// NOTE: With overrides or in laser mode, modal spindle and coolant state are not guaranteed. Need
7777
// to directly monitor and record running state during parking to ensure proper function.
78-
if (!(slumber || sys.steppers_deenergize || sys.flags.auto_reporting) && (gc_state.modal.spindle.state.value || gc_state.modal.coolant.value)) {
78+
if (!(slumber || sys.steppers_deenergize || sys.flags.auto_reporting) && (gc_spindle_get(0)->state.value || gc_state.modal.coolant.value)) {
7979
switch(state_get()) {
8080

8181
case STATE_IDLE:

spindle_control.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -510,19 +510,22 @@ void spindle_set_override (spindle_ptrs_t *spindle, override_t speed_override)
510510

511511
speed_override = constrain(speed_override, MIN_SPINDLE_RPM_OVERRIDE, MAX_SPINDLE_RPM_OVERRIDE);
512512

513-
if ((uint8_t)speed_override != spindle->param->override_pct) {
513+
if((uint8_t)speed_override != spindle->param->override_pct) {
514514

515-
spindle->param->override_pct = speed_override;
515+
spindle_set_rpm(spindle, spindle->param->rpm, speed_override);
516516

517-
if(state_get() == STATE_IDLE)
518-
spindle_set_state(spindle, gc_state.modal.spindle.state, gc_state.spindle.rpm);
519-
else
517+
if(state_get() == STATE_IDLE) {
518+
if(spindle->get_pwm && spindle->update_pwm)
519+
spindle->update_pwm(spindle, spindle->get_pwm(spindle, spindle->param->rpm_overridden));
520+
else if(spindle->update_rpm)
521+
spindle->update_rpm(spindle, spindle->param->rpm_overridden);
522+
} else
520523
sys.step_control.update_spindle_rpm = On;
521524

522525
system_add_rt_report(Report_Overrides); // Set to report change immediately
523526

524-
if(grbl.on_spindle_programmed)
525-
grbl.on_spindle_programmed(spindle, gc_state.modal.spindle.state, spindle_set_rpm(spindle, gc_state.spindle.rpm, speed_override), gc_state.modal.spindle.rpm_mode);
527+
// if(grbl.on_spindle_programmed)
528+
// grbl.on_spindle_programmed(spindle, spindle->param->state, spindle->param->rpm, spindle->param->rpm_mode);
526529

527530
if(grbl.on_override_changed)
528531
grbl.on_override_changed(OverrideChanged_SpindleRPM);
@@ -542,17 +545,20 @@ static bool set_state (spindle_ptrs_t *spindle, spindle_state_t state, float rpm
542545
if (!ABORTED) { // Block during abort.
543546

544547
if (!state.on) { // Halt or set spindle direction and rpm.
545-
spindle->param->rpm = rpm = 0.0f;
548+
rpm = 0.0f;
546549
spindle->set_state(spindle, (spindle_state_t){0}, 0.0f);
547550
} else {
548-
// NOTE: Assumes all calls to this function is when Grbl is not moving or must remain off.
551+
// NOTE: Assumes all calls to this function is when grblHAL is not moving or must remain off.
549552
// TODO: alarm/interlock if going from CW to CCW directly in non-laser mode?
550553
if (spindle->cap.laser && state.ccw)
551554
rpm = 0.0f; // TODO: May need to be rpm_min*(100/MAX_SPINDLE_RPM_OVERRIDE);
552555

553556
spindle->set_state(spindle, state, spindle_set_rpm(spindle, rpm, spindle->param->override_pct));
554557
}
555558

559+
spindle->param->rpm = rpm;
560+
spindle->param->state = state;
561+
556562
system_add_rt_report(Report_Spindle); // Set to report change immediately
557563

558564
st_rpm_changed(rpm);

0 commit comments

Comments
 (0)