Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem: _current_tool values when using M6 Macro #1422

Open
xspy69 opened this issue Jan 2, 2025 · 23 comments
Open

Problem: _current_tool values when using M6 Macro #1422

xspy69 opened this issue Jan 2, 2025 · 23 comments

Comments

@xspy69
Copy link

xspy69 commented Jan 2, 2025

Wiki Search Terms

atc / M6 / M61Q

Controller Board

6x controller

Machine Description

CNC router XYYZ, external drivers, VFD, Laser

Input Circuits

No response

Configuration file

board: 6x CNC Controller
name: 6x CNC Controller
arc_tolerance_mm: 0.002
junction_deviation_mm: 0.01
verbose_errors: false
report_inches: false
enable_parking_override_control: false
use_line_numbers: false
planner_blocks: 16
start:
  must_home: false
  deactivate_parking: false
  check_limits: true
stepping:
  engine: I2S_STATIC
  idle_ms: 255
  pulse_us: 4
  dir_delay_us: 4
  disable_delay_us: 0
  segments: 6
axes:
  shared_stepper_disable_pin: i2so.0
  homing_runs: 2
  x:
    steps_per_mm: 200
    max_rate_mm_per_min: 8000
    acceleration_mm_per_sec2: 500
    max_travel_mm: 645
    soft_limits: true
    homing:
      cycle: 2
      positive_direction: false
      mpos_mm: -645
      seek_mm_per_min: 1500
      feed_mm_per_min: 250
      seek_scaler: 1.1
      feed_scaler: 1.1
    motor0:
      limit_all_pin: gpio.2:pu
      hard_limits: true
      pulloff_mm: 2
      standard_stepper:
        step_pin: i2so.2
        direction_pin: i2so.1
        disable_pin: NO_PIN
      limit_neg_pin: NO_PIN
      limit_pos_pin: NO_PIN
  y:
    steps_per_mm: 200
    max_rate_mm_per_min: 8000
    acceleration_mm_per_sec2: 500
    max_travel_mm: 735
    soft_limits: true
    homing:
      cycle: 2
      positive_direction: false
      mpos_mm: -735
      seek_mm_per_min: 1500
      feed_mm_per_min: 250
      settle_ms: 500
      seek_scaler: 1.5
      feed_scaler: 1.5
    motor0:
      limit_all_pin: gpio.33:pu
      hard_limits: true
      pulloff_mm: 1
      standard_stepper:
        step_pin: i2so.5
        direction_pin: i2so.4:low
        disable_pin: NO_PIN
      limit_neg_pin: NO_PIN
      limit_pos_pin: NO_PIN
    motor1:
      limit_all_pin: gpio.26:pu
      standard_stepper:
        step_pin: i2so.10
        direction_pin: i2so.9:low
        disable_pin: NO_PIN
      limit_neg_pin: NO_PIN
      limit_pos_pin: NO_PIN
      pulloff_mm: 3
      hard_limits: true
  z:
    steps_per_mm: 200
    max_rate_mm_per_min: 4000
    acceleration_mm_per_sec2: 500
    max_travel_mm: 115
    soft_limits: true
    homing:
      cycle: 1
      positive_direction: true
      mpos_mm: 0
      seek_mm_per_min: 1500
      feed_mm_per_min: 250
      seek_scaler: 1.1
      feed_scaler: 1.1
    motor0:
      limit_all_pin: gpio.32
      hard_limits: true
      pulloff_mm: 1
      standard_stepper:
        step_pin: i2so.13
        direction_pin: i2so.12:low
        disable_pin: NO_PIN
      limit_neg_pin: NO_PIN
      limit_pos_pin: NO_PIN
probe:
  pin: gpio.34:low
  toolsetter_pin: gpio.35
  check_mode_start: false
  hard_stop: false
10V:
  forward_pin: gpio.15
  reverse_pin: gpio.14
  pwm_hz: 5000
  output_pin: gpio.13
  enable_pin: NO_PIN
  direction_pin: NO_PIN
  disable_with_s0: false
  s0_with_disable: true
  spinup_ms: 0
  spindown_ms: 0
  tool_num: 0
  speed_map: 0=0.000% 1700=7.000% 2400=10.000% 6000=24.390% 12000=48.387% 24000=100.000%
  off_on_alarm: false
  m6_macro: $SD/Run=tc.nc
