Browse Source

Add SPINDLE_SERVO option (#19971)

Alexander Semion 3 years ago
parent
commit
cd89fa141b
No account linked to committer's email address

+ 7
- 0
Marlin/Configuration_adv.h View File

@@ -2943,11 +2943,18 @@
2943 2943
 
2944 2944
   #define SPINDLE_LASER_FREQUENCY       2500   // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC)
2945 2945
 
2946
+  //#define SPINDLE_SERVO         // A servo converting an angle to spindle power
2947
+  #ifdef SPINDLE_SERVO
2948
+    #define SPINDLE_SERVO_NR   0  // Index of servo used for spindle control
2949
+    #define SPINDLE_SERVO_MIN 10  // Minimum angle for servo spindle
2950
+  #endif
2951
+
2946 2952
   /**
2947 2953
    * Speed / Power can be set ('M3 S') and displayed in terms of:
2948 2954
    *  - PWM255  (S0 - S255)
2949 2955
    *  - PERCENT (S0 - S100)
2950 2956
    *  - RPM     (S0 - S50000)  Best for use with a spindle
2957
+   *  - SERVO   (S0 - S180)
2951 2958
    */
2952 2959
   #define CUTTER_POWER_UNIT PWM255
2953 2960
 

+ 11
- 1
Marlin/src/feature/spindle_laser.cpp View File

@@ -30,6 +30,10 @@
30 30
 
31 31
 #include "spindle_laser.h"
32 32
 
33
+#if ENABLED(SPINDLE_SERVO)
34
+  #include "../module/servo.h"
35
+#endif
36
+
33 37
 SpindleLaser cutter;
34 38
 uint8_t SpindleLaser::power;
35 39
 bool SpindleLaser::isReady;                                           // Ready to apply power setting from the UI to OCR
@@ -45,7 +49,11 @@ cutter_power_t SpindleLaser::menuPower,                               // Power s
45 49
 // Init the cutter to a safe OFF state
46 50
 //
47 51
 void SpindleLaser::init() {
48
-  OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE);      // Init spindle to off
52
+  #if ENABLED(SPINDLE_SERVO)
53
+    MOVE_SERVO(SPINDLE_SERVO_NR, SPINDLE_SERVO_MIN);
54
+  #else
55
+    OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE);    // Init spindle to off
56
+  #endif
49 57
   #if ENABLED(SPINDLE_CHANGE_DIR)
50 58
     OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0);         // Init rotation to clockwise (M3)
51 59
   #endif
@@ -97,6 +105,8 @@ void SpindleLaser::apply_power(const uint8_t opwr) {
97 105
       ocr_off();
98 106
       isReady = false;
99 107
     }
108
+  #elif ENABLED(SPINDLE_SERVO)
109
+    MOVE_SERVO(SPINDLE_SERVO_NR, power);
100 110
   #else
101 111
     WRITE(SPINDLE_LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
102 112
     isReady = true;

+ 4
- 1
Marlin/src/feature/spindle_laser.h View File

@@ -35,6 +35,7 @@
35 35
 #endif
36 36
 
37 37
 #define PCT_TO_PWM(X) ((X) * 255 / 100)
38
+#define PCT_TO_SERVO(X) ((X) * 180 / 100)
38 39
 
39 40
 #ifndef SPEED_POWER_INTERCEPT
40 41
   #define SPEED_POWER_INTERCEPT 0
@@ -60,7 +61,7 @@ public:
60 61
   }
61 62
 
62 63
   // Convert a cpower (e.g., SPEED_POWER_STARTUP) to unit power (upwr, upower),
