成為樂齡maker

退休三年都在忙房子的事,搞得灰頭土臉比上班還忙。房子蓋好了,卻好像永遠有改善不完的事,投入再多時間都不夠。該告一段落往前走了,若無法全然放下,至少時間的比重也要逐漸減輕。看到樂齡maker這個標題就知道和蓋房子沒多大關係,這是我接下來想走的路想做的事。房子沒蓋好的人,請專注在房子上,不要進入這個領域,以免分心「誤入歧途」!

 

自我期許期Be a maker

Maker 網路翻譯成「自造世代」。Maker簡單的說:就是不分領域、年齡用自己的知識、資源,自己動手打造,實現心中渴望的想法。這比蓋房子仰賴不怎麼令人放心的「專業人士,處處充滿無法掌控的變數受限於人好玩多了。而且退休後不再有太多的得失心,既無「進度的壓力,亦無關「效率,因此更能從容地享受成為maker的樂趣。若因此,能將自己的生活經驗與歲月淬鍊出解決問題的能力繼續應用,不但可以「廢物利用造福自己和家人,聰明才智高者還能造福他人。總之,退休後成為maker的好處多多,個人觀察體驗至少有以下理由支持我成為maker

 

退休者成為 maker的六大理由

1.  充實人生,不虛度光陰。
2.  Maker的樂趣能驅散憂鬱,忘卻煩惱病痛。
3.  符合老年少吃多動的健康法則;動腦可防癡呆、動手可減緩退化。
4.  自娛或實用即可,無關專不專業、卸下得失心,更能自由發揮。
5.  經濟實惠,maker量力而為無須花大錢,成就感遠遠超越感官的快樂。
6.  學習永無止境。做一個海闊天空自由自在的maker,優游於浩瀚的知識與追求無限的智能,滿足學習的渴望與動手圓夢踏實。

 

成為maker,我想做什麼?

鍾鼎山林,各有天性。有人喜歡烹飪美食、有人愛唱歌、有人愛畫畫、有人喜歡木工創作、有人喜歡機械設計。個人自幼對聲光電學情有獨鍾,對音響、控制、微處理器有表淺的涉獵,因此,目標會優先創作與生活相關的機電整合,若行有餘力,會再追求永無止境的音響設計製作。生活中充滿機電的應用,針對這些應用,永遠有做不完的議題、改善不完的缺失、學不完的知識,以及無止境的成長空間。空談無益,先要踏出簡單的一小步,才能引發後續的發展。

 

My first Arduino

Arduino是幫助maker實現構想的利器,是個開放原始碼的設計平台,簡單易學的高階的語言、平易近人的開發環境、強大的功能,加上網路上無窮盡的分享資源,真是令人驚艷。個人一向習慣用8051或PLC,重入江湖,見獵心喜,立刻捨8051&PLC,擁抱新歡Arduino。上Arduino官網發覺它的產品分為五大類,共有21種模組或開發板,選了一片入門板Arduino Nano,在本地網拍網站一片賣260元,一口氣買二塊,三天就到7-11取貨。拆封立刻上Arduino官網下載ARDUINO 1.6.5開發軟體,再快速溜覽一下官網提供的指令集與範例,就開始測試這二塊Arduino Nano,一路順到底,真是如獲至寶。

 

牛刀小試監控抽水馬達

Arduino Nano能做什麼?上網搜尋一下它的硬體結構圖,發現用於一般小型的控制綽綽有餘。我想先解決我的抽水問題,因為附近在蓋大樓,地下水抽的兇,導致地下水水位嚴重下降,我的馬達常會抽不到水,我一直想設計一個保護機制,讓我的馬達抽不到水時能自動切斷電源,並發出警告,以期達到保護馬達、與提醒及早維修的目的,避免水塔內的水用罄才發現馬達早已故障多時。

設計目標概述:
1.啟動異常保護:馬達未於設定時間內完成啟動程序時,進入異常模式給予保護。

2.運轉異常保護:完成啟動後,持續運轉卻未正常進水時,進入異常模式給予保護

3.運轉逾時保護:馬達連續抽水超過預設時間時,進入異常模式給予保護

4.提供ByPASS功能:方便除錯、維修。

 

