DIY使用Arduino給3D打印機增加完事後自動關機功能

大家都知道,打印完畢一個模型通常都需要好幾個小時甚至幾十個小時,人總不能一直盯着吧。如果打印完畢後不及時關機,一方面持續耗電,一方面也降低設備壽命;在家中持續發出聲光對家人也有一定影響。

我使用的是極光爾沃的Z603打印機,精度不錯,但是不具備打印完事後自動關機的功能。於是自己動手給它製作了一個自動關機模塊。

首先上圖,這是個模塊結構示意圖:


圖中只有手動開關和指示燈是顯現在機箱外部的,其他均隱藏在機箱內部會邊框內,不會影響外觀。

其中Arduino模塊作爲總控制系統,接收來自輕觸開關或手動開關的指令,以決定是否該通過繼電器控制220v電源斷電。降壓模塊是借用打印機24v內置開關電源降壓後給Arduino供電。指示燈用來指示當前狀態。

電路圖如下:


該圖已經很清楚了,就不再詳細敘述了。

控制原理就是:

1. 用戶通過原開關開機後,Arduino上電,程序控制繼電器閉合,此時用戶可以關閉原開關,依靠繼電器維持打印機繼續工作。此時LED燈常亮。

2. 當打印機打印完畢後,打印機會自動移動噴嘴y軸滑塊到最大邊緣位置,此時會觸動和壓住輕觸開關(開關固定在一個海綿座上,防止壓力過大造成損壞),此時Arduino會監測到此事件,開始持續每秒閃爍LED一次。繼續判斷該開關是否持續按壓30s(因爲有時候打印模型時也可能會短時間到達y軸最大位置,防止誤關機)。30s時間到,則Arduino控制LED快速閃爍3次,控制繼電器關閉總電源。

3. 如果用戶隨時想關機,可以按下手動開關。爲了防止誤碰開關造成關機,此處程序判斷需要持續按下該開關3s,系統纔會快速閃爍LED 3次,然後控制繼電器關閉總電源。


下面是實際改裝過程圖:

(1)降壓模塊,固定在風扇螺絲上



(2)兩個繼電器用膠布纏在一起,固定在開關附近



(3)燒錄程序並焊接完成的Arduino模塊,以及自己打印的LED與開關控制盒


(4)Arduino放入阻燃盒



(5)最終佈線完畢,僅留下LED和開關控制盒在外部,美觀&方便



下面是Arudino程序代碼:

/* 
 * 3D Printer AutoPowerDown
 * Copyright [email protected]
 * 2017-6-28
*/

const int triggerButtonPin = 9;     // 限位觸發按鈕
const int manualButtonPin = 3;      // 手動關機按鈕
const int relayPin =  2;            // 繼電器
const int ledPin =  8;              // the number of the LED pin

const int LOOP_DELAY_MSECONDS =  100;           //每次循環毫秒數
const int TRIGGER_POWERDOWN_MSECONDS =  30000;  //觸發按鈕多長時間關機

int triggerButtonState = 0;         // variable for reading the pushbutton status
int manualButtonState = 0;          // variable for reading the pushbutton status
int continuousTriggerCount = 0;     //連續按下觸發按鈕的計數(時間)


void setup() {
  
  // 開啓串行通信,並設置其頻率爲9600。
  Serial.begin(9600);
  int nTry = 0;
  while (!Serial) {    
    nTry ++;
    delay(50); // wait for serial port to connect. Needed for native USB port only
    if(nTry > 20) //防止針對部分計算機和手機無法打開串口造成死鎖
      break;
  }
   
  
  // 初始化LED和繼電器
  pinMode(ledPin, OUTPUT);
  pinMode(relayPin, OUTPUT);
  
  // 並設置使用內部上拉電阻(注意,這裏使用內置的上拉電阻,無需再自己串聯電阻,但需要將button連接到GRND而不是5V,同時按下按鈕的電平狀態正好相反)
  pinMode(triggerButtonPin, INPUT_PULLUP);
  pinMode(manualButtonPin, INPUT_PULLUP);

  
  delay(1000);
  
  digitalWrite(ledPin, HIGH);
  digitalWrite(relayPin, HIGH);
  
  Serial.println("done.");
}

void loop() { 
  
  delay(LOOP_DELAY_MSECONDS);

  triggerButtonState = !digitalRead(triggerButtonPin); //將狀態取反使用更方便
  manualButtonState = !digitalRead(manualButtonPin); //將狀態取反使用更方便

  //如果什麼按鈕都沒有按下
  if ((triggerButtonState == LOW) && (manualButtonState == LOW)) {
    continuousTriggerCount = 0;
    return;
  } 
  
  Serial.print("t:");
  Serial.print(triggerButtonState);
  Serial.print("  m:");
  Serial.println(manualButtonState);
  
  Serial.print("continuousTriggerCount:");
  Serial.println(continuousTriggerCount);

  //如果按下了觸發按鈕
  if (triggerButtonState == HIGH)
  {
    continuousTriggerCount += 21;
    
    //連續觸發按鈕時間達到了關機條件
    if(continuousTriggerCount * LOOP_DELAY_MSECONDS > TRIGGER_POWERDOWN_MSECONDS)
    { 
      Serial.println("Prepare Powerdown ... ");
      
      //閃爍LED 5次
      for(int i=0;i<5;i++)
      { 
        digitalWrite(ledPin, LOW);
        delay(200); 
        digitalWrite(ledPin, HIGH);
        delay(200); 
      }
      //關閉繼電器
      digitalWrite(relayPin, LOW);
      digitalWrite(ledPin, LOW);

      
      Serial.println("Powerdowned.");
      delay(50000);       
    }
    
    digitalWrite(ledPin, LOW);
    delay(1000); 
    digitalWrite(ledPin, HIGH);
    delay(1000); 


  } 


  //如果按下了手動關機按鈕(持續3s會關機)
  if (manualButtonState == HIGH)
  {    
    continuousTriggerCount += 9; //30000/(9*1000)需要長按大約3s會關機
  
    //連續觸發按鈕時間達到了關機條件
    if(continuousTriggerCount * LOOP_DELAY_MSECONDS > TRIGGER_POWERDOWN_MSECONDS)
    {
      Serial.println("Soon will powerdown ... ");
      
      //閃爍LED 5次
      for(int i=0;i<5;i++)
      { 
        digitalWrite(ledPin, LOW);
        delay(200); 
        digitalWrite(ledPin, HIGH);
        delay(200); 
      }
      //關閉繼電器
      digitalWrite(relayPin, LOW);
      digitalWrite(ledPin, LOW);
      
      Serial.println("Powerdowned.");
      delay(50000);    
      
    } 
  }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章