How-To: Modify Marlin to control a laser with an SKR Pro

Here’s a how-to on getting a diode laser going with an SKR PRO and Ryan’s Marlin fork firmware.

I’m using dual endstops, so the following is based on https://github.com/Allted/Marlin/tree/V1CNC_SKR_Pro_Dual

There are three ways you can control a laser via G-code:

  1. Using the fan control to instead control the laser via M106 and M107 fan speed commands. Often re-assigning the high voltage fan pin to a logic voltage pin (via Marlin)
  2. Using the spindle speed M3/M4 for laser control. Instead of controlling spindle speed via M3, you control laser power.
  3. Using spindle speeds integrated into the G1 move commands. The “S” parameter of the G1 move command can be used to control laser power during that move.

Lightburn seems to support all of the above.

Number 3 above seems to run the smoothest for me. The others seemed to have a lot of stuttering.

For either method I’ll use the PWM output pin available on the 14 pin “EXPANSION-1” header, pin 4, a.k.a top row, 2nd from the left when the USB is pointing at you. This pin is also known as PC9. The logic pins on the STM32 are 3.3V. 3.3V was enough to fire my banggood laser, though I think it’s officially rated for 5V inputs.


I assume you know how to build firmware and get it to the board. Try building without any changes before you attempt any of the following.

First thing is it seems the STM32 platform has no good way for Marlin to determine if a pin is PWM capable or not. If you start enabling pins for laser you might get the following sort of compile/build error:

Compiling .pio/build/BIGTREE_SKR_PRO/src/src/HAL/STM32/HAL.cpp.o
In file included from /Users/rob/.platformio/packages/framework-arduinoststm32/cores/arduino/Arduino.h:48,
                 from Marlin/src/HAL/STM32/../shared/Marduino.h:36,
                 from Marlin/src/HAL/STM32/HAL.h:28,
                 from Marlin/src/HAL/STM32/HAL.cpp:25:
/Users/rob/.platformio/packages/framework-arduinoststm32/cores/arduino/pins_arduino.h:254:51: error: missing binary operator before token "("
  254 | #define digitalPinHasPWM(p)         (pin_in_pinmap(digitalPinToPinName(p), PinMap_PWM))
      |                                                   ^
Marlin/src/HAL/STM32/fastio.h:83:33: note: in expansion of macro 'digitalPinHasPWM'
   83 | #define PWM_PIN(P)              digitalPinHasPWM(P)
      |                                 ^~~~~~~~~~~~~~~~
Marlin/src/HAL/STM32/../../inc/SanityCheck.h:2912:12: note: in expansion of macro 'PWM_PIN'
 2912 |     #elif !PWM_PIN(SPINDLE_LASER_PWM_PIN)
      |            ^~~~~~~

What worked for me is to just disable PWM pin checking in Marlin by changing Marlin/src/HAL/STM32/fastio.h

diff --git a/Marlin/src/HAL/STM32/fastio.h b/Marlin/src/HAL/STM32/fastio.h
index c17901fa9..4c31818f3 100644
--- a/Marlin/src/HAL/STM32/fastio.h
+++ b/Marlin/src/HAL/STM32/fastio.h
@@ -80,7 +80,8 @@ void FastIO_init(); // Must be called before using fast io macros
 #define IS_INPUT(IO)
 #define IS_OUTPUT(IO)

-#define PWM_PIN(P)              digitalPinHasPWM(P)
+#define PWM_PIN(P) true
+#define NO_COMPILE_TIME_PWM

 // digitalRead/Write wrappers
 #define extDigitalRead(IO)    digitalRead(IO)

This issue may also have fixed it: https://github.com/MarlinFirmware/Marlin/pull/18539 …but Ryan hasn’t pulled that change into his fork yet.

Now, onto configuring pins for laser control.

Method 1 - M106/M107

If your laser can take 12V on it’s PWM control input maybe you don’t need to switch to a pin that is 5V and use the FAN0 output as-is.
Change the fan 0 pin in Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h