使用流程圖具體化

把構想具體化是重要的實現步驟,透過這個過程可釐清設計目標,讓後續的硬體、軟體都可根據此步驟所得結果,一一實現。我習慣用流程圖把構想具體表達出來,其優點是,流程圖可以把每一個步驟明確的規劃出來,矛盾衝突之處很容易發現,效率與實現難易度也容易評估;同時也方便日後系統除錯、維護、修改。

 

抽水馬達監控系統流程圖

硬體規劃

    1. 暖身整理抽水馬達配線

想要設計監控抽水馬達,必須先對現場配線與設備充分了解才能規劃設計,為了達到這個目的,整整花了將近一天的時間才把配電箱線路整理好。首先是在IF電源箱和5F水塔之間來回爬了數趟(maker不光是動腦和動手,腿部肌肉也有鍛鍊到),確認各個控制點的配線;接著切斷電源把線路拉出來,用配線架把每條線上架、整理、標示;現場忙完再用Orcad(免費的體驗版就夠用)劃出配線圖。如此肢體運動、腦力激盪後,身體達到陰陽平衡,心理不再掛念理不清的配線,接著要怎麼進行後續處理也胸有成竹,天道酬勤,一夜好眠。

 

整理電源箱配線架與水塔抽水控制配線圖

重整配電箱.jpg  

 

 

水塔抽水控制配線圖

 

2. 設計Arduino I/O介面

要設計I/O介面就要先知道I/O Pin 的驅動能力,在Arduino官網上,Arduino NANO I/O Pin的輸出電流可達40mA。一般而言,很少人自己窩在冷氣房,卻讓微處理器工作得這麼辛苦。個人一向慈悲為懷(對人可不一定),通常會在I/O輸出端加個緩衝級,讓微處理器涼快些,因此1-5mA就很夠用了。本次製作需要2個input Pin用於偵測馬達與進水;2個output Pin用於切斷馬達電源與發出警訊,電路設計如下:

 

a.1st_Input偵測馬達電源:

抽水馬達自動抽水的原理是,當水塔的水位下降至預設的低水位時,水塔內的浮球開關就會ON,於是馬達220V電源接通、馬達開始運轉抽水;開始抽水後,水位會上升、上升至預設的滿水位時,浮球開關就會OFF,於是電源切斷、馬達停止抽水。因此,要監測抽水馬達,就需要產生一個「狀態信號告訴Arduino,「開始或停止抽水啦!」,Arduino收到這個「狀態信號就會啟動後續監控程序。要如何產生這個「狀態信號呢?最簡單的方法就是偵測馬達的220V電源,當偵測到220V電源時就表示馬達電源已經接通,開始抽水啦,反之亦然!偵測220V的方法有很多,我用的方法是用220V電源去驅動光耦合電晶體(手邊正好有4N35),使Arduino D2外部接腳成為LOW2電位,Arduino用輪詢(polling)方式偵測到LOW電位後,就會進行後續的運算。電路很簡單,只是把220V交流電源整流,再加上濾波電容轉成直流電源,這樣就可以讓Arduino D2維持穩定的LOW狀態,不至誤判;因為濾波電容的充放電特性,220V on/off 會有數十ms的延遲,但這對抽水馬達而言可忽略不計。各零件組值計算如手稿圖,基本上歐姆定理就夠用。

 

AC220V偵測電路

ac220detect-1.jpg  

 

b. 2nd_Input偵測水塔進水:

要偵測到水確實有進水塔,最保險的做法是在水塔進水處偵測,現成的感測開關都不太好用,只好自己動手打造一個進水偵測元件,如下圖。動作原理很簡單,水的阻抗大概20kΩ(用指針式三用電表量),我在水塔進水口串入一個彎頭,彎頭嵌入二根白鐵螺絲釘當作偵測探棒。當水流經彎頭時,由於水的阻抗會等效於一個20kΩ的電阻跨接於偵測探棒(白鐵螺絲釘)的二端,形成ib路徑,讓ib流進Q1 ,於是Q1導通、LED亮、Q2 截止(Q2在無進水時ON)、Arduino D3由LOW電位變成HIGH電位(進水啦!),Arduino內部偵測到這個變化,軟體就會進行相關監控程序。

 

