Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] support >3 fans in Marlin 2.0 #12961

Closed
Bougakov opened this issue Jan 19, 2019 · 8 comments
Closed

[FR] support >3 fans in Marlin 2.0 #12961

Bougakov opened this issue Jan 19, 2019 · 8 comments
Labels
T: Feature Request Features requested by users.

Comments

@Bougakov
Copy link

Bougakov commented Jan 19, 2019

This is a feature request. Marlin 2.0 bugfix source provides support for up to 5 extruders but only for up to 3 fans.

Additional "fan" outputs might be used to drive extra equipment: in my case it is a secondary extruder head assembly that carries a 405nm laser and micro drill (for making PCBs using resist film from clean copper boards).

Interchangeable heads

Unfortunately, adding such support requires the user to make significant amount of changes in multiple files which takes a lot of effort.

I suggest to support equal number of fans and extruders - five. This will allow users to implement advanced confiurations while the "laser overhaul" (#11576 (comment)) is not finished. In my case the following modifications were needed:

In board's pin definition file:

#define E0_AUTO_FAN_PIN     9
#define FAN1_PIN            8
#define FAN2_PIN            5 // Previously left "servo" pin, currently laser
#define FAN3_PIN            3 // Previously right "servo" pin, currently a micro drill

in pins.h

#ifndef FAN_PIN
  #define FAN_PIN -1
#endif
#ifndef FAN1_PIN
  #define FAN1_PIN -1
#endif
#ifndef FAN2_PIN
  #define FAN2_PIN -1
#endif
#ifndef FAN3_PIN // More fans
  #define FAN3_PIN -1
#endif
#ifndef FAN4_PIN // More fans
  #define FAN4_PIN -1
#endif
#ifndef FAN5_PIN // More fans
  #define FAN5_PIN -1
#endif

in Conditionals-post.h:

/**
 * Up to 3 PWM fans
 */
#if HAS_FAN5 // More fans
  #define FAN_COUNT 6 
#elif HAS_FAN4 // More fans
  #define FAN_COUNT 5 
#elif HAS_FAN3 // More fans
  #define FAN_COUNT 4 
#elif HAS_FAN2
  #define FAN_COUNT 3
#elif HAS_FAN1
  #define FAN_COUNT 2
#elif HAS_FAN0
  #define FAN_COUNT 1
#else
  #define FAN_COUNT 0
#endif

#if HAS_FAN0
  #define WRITE_FAN(v) WRITE(FAN_PIN, v)
  #define WRITE_FAN0(v) WRITE_FAN(v)
#endif
#if HAS_FAN1
  #define WRITE_FAN1(v) WRITE(FAN1_PIN, v)
#endif
#if HAS_FAN2
  #define WRITE_FAN2(v) WRITE(FAN2_PIN, v)
#endif
#if HAS_FAN3 // More fans
  #define WRITE_FAN3(v) WRITE(FAN3_PIN, v)
#endif
#if HAS_FAN4 // More fans
  #define WRITE_FAN4(v) WRITE(FAN4_PIN, v)
#endif
#if HAS_FAN5 // More fans
  #define WRITE_FAN5(v) WRITE(FAN5_PIN, v)
#endif
#define WRITE_FAN_N(n, v) WRITE_FAN##n(v)

// Other fans
#define HAS_FAN0 (PIN_EXISTS(FAN))
#define HAS_FAN1 (PIN_EXISTS(FAN1) && CONTROLLER_FAN_PIN != FAN1_PIN && E0_AUTO_FAN_PIN != FAN1_PIN && E1_AUTO_FAN_PIN != FAN1_PIN && E2_AUTO_FAN_PIN != FAN1_PIN && E3_AUTO_FAN_PIN != FAN1_PIN && E4_AUTO_FAN_PIN != FAN1_PIN && E5_AUTO_FAN_PIN != FAN1_PIN)
#define HAS_FAN2 (PIN_EXISTS(FAN2) && CONTROLLER_FAN_PIN != FAN2_PIN && E0_AUTO_FAN_PIN != FAN2_PIN && E1_AUTO_FAN_PIN != FAN2_PIN && E2_AUTO_FAN_PIN != FAN2_PIN && E3_AUTO_FAN_PIN != FAN2_PIN && E4_AUTO_FAN_PIN != FAN2_PIN && E5_AUTO_FAN_PIN != FAN2_PIN)
#define HAS_FAN3 (PIN_EXISTS(FAN3) && CONTROLLER_FAN_PIN != FAN3_PIN && E0_AUTO_FAN_PIN != FAN3_PIN && E1_AUTO_FAN_PIN != FAN3_PIN && E2_AUTO_FAN_PIN != FAN3_PIN && E3_AUTO_FAN_PIN != FAN3_PIN && E4_AUTO_FAN_PIN != FAN3_PIN && E5_AUTO_FAN_PIN != FAN3_PIN) // More fans
#define HAS_FAN4 (PIN_EXISTS(FAN4) && CONTROLLER_FAN_PIN != FAN4_PIN && E0_AUTO_FAN_PIN != FAN4_PIN && E1_AUTO_FAN_PIN != FAN4_PIN && E2_AUTO_FAN_PIN != FAN4_PIN && E3_AUTO_FAN_PIN != FAN4_PIN && E4_AUTO_FAN_PIN != FAN4_PIN && E5_AUTO_FAN_PIN != FAN4_PIN) // More fans
#define HAS_FAN5 (PIN_EXISTS(FAN5) && CONTROLLER_FAN_PIN != FAN5_PIN && E0_AUTO_FAN_PIN != FAN5_PIN && E1_AUTO_FAN_PIN != FAN5_PIN && E2_AUTO_FAN_PIN != FAN5_PIN && E3_AUTO_FAN_PIN != FAN5_PIN && E4_AUTO_FAN_PIN != FAN5_PIN && E5_AUTO_FAN_PIN != FAN5_PIN) // More fans

in M42.cpp:

  #if FAN_COUNT > 0
    switch (pin) {
      #if HAS_FAN0
        case FAN_PIN: fan_speed[0] = pin_status; break;
      #endif
      #if HAS_FAN1
        case FAN1_PIN: fan_speed[1] = pin_status; break;
      #endif
      #if HAS_FAN2
        case FAN2_PIN: fan_speed[2] = pin_status; break;
      #endif
      #if HAS_FAN3 // More fans
        case FAN3_PIN: fan_speed[3] = pin_status; break;
      #endif
      #if HAS_FAN4 // More fans
        case FAN4_PIN: fan_speed[4] = pin_status; break;
      #endif
      #if HAS_FAN5 // More fans
        case FAN5_PIN: fan_speed[5] = pin_status; break;
      #endif
    }
  #endif
}