atc_manual:
  safe_z_mpos_mm: -2
  probe_seek_rate_mm_per_min: 400
  probe_feed_rate_mm_per_min: 80
  change_mpos_mm: 80.000 2.000 -2.000
  ets_mpos_mm: 25.000 25.000 -40.000
  ets_rapid_z_mpos_mm: -25
Laser:
  pwm_hz: 5000
  output_pin: gpio.4:pu
  enable_pin: NO_PIN
  disable_with_s0: false
  s0_with_disable: true
  tool_num: 50
  speed_map: 0=0.000% 255=100.000%
  off_on_alarm: true
sdcard:
  card_detect_pin: NO_PIN
  cs_pin: gpio.5
i2so:
  bck_pin: gpio.22
  data_pin: gpio.21
  ws_pin: gpio.17
spi:
  miso_pin: gpio.19
  mosi_pin: gpio.23
  sck_pin: gpio.18
uart1:
  txd_pin: gpio.25
  rxd_pin: gpio.27
  rts_pin: NO_PIN
  cts_pin: NO_PIN
  baud: 1000000
  mode: 8N1
uart_channel1:
  report_interval_ms: 75
  uart_num: 1
coolant:
  flood_pin: i2so.20
  mist_pin: gpio.12
  delay_ms: 0
parking:
  enable: true
  axis: Z
  pullout_distance_mm: 5
  pullout_rate_mm_per_min: 250
  target_mpos_mm: -5
  rate_mm_per_min: 800
control:
  macro0_pin: NO_PIN
  safety_door_pin: gpio.39:low
  reset_pin: NO_PIN
  feed_hold_pin: NO_PIN
  cycle_start_pin: gpio.36:low
  macro1_pin: NO_PIN
  macro2_pin: NO_PIN
  macro3_pin: NO_PIN
  fault_pin: NO_PIN
  estop_pin: NO_PIN
macros:
  startup_line0: $SD/Run=init_atc.nc

Startup Messages