自製進水偵測探棒

water-sensor-1.jpg

 

配線組裝圖

 

water-sensor-2.jpg  

 

彎頭內部,當作探測電極的白鐵螺絲釘圖

water-sensor-3.jpg

 

 

組裝完成圖

water-sensor-4.jpg  

 

 

 

水塔進水檢知電路圖

waterDetect-1.jpg 

 

c.1st_Output切斷馬達電源:

當偵測到異常狀況必須切斷馬達電源時,Arduino D7輸出端會拉到HIGH電位,驅動Q3導通,繼電器RL1動作(約需100mA),220V R相電源經RL1動作接點,使馬達的保護電驛MS動作。MS一旦動作,220V R相電源會經由MS本身的動作接點(稱為自保接點)持續送電,讓MS保持動作;另一方面,由於MS常閉接點串入抽水馬達電源控制迴路,MS動作就會切斷馬達電源達到保護的目的。故障排除後,要再次啟動馬達時,由於MS「自保電路會一直保持動作,因此必須把MS的R相,或S相電源斷開,才能使MS釋放,馬達才能重新啟動。

 

保護馬達控制電路圖

relay-1.jpg  

 

d. 2nd_Output發出警訊:

在異常狀況切斷馬達時,系統也要能發出警訊提醒注意,以便及早發覺故障及早維修。發生異常狀況時,Arduino D8輸出端會依記錄異常訊息的變數(Er_code)產生HIGH、LOW電位間歇地變化,發出聲音。考慮一般蜂鳴器的聲音都不太悅耳,因此,我決定用小喇叭來發聲。喇叭驅動電路是採用二個電晶體組成達靈頓電路;由於白天讓人聽到示警即可,因此,不需太大聲,以免夜間擾人,所以我在喇叭端串入一個47Ω限流電阻,讓喇叭小聲些。電路是很簡單的開關電路,輸出的頻率、聲音的長短都由軟體操控,作法非常簡單,一個指令就搞定;由於Q4集極串入一只LED,發出警訊聲時,該LED也會閃爍示警。

Arduino 驅動喇叭發聲電路圖

sp_driver-1.jpg  

 

 

e. by pass 功能:

by pass的功能對複雜的控制系統是很重要的功能,它能快速隔離監控系統的干預,簡化故障判斷。本製作雖然簡單,但是我希望若發生故障,能用by pass功能,回歸原有的抽水系統迴路,維修的水電師傅只要照一般維修抽水馬達的知識就能維修,他不需要了解監控電路,維修時也感覺不到監控電路。為了達到這個目的,整個監控系統中設計時,只在抽水控制迴路中串入一個保護電驛(MS1)的常閉接點,當保護電路驅使保護電驛動作時,該常閉接點開路,抽水馬達電源就被截斷。By pass的作法是,簡單地用一個開關把該常閉接點二端短路,這樣馬達就回歸原有的控制電路,與保護電驛動作與否無關。

 

 by pass電路圖

by pass-1.jpg  

 

完整監控電路圖

  3.設計PCB

Diy PCB一直是令人頭痛的問題,因為量少(通常只有一片),總覺得是曠日廢時的零和遊戲,失敗就得重來。早年用手繪佈局、用膠布製作感光罩、感光、蝕刻、鑽孔,一塊PCB要經過多道手續才能完成。這樣洗了一陣子PCB,後來乾脆用萬用洞洞板直接焊省事多了,這樣似乎不太專業,但只要焊得牢靠,能解決問題,外觀就不太計較了,這樣也過了將近20年。曾幾何時,眼力愈來愈不濟,洞洞板的焊點愈來愈模糊。不得已情況下只好重操賤業,再度洗PCB。拜科技之賜,現在有許多工具可用,而且有些還是免費的,對maker而言不須投資重金就能利用,真是一大祝福。PCB layout我用免費的pad2pad佈局。簡單易學、對maker而言,已夠好用。

 