diff --git a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h
index 42e3f1fac..3896da35f 100644
--- a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h
+++ b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h
@@ -230,7 +230,7 @@
 #define HEATER_1_PIN                        PD14  // Heater1
 #define HEATER_2_PIN                        PB0   // Heater1
 #define HEATER_BED_PIN                      PD12  // Hotbed
-#define FAN_PIN                             PC8   // Fan0
+#define FAN_PIN                             PC9   // Fan0
 #define FAN1_PIN                            PE5   // Fan1
 #define FAN2_PIN                            PE6

Method 2 - M3/M4 control

I believe the method below will work for this as well

Method 3 - G1 move spindle speed control.

I think you have to pick an enable pin or you’ll get errors, I picked PC1, though I don’t use it.

diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 725f39201..c90a5784f 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -2835,9 +2835,11 @@
  * See https://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
  */
 //#define SPINDLE_FEATURE
-//#define LASER_FEATURE
+#define LASER_FEATURE
 #if EITHER(SPINDLE_FEATURE, LASER_FEATURE)
-  #define SPINDLE_LASER_ACTIVE_HIGH     false  // Set to "true" if the on/off function is active HIGH
+  #define SPINDLE_LASER_ENA_PIN PC1
+  #define SPINDLE_LASER_PWM_PIN PC9
+  #define SPINDLE_LASER_ACTIVE_HIGH     true   // Set to "true" if the on/off function is active HIGH
   #define SPINDLE_LASER_PWM             true   // Set to "true" if your controller supports setting the speed/power
   #define SPINDLE_LASER_PWM_INVERT      false  // Set to "true" if the speed/power goes up when you want it to go slower

@@ -2931,7 +2933,7 @@
       /**
        * Include laser power in G0/G1/G2/G3/G5 commands with the 'S' parameter
        */
-      //#define LASER_MOVE_POWER
+      #define LASER_MOVE_POWER

       #if ENABLED(LASER_MOVE_POWER)
         // Turn off the laser on G0 moves with no power parameter.

I don’t claim to be a laser expert, but the above seemed to get me rolling enough to burn a raster image of when I tortillaed my poor cat Cooter.

5 Likes

Can you tell us what laser you are using?

Thanks.

After watching: https://youtu.be/3Qz-uDx9PhA I bought one of those. https://www.banggood.com/450nm-5W-Laser-Engraving-Module-Blue-Light-With-TTL-Modulation-p-1337358.html?cur_warehouse=USA

I hesitate to recommend it since it’s a bit dangerous in that if you don’t ground the input pin (leave it floating) the thing turns on full blast. Even connected to the SKR Pro pin at logic 0 it won’t turn off, you have to have a ~2.2K pulldown resistor to ground at all times. Also the dot pattern is more of a dash than a dot (zoom in on the cat in the tortilla). Supposedly overrated (power) lasers do that.

Do you know if your starting firmware will work with the 2209 drivers. My starting firmware is:

https://github.com/V1EngineeringInc/MarlinBuilder/releases/download/505/V1CNC_SkrPro_Dual_2209-2.0.6.1-src.zip

and of course it is different than your example.

I tried starting with your firmware but I need a little more clarification.

If I was going to setup the firmware exactly like you, I would only change code from method three and ignore everything else?

Look for:

#define X_DRIVER_TYPE  TMC2209
#define Y_DRIVER_TYPE  TMC2209
#define Z_DRIVER_TYPE  TMC2209
#define X2_DRIVER_TYPE TMC2209
#define Y2_DRIVER_TYPE TMC2209
//#define Z2_DRIVER_TYPE A4988
//#define Z3_DRIVER_TYPE A4988
//#define Z4_DRIVER_TYPE A4988
#define E0_DRIVER_TYPE TMC2209

in Marlin/Configuration.h. That driver is Ryan’s default for the SKR boards

