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 GitHub - Allted/Marlin at V1CNC_SKR_Pro_Dual
There are three ways you can control a laser via G-code:
- 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)
- Using the spindle speed M3/M4 for laser control. Instead of controlling spindle speed via M3, you control laser power.
- 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: STM32: No compile-time check for PWM_PIN by GhostlyCrowd · Pull Request #18539 · MarlinFirmware/Marlin · GitHub …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.