本製作因電路簡單,既非高頻電路亦非類比線性電路,因此佈局無需考慮過多,為使PCB佈局簡單、好鑽孔、線條粗些(細線傷眼,且手工不好處理),我能不用IC就不用IC,能用單面就不用雙面設計。佈局完成後用描圖紙從列表機印出,接著就是用曝光機曝光、顯影、蝕刻、鑽孔,完成PCB製作。因為眼力不濟,鑽孔必須使用頭戴式放大鏡才能看清楚,畢竟歲月不饒人啊!慢慢鑽,當作是怡情養性終究還是完成了。

 

由於是手洗,如前述希望線條粗些、間隙寬些,在pad2pad的Tools/Route/Router Settings有幾個重要參數要注意:

PCB-1.jpg  

   1.   Trace’s layerBotton -------底層單層佈局

2.   Minimal gap0.4mm-------視零件疏密情況,「間隙僅可能寬。
3.   Width of new traces07mm-----視零件疏密情況「佈線寬度僅可能寬。

說明:其中23參數若佈局無法成功,就要把參數調小。 

 

單層板佈線較困難,程式預設參數是佈線3次,若是無法完成佈線,就會出現下列畫面。只要多設定幾次(例如設定100),讓電腦去傷腦筋,自己趁等待時間起來活動活動還有益健康呢。 

 

PCB-2.jpg   

 

 

PCB佈局完成圖;旁邊多餘的空間規劃當萬用板用。

PCB-3.jpg   

 

PCB感光顯影完成圖

  顯影PCB-1.jpg  

 

PCB蝕刻完成圖

蝕刻後PCB.jpg

4. 完成實體

PCB完成後,插上零件焊好,再用酒精清潔後,控制電路板就完成囉;軟體在麵包板電路階段就完成(程式內容後述),接著要裝箱、配線。機箱也是很傷腦筋的問題,因為裝置地點在電源箱旁,最後考慮用配電箱當機箱用,反正是裝在配電區,裝潢時已製作一大扇電器櫥櫃掩飾起來,外表看不到內部電源設備。又因操作簡單,而且正常情況是不需要去操控它的,為簡化配線,電路裝箱時把電源開關、保險絲,保護電驛、繼電器、by pass開關,都集中安裝在PCB上。

 

控制電路板完成圖

電路板裝箱.jpg  

 

 

裝箱配線完成圖;配線箱故意選大些,剩餘空間將來還可利用!

裝配完成圖.jpg  

 

這個偵測系統從構思到完成,花了數個月的時間,拖這麼久的原因是因為在這個領域停工太久,需要暖身與補充設備;另一個原因是,雜事太多,有空時才捏一下當作是消遣,還好總算完成了。

 

軟體規劃

監測軟體是按照當初規劃的流程圖,翻譯成Arduino語言就成了。在Arduino官網上,已列出所有指令,每一指令都有範例。個人體驗的感覺是簡單易學,即使毫無基礎要上手也不難;若熟悉電腦語言,就更能輕鬆上手。程式分成「啟動程序」、「持續抽水程序」、「錯誤處理程序三部分。程式中使用for…next迴圈作計時控制,在啟動程序中規劃為10秒鐘;在持續抽水程序中規劃為15分鐘,超過規劃時間就會進入錯誤處理程序。偵測部分是用if指令輪詢,由於輪詢控制的對象是抽水馬達,因此速度不須很快,大約每秒輪詢一次足矣。

 

goto結構:本製作程式用了許多goto的指令,一般程式設計的書通常不鼓勵使用goto指令,主要原因是太多的goto指令會增加程式除錯的複雜度,也不利於後續的維護。本程式有明確的流程圖指引,不致有上述問題產生,使用goto指令可以使程式更簡單完成。

 

異常處理程式:程式在輪詢過程中,若有異常狀況就會把預設的錯誤碼存入記憶體,然後直接跳(用goto指令)到異常處理程式;程式會切斷馬達電源,並根據記憶體的錯誤碼發出相應的錯誤訊息,達到保護與示警的目的。

 

完整抽水馬達監控程式碼

// Pumping motor monitoring system   2015/8/24

int TowerSW = 2;        //PIN-5

int WaterDetectSW =3;    //PIN-6

int StopRL =7;          //PIN-10

int Alarm = 8;          //PIN-11

int Er_Code = 0;

 

// the setup routine runs once when you press reset:

