I am using inline laser control. The inline laser control works as expected, but the laser is turned off when I do a G1 or G0 movement without a S?? parameter. Is this normal? I attached a gcode file. On every M3 S60 command, the laser turns on, but it turns off directly after that on the next G1 movement. When I set the laser power with an inline command, it does stay on during the next move without a S?? parameter. For example:
G1 X5 S60 // laser turns on
G1 X50 // laser stays on
But:
M3 S60 // turns the laser on
G1 X50 // laser turns off
In configuration_adv.h, I have disabled #define LASER_MOVE_G0_OFF. From what I understand, In the second example the laser should stay on untill I use a M5 command or set it to another value.
Expected behavior:
From what I understand, In the second example the laser should stay on untill I use a M5 command or set it to another value.
Actual behavior:
The laser turns offon every G0/G1 movement without a S?? parameter
GCode Example
Looking through the code LASER_POWER_INLINE is incompatible with the old M3 gcode
When LASER_POWER_INLINE you must use M3 I eg M3 S60 I and laser only comes on with first move.
Ahh that's a shame. Do you know which piece of code turns off the laser during the movement after a regular M3 command? I think when I remove that piece of code it will work for me. Thanks!
updated... description not quite accurate enough, not entirely incompatible
Thans for the clarification. Is the laser supposed to turn of after the first move?
So which of the following is right:
M3 S60 I // laser stays off
G1 X5 // laser turns on
G1 X50 // laser stays on
Or
M3 S60 I // laser stays off
G1 X5 // laser turns on
G1 X50 // laser turns off
If possible, I still would like to edit the code so that a regular M3 works and that it does not get turnt off on the next moves, since the software I use does use inline laser control for the infill, but does use the 'normal' (M3 / M5) laser control for the outline.
Thanks again
What software?
LaserGRBL
So basically it not any bug at all, you want a new feature, LaserGRBL compatibility
No, I thought it was a bug. I also tested it using the terminal. I thought the M3 and M5 were supposed to work normally when using inline laser control. That's why I Thought it was a bug. Do you know where in the code the laser gets turned off when moving after a regular M3?
Btw, I am using a slightly modified version of LaserGRBL to make it compatible with Marlin. The inline laser control works perfect, I only thought the normal control was supposed to work even with inline control enabled.
just a small comment, if not a bug but more a feature request then replace [BUG] with [FR] in the title and maybe rephrase the title
the program LaserGRBL does have a marlin mode. am attempting to ascertain what it really means by that..
I do think there are issue with laser support.
In the file M3-M5.cpp I found this block of code:
(Marlin/src/gcode/control/M3-M5.cpp, Line 81 - 99)
#if ENABLED(LASER_POWER_INLINE)
if (parser.seen('I') == DISABLED(LASER_POWER_INLINE_INVERT)) {
// Laser power in inline mode
cutter.inline_direction(is_M4); // Should always be unused
#if ENABLED(SPINDLE_LASER_PWM)
if (parser.seen('O')) {
cutter.unitPower = cutter.power_to_range(parser.value_byte(), 0);
cutter.inline_ocr_power(cutter.unitPower); // The OCR is a value from 0 to 255 (uint8_t)
}
else
cutter.inline_power(cutter.upower_to_ocr(get_s_power()));
#else
cutter.set_inline_enabled(true);
#endif
return;
}
// Non-inline, standard case
cutter.inline_disable(); // Prevent future blocks re-setting the power
#endif
If I understand it correctly, when a M3 command is sent without a 'I', it should go to non-inline mode. However, this does not happen for me and the laser gets turned off when I sent a regular movement.
the fuction inline_disable contains
// Force disengage planner power control
static inline void inline_disable() {
isReady = false;
unitPower = 0;
planner.laser_inline.status.isPlanned = false;
planner.laser_inline.status.isEnabled = false;
planner.laser_inline.power = 0;
}
looks good, but in the middle of planner.cpp with no way to avoid this code without disabling LASER_POWER_INLINE is
// Update block laser power
#if ENABLED(LASER_POWER_INLINE)
laser_inline.status.isPlanned = true;
block->laser.status = laser_inline.status;
block->laser.power = laser_inline.power;
#endif
And this is what turns M3 off
Its a right mess... trying to get me head around what the original intent was...
Thanks for the clarification.
I hope that in future updates regular laser control and inline laser control can both work!
can you provide example gcode that uses a mix of features. M3/M5 G1 with S 's etc
Here is an example gcode file
From line 0 to 3724 it creates the infill. This parts works as it should.
From line 3725 to 4256 it should create the outline, but this dos not work as expected.
For example, on line 3727 the laser turns on, but it directly turns off when on the next line when it starts moving.
I think with LASER_POWER_INLINE enabled, this should happen:
M3 S60 I // laser turns on, inline power is active: planner expects power parameter with every G0/G1 code and adjusts power acoording to planned movement
G1 X5 // laser turns off, as no laser power is given
G1 X50 S50// laser turns on synchronized with movement to X50
M5 // laser off
M3 S60 // laser turns on, inline power is ignored
G1 X5 // laser keeps on at S60, moves to X5
G1 X50 S30 // laser keeps on at S60, ignoring S30 , moves to X50
M5 // laser off
So M3 S60 should disable planner laser power calculation, set laser_inline.power to 0 but should not set unitPower to 0, so in planner will be something like this
block->laser.power = laser_inline.status.isEnabled ? laser_inline.power : unitPower ;
I think with LASER_POWER_INLINE enabled, this should happen:
M3 S60 I // laser turns on, inline power is active: planner expects power parameter with every G0/G1 code and adjusts power acoording to planned movement G1 X5 // laser turns off, as no laser power is given G1 X50 S50// laser turns on synchronized with movement to X50 M5 // laser off M3 S60 // laser turns on, inline power is ignored G1 X5 // laser keeps on at S60, moves to X5 G1 X50 S30 // laser keeps on at S60, ignoring S30 , moves to X50 M5 // laser offSo
M3 S60should disable planner laser power calculation, set laser_inline.power to 0 but should not set unitPower to 0, so in planner will be something like thisblock->laser.power = laser_inline.status.isEnabled ? laser_inline.power : unitPower ;
@chepo92 Thanks for your reply, thats what I thought too, but the last part doesn't work for me like that. During the moves after the regular M3 S60, the laser turns off.
@chepo92 Thanks for your reply, thats what I thought too, but the last part doesn't work for me like that. During the moves after the regular M3 S60, the laser turns off.
Yes, I can replicate it, try that change in the code
@chepo92
I just tried to compile the new firmware. I get an error: 'unitPower was not declared in this scope'. This is about line 1832 of the planner.cpp file right? What happens when you want to use inline control after a regular M3? Will that work?
@ryanaukes I think it should be:
block->laser.power = laser_inline.status.isEnabled ? laser_inline.power : cutter.power;
You have to make other changes (M3-M5.cpp, planner.cpp, spindle_laser.h), I'm working on it in:
https://github.com/chepo92/Marlin/tree/CR10S5-BL-laser-fs
I just tested it but still no luck, the planner is setting cutter.power= 0, somewhere, i'll try hardcode the power and disable trapezoid power to find out
What happens when you want to use inline control after a regular M3? Will that work?
What do you think? I believe after a regular M3 it should ignore any inline power change (as if LASER_POWER_INLINE was disabled):
M3 S60 // laser turns on, inline power is ignored
G1 X5 // laser keeps on at S60, moves to X5
G1 X50 S30 // laser keeps on at S60, ignoring S30 , moves to X50
M5 // laser off
I am not really used to GitHub yet. How can I see what you changed to try to fix this? I am not using trapezoid power.
I am not really used to GitHub yet. How can I see what you changed to try to fix this? I am not using trapezoid power.
follow this link: https://github.com/MarlinFirmware/Marlin/compare/bugfix-2.0.x...chepo92:CR10S5-BL-laser-fs
look at the changes in M3-M5.cpp, planner.cpp, spindle_laser.h,
Making many test,
All changes in planner.cpp line ~1835
0. Original block->laser.power = laser_inline.power ;
- M3 turns on, any following G0/G1 will turn off
- M3 I turns laser on after a G0/G1 is sent
block->laser.power = cutter.power ; cutter.power is not keeping previous power valueafter M3 I keeps always off for any G1/G0
set block->laser.power = 10 ;
M3 I keeps laser at 10% for any G1/G0 for any in line power
block->laser.power = laser_inline.status.isEnabled ? laser_inline.power : cutter.power;
M3 turns on, any following G0/G1 will turn offM3 I keeps laser at the set inline power for any G1/G0 with inline power argumentSo the problem should be when cutter.power is not keeping previous value or being set to 0 somewhere
@chepo92 Did you by any chance already find a solution or made some progress? I tried the changes you made, but for me it didn't work either.
@chepo92 Did you by any chance already find a solution or made some progress? I tried the changes you made, but for me it didn't work either.
No luck, I don't know where cutter.power is being changed in code
A workaround for now is that you post process or change the config of your gcode generator, so it always outputs inline power, I think that is easier.
Thats a shame. What method do you use to change the normal code to inline code? I can do it manually but for some files that would take way too long. For example, how would you post process the example file I included in my post.
Thanks!
Many possibilities of where this thing is being set to 0
Thats a shame. What method do you use to change the normal code to inline code? I can do it manually but for some files that would take way too long.
You can do it with any text editor or with a search and replace post processing script (search for all M3 alone and add the power to the following G0/G1 lines until an M5 is found)
I have just spent some time being confused by this, I think its certainly a bug. The same file works fine with LASER_POWER_INLINE disabled does not work at LASER_POWER_INLINE enabled.
At least LASER_POWER_INLINE should be defaulted off until this is fixed.
Hi,
I was the original author of the laser power inline code (though it was completed by someone else as I didn't have access to a laser cutter for a while)
The reason for:
// Force disengage planner power control
static inline void inline_disable() {
isReady = false;
unitPower = 0;
planner.laser_inline.status.isPlanned = false;
planner.laser_inline.status.isEnabled = false;
planner.laser_inline.power = 0;
}
When I originally wrote it (as someone else ended up finishing off the code) was to ensure the laser could be fired without issuing a move order.
Suppose you wish to pulse the laser to check alignment (on a CO2 laser which is what I was prototyping the firmware on); what you would need to do is issue M3 S[power] M5, and it would pulse the laser on and off allowing you to do tape based alignment. Inlined power calls are tied to movement, so will not execute until another block of movement has occured.
This was done as otherwise you need to use planner.synchronize() to sync with the movement, but then you deplete the movement buffer and the laser head slows down and then speeds back up on every power change ; that's why there is a return at the end of the inlined power processing; to avoid ever hitting the synchronize call see here
If you want M3 to behave in the way originally suggested:
G1 X5 S60 // laser turns on
G1 X50 // laser stays on
Being equivelent to
M3 S60 // turns the laser on
G1 X50 // laser turns off
You either A: Make the M3 call be inlined by adding I to the end OR toggle LASER_POWER_INLINE_INVERT in your config, making all calls behave inlined unless stated otherwise. The latter would likely be the best option for longer term use; as if you want to do temporary firing you can just use M3 S[power] I M5 I to create a pulse for alignment
@jediminer543 Thank you for the full explanation.
It is helpful to understand the reasons of why this is the way it is!
@jediminer543 so in your view do we have a bug here? not sure myself
I think it would be more of an flawed design than a bug; What I should really have done is move the entire power config into planner controlled sections to completely eliminate the planner.synchronise() call in power setting; then the M3 I mode would become the same as M3 and the entire behaviour would be simplifed.
I didn't do that originally as both I ran out of time, and also wasn't certain the planner had any design built in to support what would basicly be a zero length meta-block
This issue has had no activity in the last 30 days. Please add a reply if you want to keep this issue active, otherwise it will be automatically closed within 7 days.
bump, still a bug IMHO. A change of defaults this setting to off would fix.
submitting a PR with the change will make that happen a lot faster
@ryanaukes do you know whether the pull request from @IamPete1 has resolved your issue?
@ryanaukes do you know whether the pull request from @IamPete1 has resolved your issue?
Disabling inline laser control won't solve my problem, since my problem is that I want to be able to use both inline laser control and regular laser control.
OK, I didn't actually read through every detail. I just saw the PR referenced at the end of the comments and thought maybe it had been resolved.
@shitcreek I just saw your reply to my other post where you explained how the inline laser is supposed to work, but I cannot respond there anymore. I do understand how it is supposed to work. On this page you can see the problem I am having and why this suboptimal behaviour of Marlin is the way it is.
The problem is that I can use either inline laser control or regular laser control. As soon as I enable inline laser control, regular laser control doesn't work anymore. Whenever I use a regular G1 or G0 without a Sxxx parameter it turns off the laser, while it is supposed to stay on.
I now have a better setup so I'll spin up the linux test build of marlin and see what I can do
@ryanaukes I just took a look at your config_adv file and I think I see your problem.
Your SPEED_POWER_STARTUP is set to 1
With LASER_MOVE_POWER, the laser will default to SPEED_POWER_STARTUP if no S parameter is included.
When you say the laser turns off, do you mean completely and on the display as well or just that it is effectively off?
@ryanaukes I just took a look at your config_adv file and I think I see your problem.
Your
SPEED_POWER_STARTUPis set to 1With
LASER_MOVE_POWER, the laser will default toSPEED_POWER_STARTUPif noSparameter is included.When you say the laser turns off, do you mean completely and on the display as well or just that it is effectively off?
Thanks for your reply! It has been a while since I tested it, so I honestly don't know right now. I will try it again soon and let you know (hopefully during this weekend)!
Isn't the laser supposed to stay at the same value when using a G1 after turning the laser on with a regular M3 (so no inline laser command), instead of turning to the default value? Because if it sets it to the default on every move without a parameter, regular laser commands would be really unpractical to use when also using inline laser commands.
My bad. I meant with M3.
G1 shouldn't turn the laser off unless it has S0
in gcode.cpp:
#if ENABLED(LASER_MOVE_POWER)
// Set the laser power in the planner to configure this move
if (parser.seen('S')) {
const float spwr = parser.value_float();
cutter.inline_power(TERN(SPINDLE_LASER_PWM, cutter.power_to_range(cutter_power_t(round(spwr))), spwr > 0 ? 255 : 0));
}
else if (ENABLED(LASER_MOVE_G0_OFF) && parser.codenum == 0) // G0
cutter.set_inline_enabled(false);
#endif
As you can see, only G0 is targeted.
When you say the laser turns off, do you mean completely and on the display as well or just that it is effectively off?
I just tested it again. When I do the following:
M3 S60
G1 X50
The laser turns on after the M3 command. After the G1 command, the laser turns off, but the value (60 in this case) keeps set. So the power is nit set to 0, but the laser gets disabled.
Is your fan pin assigned to a different pin?
FAN_PIN is set to pin 9,
FAN1_PIN is set to pin 8,
SPINDLE_LASER_PWM_PIN is set to pin 44
Check out that PR of mine, I try to fix this issue, with some success. Still need more testing and how it will behave with certain features turned off.
Check out that PR of mine, I try to fix this issue, with some success. Still need more testing and how it will behave with certain features turned off.
Thanks, I will definitely check it out!