63
-  // which can be PWM, Percent, or RPM (rel/abs).
64
+  // which can be PWM, Percent, Servo angle, or RPM (rel/abs).
64 65
   static const inline cutter_power_t cpwr_to_upwr(const cutter_cpower_t cpwr) { // STARTUP power to Unit power
65 66
     const cutter_power_t upwr = (
66 67
       #if ENABLED(SPINDLE_FEATURE)
@@ -69,6 +70,8 @@ public:
69 70
           cpwr                            // to RPM
70 71
         #elif CUTTER_UNIT_IS(PERCENT)     // to PCT
71 72
           cpwr_to_pct(cpwr)
73
+        #elif CUTTER_UNIT_IS(SERVO)       // to SERVO angle
74
+          PCT_TO_SERVO(cpwr_to_pct(cpwr))
72 75
         #else                             // to PWM
73 76
           PCT_TO_PWM(cpwr_to_pct(cpwr))
74 77
         #endif

+ 7
- 1
Marlin/src/gcode/control/M3-M5.cpp View File

@@ -69,9 +69,13 @@ void GcodeSuite::M3_M4(const bool is_M4) {
69 69
   auto get_s_power = [] {
70 70
     if (parser.seenval('S')) {
71 71
       const float spwr = parser.value_float();
72
-      cutter.unitPower = TERN(SPINDLE_LASER_PWM,
72
+      #if ENABLED(SPINDLE_SERVO)
73
+        cutter.unitPower = spwr;
74
+      #else
75
+        cutter.unitPower = TERN(SPINDLE_LASER_PWM,
73 76
                               cutter.power_to_range(cutter_power_t(round(spwr))),
74 77
                               spwr > 0 ? 255 : 0);
78
+      #endif
75 79
     }
76 80
     else
77 81
       cutter.unitPower = cutter.cpwr_to_upwr(SPEED_POWER_STARTUP);
@@ -108,6 +112,8 @@ void GcodeSuite::M3_M4(const bool is_M4) {
108 112
     }
109 113
     else
110 114
       cutter.set_power(cutter.upower_to_ocr(get_s_power()));
115
+  #elif ENABLED(SPINDLE_SERVO)
116
+    cutter.set_power(get_s_power()); 
111 117
   #else
112 118
     cutter.set_enabled(true);
113 119
   #endif

+ 5
- 1
Marlin/src/inc/Conditionals_adv.h View File

@@ -33,7 +33,7 @@
33 33
 // Determine NUM_SERVOS if none was supplied
34 34
 #ifndef NUM_SERVOS
35 35
   #define NUM_SERVOS 0
36
-  #if ANY(CHAMBER_VENT, HAS_Z_SERVO_PROBE, SWITCHING_EXTRUDER, SWITCHING_NOZZLE)
36
+  #if ANY(HAS_Z_SERVO_PROBE, CHAMBER_VENT, SWITCHING_TOOLHEAD, SWITCHING_EXTRUDER, SWITCHING_NOZZLE, SPINDLE_SERVO)
37 37
     #if NUM_SERVOS <= Z_PROBE_SERVO_NR
38 38
       #undef NUM_SERVOS
39 39
       #define NUM_SERVOS (Z_PROBE_SERVO_NR + 1)
@@ -62,6 +62,10 @@
62 62
       #undef NUM_SERVOS
63 63
       #define NUM_SERVOS (SWITCHING_EXTRUDER_E23_SERVO_NR + 1)
64 64
     #endif
65
+    #if NUM_SERVOS <= SPINDLE_SERVO_NR
66
+      #undef NUM_SERVOS
67
+      #define NUM_SERVOS (SPINDLE_SERVO_NR + 1)
68
+    #endif
65 69
   #endif
66 70
 #endif
67 71
 

+ 4
- 4
Marlin/src/inc/SanityCheck.h View File

@@ -3007,8 +3007,8 @@ static_assert(   _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
3007 3007
 #if HAS_CUTTER
3008 3008
   #ifndef CUTTER_POWER_UNIT
3009 3009
     #error "CUTTER_POWER_UNIT is required with a spindle or laser. Please update your Configuration_adv.h."
3010
-  #elif !CUTTER_UNIT_IS(PWM255) && !CUTTER_UNIT_IS(PERCENT) && !CUTTER_UNIT_IS(RPM)
3011
-    #error "CUTTER_POWER_UNIT must be PWM255, PERCENT, or RPM. Please update your Configuration_adv.h."
3010
+  #elif !CUTTER_UNIT_IS(PWM255) && !CUTTER_UNIT_IS(PERCENT) && !CUTTER_UNIT_IS(RPM) && !CUTTER_UNIT_IS(SERVO)
3011
+    #error "CUTTER_POWER_UNIT must be PWM255, PERCENT, RPM, or SERVO. Please update your Configuration_adv.h."
3012 3012
   #endif
3013 3013
 
3014 3014
   #if ENABLED(LASER_POWER_INLINE)
@@ -3047,8 +3047,8 @@ static_assert(   _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
3047 3047
   #define _PIN_CONFLICT(P) (PIN_EXISTS(P) && P##_PIN == SPINDLE_LASER_PWM_PIN)
3048 3048
   #if BOTH(SPINDLE_FEATURE, LASER_FEATURE)
3049 3049
     #error "Enable only one of SPINDLE_FEATURE or LASER_FEATURE."
3050
-  #elif !PIN_EXISTS(SPINDLE_LASER_ENA)
3051
-    #error "(SPINDLE|LASER)_FEATURE requires SPINDLE_LASER_ENA_PIN."
3050
+  #elif !PIN_EXISTS(SPINDLE_LASER_ENA) && DISABLED(SPINDLE_SERVO)
3051
+    #error "(SPINDLE|LASER)_FEATURE requires SPINDLE_LASER_ENA_PIN or SPINDLE_SERVO to control the power."
3052 3052
   #elif ENABLED(SPINDLE_CHANGE_DIR) && !PIN_EXISTS(SPINDLE_DIR)
3053 3053
     #error "SPINDLE_DIR_PIN is required for SPINDLE_CHANGE_DIR."
3054 3054
   #elif ENABLED(SPINDLE_LASER_PWM)

Loading…
Cancel
Save