Is this correct?

Secondly, once the modifications to the firmware are made, do you have to use light burn to verify they are working if you are using method 3? (To clarify you cannot use the touchscreen laser menu to bump the fan percentage up and down correct?)

I believe that’s correct. I don’t think the fan control would work to tweak the laser, right. You could enter manual gcode in the TFT GUI if you have one, or create your own gcode file for testing. I think I have one that burns a little square, I’ll try to find it later.

Tuco do you still have your laser hooked up?

Thanks to your post I got up and running very quickly!

I am having a heck of a time getting the grayscale to work without glitches.

I can get either dark spot or light spots. I swear I have tried everything I can think of. I am seeing it with different boards, different software, and different lasers.

Are you having these same issues?

No, have the router hooked up at the moment.

That cat pic above was more of a dither than true greyscale.

Is that gcode anywhere?

Yeah I can get dither to work but something about full greyscale seems to choke Marlin. I was hoping to narrow it down. Last night I went to hook up my board to the scope and popped it, thinking I touched something wrong I carefully hooked up another board and a popped a second one. After that I stopped before I got real angry.

I can see it kinda stutter when it happens, ever so slight but it does.

I have that same pic from two different software.
The smoothest was inline, M3 not inline was not very good, M106 was all bad.
Inline test was the main one. LB1 seems slightly better (from Light burn).
Laser.zip (206.2 KB)

Hmmm, now that I look at the tests. The first picture I did was pretty slow 25-30mm/s It has no glitches. The rest of these are at 55-60. I need to do another slower test. I will be pretty bummer if I spent 2 days chasing my tail and it was just a speed thing.

Eureka!!

Speed…this whole time it was speed.

I will keep testing to see what the limits are.

PS using heater2 for the enable pin/power is working perfectly.

2 Likes

I found that speed was messing me up too. I still haven’t figured out the speed thing but I’ll keep testing. the last burn I did was at 600mm/s and at 100%. I am using Light Burn and have a 7.5W Diode laser. I did 3 passes on brown paper foam board and it did not go all the way through. from what I have been reading that is still to fast ill work on slowing it down some more. I draws a clean line just doesn’t cut very deep.

Did you change the firmware? The regular firmware is capped at 50mm/s.

as far as I know I didn’t do anything to it. Just downloaded it from the github that you sent the link to me. and uploaded it to the board. I may be reading it wrong, it might be mm/min, I’ll have to double check it tonight.

Mm/min is that standard for measuring laser speed (in lightburn and other similar programs)

So I’m stuck again.

If I use Tuco’s firmware from the first post on this thread

I can make his changes and it compiles fine but when I load it onto my primo I get an all low error.

If I start with the firmware Jeff recommended

https://github.com/V1EngineeringInc/MarlinBuilder/releases/download/505/V1CNC_SkrPro_Dual_2209-2.0.6.1-src.zip

My primo with dual end stops functions correctly (no all low error) but after changing the lines from method three of Tuco’s instructions, Platformio won’t compile and throws these errors.

