Bläddra i källkod

SOFT_PWM: Implement dithering if SOFT_PWM_SCALE is 1 or more

If dithering is enabled, the remainder of the soft_pwm_X duty value at
turnoff time is added to the next cycle. If e.g. the duty is set to 9 and
SCALE is set to 2, the PWM will be active for 8 counts for 3 cycles and
12 counts on each fourth cycle, i.e. the average is 9 cycles.

This compensates the resolution loss at higher scales and allows running
fans with SOFT_PWM with significantly reduced noise.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Stefan Brüns 7 år sedan
förälder
incheckning
35a55d5757
2 ändrade filer med 32 tillägg och 18 borttagningar
  1. 6
    0
      Marlin/Configuration.h
  2. 26
    18
      Marlin/temperature.cpp

+ 6
- 0
Marlin/Configuration.h Visa fil

@@ -1424,6 +1424,12 @@
1424 1424
 // at zero value, there are 128 effective control positions.
1425 1425
 #define SOFT_PWM_SCALE 0
1426 1426
 
1427
+// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can
1428
+// be used to mitigate the associated resolution loss. If enabled,
1429
+// some of the PWM cycles are stretched so on average the wanted
1430
+// duty cycle is attained.
1431
+//#define SOFT_PWM_DITHER
1432
+
1427 1433
 // Temperature status LEDs that display the hotend and bed temperature.
1428 1434
 // If all hotends and bed temperature and temperature setpoint are < 54C then the BLUE led is on.
1429 1435
 // Otherwise the RED led is on. There is 1C hysteresis.

+ 26
- 18
Marlin/temperature.cpp Visa fil

@@ -1521,7 +1521,7 @@ void Temperature::isr() {
1521 1521
       static uint8_t state_heater_ ## n = 0; \
1522 1522
       static uint8_t state_timer_heater_ ## n = 0
1523 1523
   #else
1524
-    #define ISR_STATICS(n) static uint8_t soft_pwm_ ## n
1524
+    #define ISR_STATICS(n) static uint8_t soft_pwm_ ## n = 0
1525 1525
   #endif
1526 1526
 
1527 1527
   // Statics per heater
@@ -1544,43 +1544,51 @@ void Temperature::isr() {
1544 1544
   #endif
1545 1545
 
1546 1546
   #if DISABLED(SLOW_PWM_HEATERS)
1547
+    constexpr uint8_t pwm_mask =
1548
+      #if ENABLED(SOFT_PWM_DITHER)
1549
+        _BV(SOFT_PWM_SCALE) - 1
1550
+      #else
1551
+        0
1552
+      #endif
1553
+    ;
1554
+
1547 1555
     /**
1548 1556
      * Standard PWM modulation
1549 1557
      */
1550 1558
     if (pwm_count >= 127) {
1551
-      pwm_count = 0;
1552
-      soft_pwm_0 = soft_pwm[0];
1553
-      WRITE_HEATER_0(soft_pwm_0 > 0 ? HIGH : LOW);
1559
+      pwm_count -= 127;
1560
+      soft_pwm_0 = (soft_pwm_0 & pwm_mask) + soft_pwm[0];
1561
+      WRITE_HEATER_0(soft_pwm_0 > pwm_mask ? HIGH : LOW);
1554 1562
       #if HOTENDS > 1
1555
-        soft_pwm_1 = soft_pwm[1];
1556
-        WRITE_HEATER_1(soft_pwm_1 > 0 ? HIGH : LOW);
1563
+        soft_pwm_1 = (soft_pwm_1 & pwm_mask) + soft_pwm[1];
1564
+        WRITE_HEATER_1(soft_pwm_1 > pwm_mask ? HIGH : LOW);
1557 1565
         #if HOTENDS > 2
1558
-          soft_pwm_2 = soft_pwm[2];
1559
-          WRITE_HEATER_2(soft_pwm_2 > 0 ? HIGH : LOW);
1566
+          soft_pwm_2 = (soft_pwm_2 & pwm_mask) + soft_pwm[2];
1567
+          WRITE_HEATER_2(soft_pwm_2 > pwm_mask ? HIGH : LOW);
1560 1568
           #if HOTENDS > 3
1561
-            soft_pwm_3 = soft_pwm[3];
1562
-            WRITE_HEATER_3(soft_pwm_3 > 0 ? HIGH : LOW);
1569
+            soft_pwm_3 = (soft_pwm_3 & pwm_mask) + soft_pwm[3];
1570
+            WRITE_HEATER_3(soft_pwm_3 > pwm_mask ? HIGH : LOW);
1563 1571
           #endif
1564 1572
         #endif
1565 1573
       #endif
1566 1574
 
1567 1575
       #if HAS_HEATER_BED
1568
-        soft_pwm_BED = soft_pwm_bed;
1569
-        WRITE_HEATER_BED(soft_pwm_BED > 0 ? HIGH : LOW);
1576
+        soft_pwm_BED = (soft_pwm_BED & pwm_mask) + soft_pwm_bed;
1577
+        WRITE_HEATER_BED(soft_pwm_BED > pwm_mask ? HIGH : LOW);
1570 1578
       #endif
1571 1579
 
1572 1580
       #if ENABLED(FAN_SOFT_PWM)
1573 1581
         #if HAS_FAN0
1574
-          soft_pwm_fan[0] = fanSpeedSoftPwm[0] >> 1;
1575
-          WRITE_FAN(soft_pwm_fan[0] > 0 ? HIGH : LOW);
1582
+          soft_pwm_fan[0] = (soft_pwm_fan[0] & pwm_mask) + fanSpeedSoftPwm[0] >> 1;
1583
+          WRITE_FAN(soft_pwm_fan[0] > pwm_mask ? HIGH : LOW);
1576 1584
         #endif
1577 1585
         #if HAS_FAN1
1578
-          soft_pwm_fan[1] = fanSpeedSoftPwm[1] >> 1;
1579
-          WRITE_FAN1(soft_pwm_fan[1] > 0 ? HIGH : LOW);
1586
+          soft_pwm_fan[1] = (soft_pwm_fan[1] & pwm_mask) + fanSpeedSoftPwm[1] >> 1;
1587
+          WRITE_FAN1(soft_pwm_fan[1] > pwm_mask ? HIGH : LOW);
1580 1588
         #endif
1581 1589
         #if HAS_FAN2
1582
-          soft_pwm_fan[2] = fanSpeedSoftPwm[2] >> 1;
1583
-          WRITE_FAN2(soft_pwm_fan[2] > 0 ? HIGH : LOW);
1590
+          soft_pwm_fan[2] = (soft_pwm_fan[2] & pwm_mask) + fanSpeedSoftPwm[2] >> 1;
1591
+          WRITE_FAN2(soft_pwm_fan[2] > pwm_mask ? HIGH : LOW);
1584 1592
         #endif
1585 1593
       #endif
1586 1594
     }

Laddar…
Avbryt
Spara