void setup() {               

  // initialize the digital pin as an output.

  pinMode(TowerSW, INPUT);         //demanding pumping water.

  pinMode(WaterDetectSW, INPUT);    // detecting if water be pumped up.

  pinMode(StopRL, OUTPUT);         //stop motor if the motor is unnormal.

  pinMode(Alarm, OUTPUT);          //alarm as pumping system fails.

  pinMode(13, OUTPUT);             //blinking as different process loop.

 

  }

 

void loop() {

// the loop routine runs for drawing water into water tank:

 

Start:

//==================================================================

//--------------------1. initial process----------------------------

//==================================================================

 

if ( digitalRead(TowerSW) == LOW ){      // main if loop ;pumping water wanted 

  for(int i=0;i<10;i++){                 //set initial process for 10 sec

digitalWrite(13,HIGH);

 

      //-----------------check motor---------------------------

if (digitalRead(TowerSW) == HIGH ){      //check if motor off?

Er_Code = 1;                                 //if so, keeps alarm_1 and ending

goto Alarm1_And_Ending;                       //Alarm_1

 }

     //---------------------------------------------------------------

 

     //----------------check water coming up--------------------

 if (digitalRead(WaterDetectSW) ==HIGH ){   // == HIGH => water coming up!

 goto Normal_process ;                            // water coming up within 10sec

 }                                     // Yes,ends initial process and goes on next process.

     //--------------------------------------------------------

    

 delay(100);                                    //for blinking 2 times in per cycle

 digitalWrite(13,LOW);

 delay(200);

 digitalWrite(13,HIGH);

 delay(100);

 digitalWrite(13,LOW);

 delay(600);

}                                        //for next loop --gets 10sec initial process

    //-----------------time up(10sec)-------------------------------

  Er_Code = 2;            water can't pump up within 10sec => keeps alarm_2 and ending

  goto Alarm1_And_Ending;                     //Alarm_2

   //-------------------------------------------------------------------

 

//==================================================================

//---------- 2. keeps pumping water process:-------------------------

//==================================================================

Normal_process:

   for(int i=0;i<750;i++){    //sets running process for 15min (1.2sec*750=900sec=15min)

digitalWrite(13,HIGH);      //for blinking 3 times in per loop

delay(100);

digitalWrite(13,LOW);

delay(200);

digitalWrite(13,HIGH);

delay(100);

digitalWrite(13,LOW);

delay(200);

digitalWrite(13,HIGH);

delay(100);

 

   //***********************  end process  ************************

if (digitalRead(TowerSW) ==LOW ){          //check if motor off within 15min ?

 goto Start ;                              //if so, end pumping process;restart.                                      

 }

   //**************************************************************

  

   //----------------check water coming up--------------------

if (digitalRead(WaterDetectSW) == LOW ){  //if water coming up while motor is running?

  Er_Code = 3;                         //if fails,goes for error and ending process

 goto Alarm1_And_Ending;                                          

 }

   //--------------------------------------------------------

 digitalWrite(13,LOW); 

 delay(500);

     }                               //for next loop---gets 15min loop

 

 //-----------------time up(15min)-------------------------------

  Er_Code = 4;       // pumping water more than 10min => keeps alarm_4 and ending

  goto Alarm1_And_Ending;          //Alarm_4

 //------------------------------------------------------------------

 

}                                //main if loop 

 digitalWrite(13,HIGH); 

 delay(10);

 digitalWrite(13,LOW); 

 delay(500);

 goto Start ;                        //main loop

 

//==================================================================

//------------------3. Error and Ending Loop------------------------

//==================================================================

Alarm1_And_Ending:

digitalWrite(StopRL,HIGH);           //turns motor off

for(int i= 1;i<= Er_Code;i++){         //Bee with error code

 tone(Alarm, 1000, 200);

 delay(300);

}

 delay(1000);

 goto Alarm1_And_Ending;

 

}          //maim void loop

//====================================================================

 

 

文章標籤
創作者介紹
創作者 錫安居 的頭像
錫安居

六家蓋房子

錫安居 發表在 痞客邦 留言(2) 人氣()


留言列表 (2)

發表留言
  • 悄悄話