Building in release mode
Compiling .pio/build/BIGTREE_SKR_PRO/src/src/HAL/STM32/HAL.cpp.o
Compiling .pio/build/BIGTREE_SKR_PRO/src/src/HAL/STM32/HAL_SPI.cpp.o
Compiling .pio/build/BIGTREE_SKR_PRO/src/src/HAL/STM32/MarlinSerial.cpp.o
Compiling .pio/build/BIGTREE_SKR_PRO/src/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp.o
In file included from Marlin/src/HAL/STM32/…/…/inc/MarlinConfig.h:41,
from Marlin/src/HAL/STM32/HAL.cpp:28:
Marlin/src/HAL/STM32/…/…/inc/SanityCheck.h:417:4: error: #error “SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h.”
417 | #error “SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h.”
| ^~~~~
In file included from Marlin/src/HAL/STM32/…/…/inc/MarlinConfig.h:41,
from Marlin/src/HAL/STM32/HAL_SPI.cpp:25:
Marlin/src/HAL/STM32/…/…/inc/SanityCheck.h:417:4: error: #error “SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h.”
417 | #error “SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h.”
| ^~~~~
In file included from Marlin/src/HAL/STM32/…/…/inc/MarlinConfig.h:42,
from Marlin/src/HAL/STM32/HAL.cpp:28:
Marlin/src/HAL/STM32/…/…/inc/…/HAL/STM32/inc/SanityCheck.h:32:4: error: #error “Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32.”
32 | #error “Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32.”
| ^~~~~
In file included from Marlin/src/HAL/STM32/…/…/inc/MarlinConfig.h:41,
from Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp:23:
Marlin/src/HAL/STM32/…/…/inc/SanityCheck.h:417:4: error: #error “SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h.”
417 | #error “SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h.”
| ^~~~~
In file included from Marlin/src/HAL/STM32/…/…/inc/MarlinConfig.h:41,
from Marlin/src/HAL/STM32/MarlinSerial.cpp:22:
Marlin/src/HAL/STM32/…/…/inc/SanityCheck.h:417:4: error: #error “SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h.”
417 | #error “SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE. Please update your Configuration_adv.h.”
| ^~~~~
In file included from Marlin/src/HAL/STM32/…/…/inc/MarlinConfig.h:42,
from Marlin/src/HAL/STM32/HAL_SPI.cpp:25:
Marlin/src/HAL/STM32/…/…/inc/…/HAL/STM32/inc/SanityCheck.h:32:4: error: #error “Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32.”
32 | #error “Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32.”
| ^~~~~
In file included from Marlin/src/HAL/STM32/…/…/inc/MarlinConfig.h:42,
from Marlin/src/HAL/STM32/MarlinSerial.cpp:22:
Marlin/src/HAL/STM32/…/…/inc/…/HAL/STM32/inc/SanityCheck.h:32:4: error: #error “Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32.”
32 | #error “Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32.”
| ^~~~~
In file included from Marlin/src/HAL/STM32/…/…/inc/MarlinConfig.h:42,
from Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp:23:
Marlin/src/HAL/STM32/…/…/inc/…/HAL/STM32/inc/SanityCheck.h:32:4: error: #error “Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32.”
32 | #error “Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32.”
| ^~~~~
*** [.pio/build/BIGTREE_SKR_PRO/src/src/HAL/STM32/HAL_SPI.cpp.o] Error 1
*** [.pio/build/BIGTREE_SKR_PRO/src/src/HAL/STM32/HAL.cpp.o] Error 1
*** [.pio/build/BIGTREE_SKR_PRO/src/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp.o] Error 1
*** [.pio/build/BIGTREE_SKR_PRO/src/src/HAL/STM32/MarlinSerial.cpp.o] Error 1
============================== [FAILED] Took 7.40 seconds ==============================

Environment Status Duration


BIGTREE_SKR_PRO FAILED 00:00:07.397
======================== 1 failed, 0 succeeded in 00:00:07.397 ========================
The terminal process “pio ‘run’” terminated with exit code: 1.

Terminal will be reused by tasks, press any key to close it.


I either need to fix the all low error on tucos firmware or fix the compile error on Jeff’s firmware (with Tuco laser mods).

Thanks in advance smart people!

“I just want to hit the open road and drive man…
But in whose car?” - Nellie from The Office / Andy’s Ancestry

Two options.

The skr firmware that you just stick the bin on the card and reboot is here…no need to actually compile or anything. Marlinbuilder releases

If you want to use the laser here is the new bin, https://github.com/V1EngineeringInc/MarlinBuilder/actions select the latest skrpro branch, it updates every night. The changes have all been made…just waiting for Marlin to bump the branch to have it work this smoothly.

2 Likes

Thanks Ryan, will the laser firmware work with the way tuco wired it up with the activate wire on pin PC9?