in planner.cpp:

  #if FAN_COUNT > 0

    #if FAN_KICKSTART_TIME > 0

      static millis_t fan_kick_end[FAN_COUNT] = { 0 };

      #define KICKSTART_FAN(f) \
        if (tail_fan_speed[f]) { \
          millis_t ms = millis(); \
          if (fan_kick_end[f] == 0) { \
            fan_kick_end[f] = ms + FAN_KICKSTART_TIME; \
            tail_fan_speed[f] = 255; \
          } else if (PENDING(ms, fan_kick_end[f])) \
            tail_fan_speed[f] = 255; \
        } else fan_kick_end[f] = 0

      #if HAS_FAN0
        KICKSTART_FAN(0);
      #endif
      #if HAS_FAN1
        KICKSTART_FAN(1);
      #endif
      #if HAS_FAN2
        KICKSTART_FAN(2); // Consider disabling this if this "fan" output is used to drive a laser diode and not an electric motor
      #endif
      #if HAS_FAN3 // More fans 
        KICKSTART_FAN(3);
      #endif
      #if HAS_FAN4 // More fans 
        KICKSTART_FAN(4);
      #endif
      #if HAS_FAN5 // More fans 
        KICKSTART_FAN(5);
      #endif

    #endif // FAN_KICKSTART_TIME > 0

    #if FAN_MIN_PWM != 0 || FAN_MAX_PWM != 255
      #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? map(tail_fan_speed[f], 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : 0)
    #else
      #define CALC_FAN_SPEED(f) tail_fan_speed[f]
    #endif

    #if ENABLED(FAN_SOFT_PWM)
      #if HAS_FAN0
        thermalManager.soft_pwm_amount_fan[0] = CALC_FAN_SPEED(0);
      #endif
      #if HAS_FAN1
        thermalManager.soft_pwm_amount_fan[1] = CALC_FAN_SPEED(1);
      #endif
      #if HAS_FAN2 // More fans
        thermalManager.soft_pwm_amount_fan[2] = CALC_FAN_SPEED(2);
      #endif
      #if HAS_FAN3 // More fans
        thermalManager.soft_pwm_amount_fan[3] = CALC_FAN_SPEED(3);
      #endif
      #if HAS_FAN4 // More fans
        thermalManager.soft_pwm_amount_fan[4] = CALC_FAN_SPEED(4);
      #endif
      #if HAS_FAN5 // More fans
        thermalManager.soft_pwm_amount_fan[5] = CALC_FAN_SPEED(5);
      #endif
    #else
      #if HAS_FAN0
        analogWrite(FAN_PIN, CALC_FAN_SPEED(0));
      #endif
      #if HAS_FAN1
        analogWrite(FAN1_PIN, CALC_FAN_SPEED(1));
      #endif
      #if HAS_FAN2
        analogWrite(FAN2_PIN, CALC_FAN_SPEED(2));
      #endif
      #if HAS_FAN3 // More fans
        analogWrite(FAN3_PIN, CALC_FAN_SPEED(3));
      #endif
      #if HAS_FAN4 // More fans
        analogWrite(FAN4_PIN, CALC_FAN_SPEED(4));
      #endif
      #if HAS_FAN5 // More fans
        analogWrite(FAN5_PIN, CALC_FAN_SPEED(5));
      #endif

	  #endif

  #endif // FAN_COUNT > 0