[10:54:21] [ $ss ] [MSG:INFO: FluidNC v3.9.3 https://github.com/bdring/FluidNC]

[10:54:21] [ $ss ] [MSG:INFO: Compiled with ESP32 SDK:v4.4.7-dirty]

[10:54:21] [ $ss ] [MSG:INFO: Local filesystem type is littlefs]

[10:54:21] [ $ss ] [MSG:INFO: Configuration file:Roxyz rev0.yaml]

[10:54:21] [ $ss ] [MSG:DBG: Running after-parse tasks]

[10:54:21] [ $ss ] [MSG:DBG: Checking configuration]

[10:54:21] [ $ss ] [MSG:INFO: Machine 6x CNC Controller]

[10:54:21] [ $ss ] [MSG:INFO: Board 6x CNC Controller]

[10:54:21] [ $ss ] [MSG:INFO: UART1 Tx:gpio.25 Rx:gpio.27 RTS:NO_PIN Baud:1000000]

[10:54:22] [ $ss ] [MSG:INFO: uart_channel1 created at report interval: 75]

[10:54:22] [ $ss ] [MSG:INFO: I2SO BCK:gpio.22 WS:gpio.17 DATA:gpio.21]

[10:54:22] [ $ss ] [MSG:INFO: SPI SCK:gpio.18 MOSI:gpio.23 MISO:gpio.19]

[10:54:22] [ $ss ] [MSG:INFO: SD Card cs_pin:gpio.5 detect:NO_PIN freq:8000000]

[10:54:22] [ $ss ] [MSG:INFO: Stepping:I2S_STATIC Pulse:4us Dsbl Delay:0us Dir Delay:4us Idle Delay:255ms]

[10:54:22] [ $ss ] [MSG:INFO: Axis count 3]

[10:54:22] [ $ss ] [MSG:INFO: Shared stepper disable I2SO.0]

[10:54:22] [ $ss ] [MSG:INFO: Axis X (-645.000,0.000)]

[10:54:22] [ $ss ] [MSG:INFO: Motor0]

[10:54:22] [ $ss ] [MSG:INFO: standard_stepper Step:I2SO.2 Dir:I2SO.1 Disable:NO_PIN]

[10:54:22] [ $ss ] [MSG:INFO: X All Limit gpio.2:pu]

[10:54:22] [ $ss ] [MSG:INFO: Axis Y (-735.000,0.000)]

[10:54:22] [ $ss ] [MSG:INFO: Motor0]

[10:54:22] [ $ss ] [MSG:INFO: standard_stepper Step:I2SO.5 Dir:I2SO.4:low Disable:NO_PIN]

[10:54:22] [ $ss ] [MSG:INFO: Y All Limit gpio.33:pu]

[10:54:22] [ $ss ] [MSG:INFO: Motor1]

[10:54:22] [ $ss ] [MSG:INFO: standard_stepper Step:I2SO.10 Dir:I2SO.9:low Disable:NO_PIN]

[10:54:22] [ $ss ] [MSG:INFO: Y2 All Limit gpio.26:pu]

[10:54:22] [ $ss ] [MSG:INFO: Axis Z (-115.000,0.000)]

[10:54:22] [ $ss ] [MSG:INFO: Motor0]

[10:54:22] [ $ss ] [MSG:INFO: standard_stepper Step:I2SO.13 Dir:I2SO.12:low Disable:NO_PIN]

[10:54:22] [ $ss ] [MSG:INFO: Z All Limit gpio.32]

[10:54:22] [ $ss ] [MSG:INFO: safety_door_pin gpio.39:low]

[10:54:22] [ $ss ] [MSG:INFO: cycle_start_pin gpio.36:low]

[10:54:22] [ $ss ] [MSG:INFO: Kinematic system: Cartesian]

[10:54:22] [ $ss ] [MSG:INFO: Connecting to STA SSID:Sys_Workshop]

[10:54:22] [ $ss ] [MSG:INFO: Connecting.]

[10:54:22] [ $ss ] [MSG:INFO: Connecting..]

[10:54:22] [ $ss ] [MSG:INFO: Connected - IP is 192.168.0.36]

[10:54:22] [ $ss ] [MSG:INFO: WiFi on]

[10:54:22] [ $ss ] [MSG:INFO: Start mDNS with hostname:http://fluidnc.local/]

[10:54:22] [ $ss ] [MSG:INFO: HTTP started on port 80]

[10:54:22] [ $ss ] [MSG:INFO: Telnet started on port 23]

[10:54:22] [ $ss ] [MSG:INFO: ATC:atc_manual]

[10:54:22] [ $ss ] [MSG:INFO: 10V Spindle Ena:NO_PIN Out:gpio.13 Dir:NO_PIN Fwd:gpio.15 Rev:gpio.14 Freq:5000Hz Period:8191 with m6_macro]

[10:54:22] [ $ss ] [MSG:INFO: Laser Ena:NO_PIN Out:gpio.4:pu Freq:5000Hz Period:8191]

[10:54:22] [ $ss ] [MSG:INFO: Flood coolant I2SO.20]

[10:54:22] [ $ss ] [MSG:INFO: Mist coolant gpio.12]

[10:54:22] [ $ss ] [MSG:INFO: Probe gpio.34:low]

[10:54:22] [ $ss ] [MSG:INFO: Toolsetter gpio.35]

[10:54:22] [ $ss ] ok

User Interface Software

No response

What happened?

I’m trying to make use of the new variables introduced in 3.9.3 but I’m facing a strange issue.

Testing procedure :

  • a macro is executed when m6 is called (==> yaml config)
  • at the beginning of the macro is displayed _current_tool and _selected_tool values.
  • I set the current_tool using M61Q to x tool
  • then use M6Ty to proceed to a tool change

Result : current_tool equals selected_tool ( y value) at the beginning of the macro, so no tool changed is performed.
I assumed that _current_tool should be manually updated by the user macro in that case.

Last thing, when I sent a M61Q-1 the spindle was changed to my laser (tool number 50 in the yaml).

Best

GCode File

(debug, begin Selected Tool: #<_selected_tool> - Current Tool: #<_current_tool>.)

Other Information

[10:47:58] [ ] [MSG:INFO: 10V spindle changed to tool:1 using m6_macro]
[10:47:58] [ ] [MSG:INFO: 10V spindle run macro: $SD/Run=tc.nc]
[10:47:58] [ ] [MSG:DBG: Macro line: $SD/Run=tc.nc]
[10:47:58] [ ] [MSG:DBG: DEBUG, begin Selected Tool: 1.000000- Current Tool: 1.000000]

@bdring
Copy link
Owner

bdring commented Jan 2, 2025

I can reproduce the problem. I will work on it when I get a chance.

Grbl 3.9 [FluidNC v3.9.3 (main-c692589c) (wifi) '$' for help]
D#<_current_tool>
[MSG:INFO: Value is -1.000]
ok
D#<_selected_tool>
[MSG:INFO: Value is 0.000]
ok
M61Q5
ok
D#<_selected_tool>
[MSG:INFO: Value is 5.000]
ok
D#<_current_tool>
[MSG:INFO: Value is 5.000]
ok
M5T6
ok
D#<_selected_tool>
[MSG:INFO: Value is 6.000]
ok
D#<_current_tool>
[MSG:INFO: Value is 5.000]
ok
$G
[GC:G0 G54 G17 G21 G90 G94 M5 M9 T6 F0 S0]
ok

@bdring
Copy link
Owner

bdring commented Jan 2, 2025

I made a mistake in my test. I meant to send M6T6. Here is the result. It looks OK to me.

Grbl 3.9 [FluidNC v3.9.3 (main-c692589c) (wifi) '$' for help]
D#<_selected_tool>
[MSG:INFO: Value is 0.000]
ok
D#<_current_tool>
[MSG:INFO: Value is -1.000]
ok
M61Q5
ok
D#<_current_tool>
[MSG:INFO: Value is 5.000]
ok
D#<_selected_tool>
[MSG:INFO: Value is 5.000]
ok
M6T5
ok
D#<_selected_tool>
[MSG:INFO: Value is 5.000]
ok
D#<_current_tool>
[MSG:INFO: Value is 5.000]
ok

The Q value in M61 must be a positive integer.

https://linuxcnc.org/docs/2.8/html/gcode/m-code.html#mcode:m61

I can add code to give an error in that case.

@rvalotta
Copy link
Contributor

rvalotta commented Jan 2, 2025

I can no longer test this as my fluidNC board was exposed to my stupidity. To test this properly a M6 macro should be created that displays the current and selected tool At the start of the macro these values should be different. Selected Tool being the tool about to be loaded and current tool being the tool in the spindle... Traditionally my M6 Macro would do a M61Q<_selected_tool> to update the current tool on successful tool change... Selected too should be updated with the T# so the macro knows what tool to grab.

@bdring
Copy link
Owner

bdring commented Jan 2, 2025

You should not need to do an M61Qx after an M6. Look at last console session. M61 is used to set the tool number without doing a tool change.

I only use M61 when I turn on my machine and the tool is already installed. It lets FluidNC know what tool is there.

FWIW:

M6 and T are separate commands, even if they are on the same line.

T2
M6

if the same thing as

M6T2
or
T2M6

M6
T2

Is not the same.

@rvalotta
Copy link
Contributor

rvalotta commented Jan 2, 2025

Okay so how does fluid know that the tool change was successful and to update the current_tool? I ask for M6T2 it should call my macro saying current-tool is the loaded tool and selected tool is 2. At some point I need to tell fluid the tool change was successful or halt the script and let the user take the appropriate actions to fix any issue.

@rvalotta
Copy link
Contributor

rvalotta commented Jan 2, 2025

Yes T2 is a separate command and should be setting selected_tool

@rvalotta
Copy link
Contributor

rvalotta commented Jan 2, 2025

From the linuxcnc docs:
https://linuxcnc.org/docs/html/gcode/overview.html

#<_current_tool> - Return number of the current tool in spindle. Same as #5400.
#<_selected_tool> - Return number of the selected tool post a T code. Default -1.

@bdring
Copy link
Owner

bdring commented Jan 2, 2025

It is probably best to let FluidNC handle the non failure case and you handle the failure cases.

The failures cases are probably pretty complicated. The machine could generate an alarm (hard limit, probe fail), you could manually do a reset or the macro could generate an alarm. In many cases the macro will have been aborted. You will need to manually reset things

How are you detecting the failures.

@rvalotta
Copy link
Contributor

rvalotta commented Jan 2, 2025

So the m6 script is question is for the RapidChangeATC. It has a break beam sensor and we check to make sure the nut has either loaded or unloaded properly and currently issue an alarm on failures. Traditional on success I set the current_tool using a M61Q as it was meant to update current tool while T was meant to update selected tool. No matter what current_tool shouldnt be updated till the script completes and not before hand.

@bdring
Copy link
Owner

bdring commented Jan 2, 2025

  • What happens after the failure.
  • Are you in alarm state?
  • Were the values changed (correctly or incorrectly)?
  • What should the values be after failure in all fail cases?

@xspy69
Copy link
Author

xspy69 commented Jan 2, 2025

If the tool can’t be loaded/unloaded an alarm is thrown.
current_tool is updated accordingly.

In case of failure, to my point of view values should stay the same before calling the macro as the alarm must be handle by the user.

What’s your opinion on this ?

Best

@rvalotta
Copy link
Contributor

rvalotta commented Jan 2, 2025

Lets be honest on an alarm they are going to have to restart their program.
Current tool and selected tool should be their respective values as they were at the start of the M6 script.
When they restart their gcode it will hit a M6T2 and set a new seleccted_tool. If the user unloads the current tool its up to them to set it back to 0.

that is my thoughts on it...

Right now I couldn't tell you what the values are as I stated I toasted my FluidNC controller.

@bdring
Copy link
Owner

bdring commented Jan 2, 2025

I don't know. It depends on the state. What if the tool is picked up, but fails on toolsetter probing. You have the right tool, but are in alarm.

Machine generated failures are harder to handle than macro generated failures because you can still send gcode before the macro generates the failure.

We might be able to detect the failure of an ATC macro and do one common thing. More than that and you would have to use the class method.

@xspy69
Copy link
Author

xspy69 commented Jan 2, 2025

Bart, I'm a bit lost, sorry. According to you how should we handle those variables in a m6 macro ?
Previously we used a user variable to handle tool change but without the possibility of using M61Q, so we should always start a job with no tool loaded.

I'm curious to read your suggestions on this. there is no generic way to handle that ?

Thanks !

@rvalotta
Copy link
Contributor

rvalotta commented Jan 3, 2025

Just a thought. If the tool change is being handed over to the macro shouldn't the macro be the one to update current_tool or stop the script if something goes wrong.... or at a minimum have a way of informing fluidnc that it was successful. I don't think that behaviour should be part of the firmware. You are handing over the tool change functionality to the macro.

@bdring
Copy link
Owner

bdring commented Jan 3, 2025

This is a complicated issue. We also have to deal with our ability to change spindles via M6. A macro cannot do that by itself.

We will need to think about our options. It will not be a quick fix.

@rvalotta
Copy link
Contributor

rvalotta commented Jan 3, 2025

I wouldn't of thought multiple spindles would of mattered as they would have their own m6 script or use the internal handling.

@bdring
Copy link
Owner

bdring commented Jan 11, 2025

See this PR

#1425

@xspy69
Copy link
Author

xspy69 commented Jan 13, 2025

Hi Bart,

I've tested out this PR and it works flawlessly! Changing spindle works also, it just needs to take care of current_tool when coming from a laser for example but that's the job of the M6 macro. Starting with a tool set at -1 is also a good point as it requires to call M61Qx before starting. Really appreciate your work on this !

@bdring
Copy link
Owner

bdring commented Jan 13, 2025

@rvalotta are you able to test this? Let me know if you have any questions.

@rvalotta
Copy link
Contributor

@bdring Sadly no... I used my superpowers and managed to release the smoke on my fluidNC on one of the io modules and the ESP and just replaced it with a controller i had on hand.

I have been working with xspy69 to make sure it works as its suppose to

@rvalotta
Copy link
Contributor

Just thinking out loud here more so people are aware than anything else

Spoke with xspy69. His setup is a spindle with a m6 macro and a laser without a macro (tool 50).

As he explains it When he switches from the Laser back to the spindle it is saying current_tool is 50. which is fine as long as they put the tool that is in the spindle away before switching to the laser or their macro makes sure the tool number for current tool is within range of the atc.. In my case it would trigger a manual tool change as the tool number is outside the valid pocket range.

I don't think their is anything that can be done in the core to rectify this. I would suggest a note on the wiki for m6_macro saying if they are going to be switching spindles to ensure they only handle valid tool ranges or something to the like or if the tool has no m6 macro it sets the current_tool to 0.

Maybe even disallow a spindle change is the current_tool is not 0 to make sure its unloaded?

Anyways that is just some thoughts but as it is now it is working wonderfully... Thankyou

@bdring
Copy link
Owner

bdring commented Jan 13, 2025

The M6 macro will only be sent to the tool that has the selected tool within its range.

Assume you have a VFD ATC spindle with tools 0-99 and a laser with tools 100-255. The laser has an active lens cap.

If you want to sculpt a part with the spindle, etch with the laser, then cut out the part with the spindle, you would do something like this.

M6T1 ; select tool 1
; sculpting gcode
M6T0; put away the spindle tool
M6T101; select the laser, open the lens cap, etc.
; etch the part
M6T100 ;  close the lens cap
M6T2; get a spindle tool
; cut out the part.
M6T0 ; return the tool
; end the job.
  • The spindle m6_macro should remember its own last tool. This allows you properly deal with returning from the laser.
  • The laser m6_macro needs to know that 100 is the lasers version of T0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants