Welcome! Log In Create A New Profile

Advanced

SKR 1.3 Bed Enable Pin (Extra failsafe for the failsafe)

Posted by ngen33r 
SKR 1.3 Bed Enable Pin (Extra failsafe for the failsafe)
June 18, 2024 09:28PM
I know this has been mentioned a few times, but there has not been an answer. I have 2 seperate issues that I am struggling with.
1. I cannot seem to get the IO pins to respond to M42 despite having it enabled in firmware. I have tried a couple pins and the diag screen does not let me swap them to Output or change the state and these are not protected pins.
2. I want to add an extra fail-safe into the firmware for Bed Enable. I am using a 120V bed that is fused, fed through a relay to an SSR with a thermal switch in series. I have worked with thermal switches on industrial equipment and they too can fail to open, although rare, it can happen and I have seen it happen. Yes I could run 2 of them in series, but I have a relay that I want to use that is opto-isolated and will keep the power off to the bed at all times unless a print is happenning. I have looked at the code, but I am not well versed in C++. I would like to add the enable trigger in the start and stop heat bed code and also add it to the kill code.

For the KILL code it seems like it could go in several places, not sure what one.
void Temperature::_temp_error(const heater_id_t heater_id, FSTR_P const serial_msg, FSTR_P const lcd_msg) {

  static uint8_t killed = 0;

  if (IsRunning() && TERN1(BOGUS_TEMPERATURE_GRACE_PERIOD, killed == 2)) {
    SERIAL_ERROR_START();
    SERIAL_ECHOF(serial_msg);
    SERIAL_ECHOPGM(STR_STOPPED_HEATER);

    heater_id_t real_heater_id = heater_id;

    #if HAS_TEMP_REDUNDANT
      if (heater_id == H_REDUNDANT) {
        SERIAL_ECHOPGM(STR_REDUNDANT); // print redundant and cascade to print target, too.
        real_heater_id = (heater_id_t)HEATER_ID(TEMP_SENSOR_REDUNDANT_TARGET);
      }
    #endif

    switch (real_heater_id) {
      OPTCODE(HAS_TEMP_COOLER,  case H_COOLER:  SERIAL_ECHOPGM(STR_COOLER);         break)
      OPTCODE(HAS_TEMP_PROBE,   case H_PROBE:   SERIAL_ECHOPGM(STR_PROBE);          break)
      OPTCODE(HAS_TEMP_BOARD,   case H_BOARD:   SERIAL_ECHOPGM(STR_MOTHERBOARD);    break)
      OPTCODE(HAS_TEMP_CHAMBER, case H_CHAMBER: SERIAL_ECHOPGM(STR_HEATER_CHAMBER); break)
      OPTCODE(HAS_TEMP_BED,     case H_BED:     SERIAL_ECHOPGM(STR_HEATER_BED);     break)
      default:
        if (real_heater_id >= 0) SERIAL_ECHOLNPGM("E", real_heater_id);
    }
    SERIAL_EOL();
  }

  disable_all_heaters(); // always disable (even for bogus temp)
  hal.watchdog_refresh();

  #if BOGUS_TEMPERATURE_GRACE_PERIOD
    const millis_t ms = millis();
    static millis_t expire_ms;
    switch (killed) {
      case 0:
        expire_ms = ms + BOGUS_TEMPERATURE_GRACE_PERIOD;
        ++killed;
        break;
      case 1:
        if (ELAPSED(ms, expire_ms)) ++killed;
        break;
      case 2:
        loud_kill(lcd_msg, heater_id);
        ++killed;
        break;
    }
  #elif defined(BOGUS_TEMPERATURE_GRACE_PERIOD)
    UNUSED(killed);
  #else
    if (!killed) { killed = 1; loud_kill(lcd_msg, heater_id); }
  #endif
}

OR

void Temperature::disable_all_heaters() {

  // Disable autotemp, unpause and reset everything
  TERN_(AUTOTEMP, planner.autotemp_enabled = false);
  TERN_(PROBING_HEATERS_OFF, pause_heaters(false));

  #if HAS_HOTEND
    HOTEND_LOOP() {
      setTargetHotend(0, e);
      temp_hotend[e].soft_pwm_amount = 0;
    }
  #endif

  #if HAS_TEMP_HOTEND
    #define DISABLE_HEATER(N) WRITE_HEATER_##N(LOW);
    REPEAT(HOTENDS, DISABLE_HEATER);
  #endif

  #if HAS_HEATED_BED
    setTargetBed(0);
    temp_bed.soft_pwm_amount = 0;
    WRITE_HEATER_BED(LOW);
  #endif

  #if HAS_HEATED_CHAMBER
    setTargetChamber(0);
    temp_chamber.soft_pwm_amount = 0;
    WRITE_HEATER_CHAMBER(LOW);
  #endif

  #if HAS_COOLER
    setTargetCooler(0);
    temp_cooler.soft_pwm_amount = 0;
    WRITE_HEATER_COOLER(LOW);
  #endif
}

For the bed enable maybe and if statement here for enable if (celsius) BED_ENABLE_PIN = 1; or add it to the power manager?

static void setTargetBed(const celsius_t celsius) {
        TERN_(AUTO_POWER_CONTROL, if (celsius) powerManager.power_on());
        temp_bed.target = _MIN(celsius, BED_MAX_TARGET);
        start_watching_bed();
      }

I think I am on the right path, I just want one of the code wizzards to verify. I'd also like to find out why pin control seems to not be working.
Re: SKR 1.3 Bed Relay Enable Pin (Extra failsafe for SSR)
August 22, 2024 01:03AM
I finally had the time to get this working and tested. MARLIN 2.1.2.2

**USE AT YOUR OWN RISK**

I used pin 1.10 since I am using the 3 motor expansion for the Z axis and I do not have a driver in that socket. 1.10 is for Z UART, but any unprotected pin can be used or even a protected one with some other modifications. If you are using an Amazon cheapo relay, you will have to change the 10K resistor on the signal line. 10K @ 3.3V only gives about 0.22mA. That is not enough to trigger the opto. I went with 1K. That gives me 2mA of draw on the pin.

Code additions:

Configuration_adv.h
#define HEATED_BED_RELAY
#define HEATED_BED_RELAY_PIN P1_10

pins_BTT_SKR_V1_3.h
Add the following and make sure if the pin has another function that it is commented out.
#define HEATED_BED_RELAY_PIN P1_10

temperature.cpp
Add to this function below the heated bed code.
  void Temperature::disable_all_heaters() {
 
. #if HAS_HEATED_BED
    setTargetBed(0);
    temp_bed.soft_pwm_amount = 0;
    WRITE_HEATER_BED(LOW);

 //TURN OFF BED RELAY
   #if ENABLED(HEATED_BED_RELAY)
    WRITE(HEATED_BED_RELAY_PIN, LOW); // Turn off the heated bed relay
  #endif
  //BED RELAY
temperature.h
 static void setTargetBed(const celsius_t celsius) {
        TERN_(AUTO_POWER_CONTROL, if (celsius) powerManager.power_on());
        temp_bed.target = _MIN(celsius, BED_MAX_TARGET);
		
		//BED RELAY CONTROL ADDED HERE
		#if ENABLED(HEATED_BED_RELAY)
			if (celsius > 0) {
			WRITE(HEATED_BED_RELAY_PIN, HIGH); // Turn on the relay when bed is heating
		} else {
			WRITE(HEATED_BED_RELAY_PIN, LOW);  // Turn off the relay when bed heating is off
		}
		#endif
		//BED RELAY CONTROL
		
        start_watching_bed();
      }

MarlinCore.cpp
void setup() {
  #ifdef FASTIO_INIT
    FASTIO_INIT();
  #endif
   
  //MAKE SURE BED RELAY IS OFF ON START
  SET_OUTPUT(HEATED_BED_RELAY_PIN);
  WRITE(HEATED_BED_RELAY_PIN,0);

Edited 3 time(s). Last edit at 08/22/2024 10:55AM by ngen33r.
Sorry, only registered users may post in this forum.

Click here to login