in temperature.cpp:

  #if HAS_FAN3 // More fans
    SET_OUTPUT(FAN3_PIN);
    #if ENABLED(FAST_PWM_FAN)
      setPwmFrequency(FAN3_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
    #endif
  #endif

  #if HAS_FAN4 // More fans
    SET_OUTPUT(FAN4_PIN);
    #if ENABLED(FAST_PWM_FAN)
      setPwmFrequency(FAN4_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
    #endif
  #endif
 
  #if HAS_FAN5 // More fans
    SET_OUTPUT(FAN5_PIN);
    #if ENABLED(FAST_PWM_FAN)
      setPwmFrequency(FAN5_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
    #endif
  #endif

in ultralcd_HD44780.cpp:

      #if FAN_COUNT > 0
        if (0
          #if HAS_FAN0
            || fan_speed[0]
          #endif
          #if HAS_FAN1
            || fan_speed[1]
          #endif
          #if HAS_FAN2
            || fan_speed[2]
          #endif
          #if HAS_FAN3 // More fans
            || fan_speed[3]
          #endif
          #if HAS_FAN4 // More fans
            || fan_speed[4]
          #endif
          #if HAS_FAN5 // More fans
            || fan_speed[5]
          #endif
		  ) leds |= LED_C;
      #endif // FAN_COUNT > 0

in menu_temperature.cpp:

    #if HAS_FAN3 // More fans
      MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_FAN_SPEED " 4", &fan_speed[3], 0, 255);
      #if ENABLED(EXTRA_FAN_SPEED)
        MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_EXTRA_FAN_SPEED " 4", &new_fan_speed[3], 3, 255);
      #endif
    #endif
    #if HAS_FAN4 // More fans
      MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_FAN_SPEED " 5", &fan_speed[4], 0, 255);
      #if ENABLED(EXTRA_FAN_SPEED)
        MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_EXTRA_FAN_SPEED " 5", &new_fan_speed[4], 3, 255);
      #endif
    #endif
    #if HAS_FAN5 // More fans
      MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_FAN_SPEED " 6", &fan_speed[5], 0, 255);
      #if ENABLED(EXTRA_FAN_SPEED)
        MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_EXTRA_FAN_SPEED " 6", &new_fan_speed[5], 3, 255);
      #endif
    #endif
	#endif // FAN_COUNT > 0

in menu_tune.cpp:

    #if HAS_FAN3 // More fans
      MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_FAN_SPEED " 4", &fan_speed[3], 0, 255);
      #if ENABLED(EXTRA_FAN_SPEED)
        MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_EXTRA_FAN_SPEED " 4", &new_fan_speed[3], 3, 255);
      #endif
    #endif
    #if HAS_FAN4 // More fans
      MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_FAN_SPEED " 5", &fan_speed[4], 0, 255);
      #if ENABLED(EXTRA_FAN_SPEED)
        MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_EXTRA_FAN_SPEED " 5", &new_fan_speed[4], 3, 255);
      #endif
    #endif
    #if HAS_FAN5 // More fans
      MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_FAN_SPEED " 6", &fan_speed[5], 0, 255);
      #if ENABLED(EXTRA_FAN_SPEED)
        MENU_MULTIPLIER_ITEM_EDIT(int8, MSG_EXTRA_FAN_SPEED " 6", &new_fan_speed[5], 3, 255);
      #endif
    #endif
    #endif // FAN_COUNT > 0

and, finally, in sensitive_pins.h:

#if PIN_EXISTS(FAN3) // More fans
  #define _FAN3 FAN3_PIN,
#else
  #define _FAN3
#endif
#if PIN_EXISTS(FAN4) // More fans
  #define _FAN4 FAN4_PIN,
#else
  #define _FAN4
#endif
#if PIN_EXISTS(FAN5) // More fans
  #define _FAN5 FAN5_PIN,
#else
  #define _FAN5
#endif
@marcio-ao
Copy link
Contributor

It would also allow you to control lamps: https://www.youtube.com/watch?v=h3pUAb0Q25c :D

@boelle
Copy link
Contributor

boelle commented Jan 23, 2019

i could use this (i think)

i only have 1 extruder but i need to control 1 more fan than the default pins file for the re-arm has

@boelle
Copy link
Contributor

boelle commented Mar 13, 2019

@Bougakov still working on this?

@boelle boelle changed the title Feature request: support >3 fans in Marlin 2.0 [FR] support >3 fans in Marlin 2.0 Oct 24, 2019
@ogland
Copy link

ogland commented Jul 29, 2020

Not sure why this isn't a thing yet. Please make it real.

@ellensp
Copy link
Contributor

ellensp commented Jul 29, 2020

fans 0 through fan 7 have been in marlin for some time...

@ogland
Copy link

ogland commented Jul 29, 2020

Yeah! I just NOW found that out when attempting the same method I did a while back using this: #12961

Turns out it was really straight forward. Weird that the issue isn't closed.

@ellensp
Copy link
Contributor

ellensp commented Jul 29, 2020

I can fix that :)

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Sep 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
T: Feature Request Features requested by users.
Projects
None yet
Development

No branches or pull requests

6 participants