# 防後倒中柱輪椅 ###### tags: `Arduino` [Arduino作品目錄](https://hackmd.io/KH0oMN6ZSiuiogFCy5s_mA) ## 概念簡述 設計一個輪椅輔助裝置,依照傾斜度自動伸出/收回輔助輪。 ## 功能設計 ### (P)套件需求 1. 傾斜儀 SW-520D 2. 伺服馬達 ### (P)功能描述 當輪椅要爬上坡而傾斜時,放下輔助輪穩定輪椅。 當輪椅回歸平路而歸正時,收回輔助輪還原狀態。 透過傾斜儀偵測坡度變化,根據變化模式結果來讓伺服器馬達轉動輔助輪,以控制輔助輪的伸出與收回兩個動作。 ### (P)邏輯設計 從簡述可以得知,放下輔助輪的具體情境有兩種: 1. 從平地走向有坡度時,需要放下輔助輪 2. 從有坡度地走向平地時,需要收回輔助輪 由此可知,對於傾斜儀的==瞬間判定==結果,可以簡化為2種 : 結果A: 傾斜度測定為斜坡地 結果B: 傾斜度測定為平地 然而瞬間結果不足以判定當下狀況,所以我們讓傾斜儀以每`500ms`的間隔,依照測定5次傾斜度的結果來判定輪椅當下的傾斜狀態,有以下3種狀態 : ``` 平地狀態 : 5次都是結果A,所以判定為目前輪椅處於平地 斜坡狀態 : 5次都是結果B,所以判定為目前輪椅處於斜坡地 不穩定狀態 : 5次內結果A跟結果B都有,判定為不穩定狀態 ``` 透過上述3種狀態,我們就能輕鬆來決定伸出/收回 輔助輪的情形。 ``` 伸出輔助輪: 上次偵測是平地狀態,但本次偵測是斜坡狀態 收回輔助輪: 上次偵測是斜坡狀態,但本次偵測是平地狀態 ``` ### (P)示意圖 ```mermaid graph TD; 偵測當前狀態-->判定狀態變化; 判定狀態變化-->平地變斜坡-放出輔助輪; 判定狀態變化-->斜坡變平地-收回輔助輪; 判定狀態變化-->其他狀態變化-不動作; 平地變斜坡-放出輔助輪-->繼續偵測當前狀態; 斜坡變平地-收回輔助輪-->繼續偵測當前狀態; 其他狀態變化-不動作-->繼續偵測當前狀態; ``` ## 程式碼: + 實際套件組合完成後的接腳配置以程式碼為主 ```cpp= //引入套件所需要的函式庫 #include <Servo.h> #include <SoftwareSerial.h> Servo motor; //建立Servo物件,命名為motor,來使用裡面的功能(methods) int sw520d_d0 = 2; //傾斜儀SW-520D 接Pin2 int last_status = 2; //全域變數,初始狀態設置為狀態2,即平穩狀態 //初始設定函式,僅會執行一次 void setup(){ Serial.begin(9600); //設置監控視窗頻鮑率為9600bps pinMode (sw520d_d0,INPUT); //設置目前為傾斜儀pin2腳位為輸入模式 motor.attach(9); //透過 Pin 9 來控制伺服馬達 motor.write(0); //初始化伺服馬達角度=0 delay(2000); //等兩秒,再進行後續動作 } //重複執行函式,會重複執行 void loop(){ //呼叫自訂的偵測傾斜儀狀態函數 detect_status5sec() int current_status = detect_status5sec(sw520d_d0) ; //把兩個狀態變數從監控視窗印出來,方便檢測 Serial.print("上個狀態");Serial.print(last_status);Serial.print("\n"); Serial.print("目前狀態");Serial.print(current_status);Serial.print("\n"); //both_equal:是否目前狀態與上個狀態不同 bool both_equal = ( last_status != current_status ); //both_not3:是否目前狀態與上個狀態都不是不穩定狀態 bool both_not3 = ( last_status != 3 && current_status != 3 ); if(both_equal && both_not3) //上面兩個條件都滿足 { Rotate( last_status, current_status);//執行轉動功能 }//if if(last_status!=3 && current_status!=3)last_status=current_status; //若非狀態三,則儲存狀態。本行極度重要 }//loop() /*函數detect_status5sec: * 偵測多次當下結果來評斷傾斜狀態 * 傾斜儀偵測結果有三種狀態 * 狀態1: 在偵測期間都是傾斜的,回傳1來表示為狀態1 * 狀態2: 在偵測期間都是不傾斜,回傳2來表示為狀態2 * 狀態3: 在偵測期間傾斜不傾斜都有出現,回傳3表示為狀態3 * */ int detect_status5sec(int sw520d_d0){ int tiltControl = digitalRead(sw520d_d0); int count=0;//用來算有幾次偵測為傾斜 int dt=5; //設置偵測次數 int ms=500;//設置每次偵測間隔多少毫秒 //執行迴圈,跑dt次偵測,每次偵測間隔ms秒 for (int i=0;i<dt;i++) { //若傾斜則成立 if (tiltControl == HIGH) { count+=1 ; } delay(ms); } if(count==5) return 1;//都是傾斜,回傳1 else if (count==0) return 2;//都不傾斜,回傳2 else return 3;//傾斜不傾斜都有,回傳3 } /* * 函數Rotate: * 確認情況後轉動馬達或不轉動馬達,來完成伸出/收回輔助輪 * 1表示處於斜坡地 * 2表示處於平地 * 3表示處於晃動中不穩定的狀態 * 由1變2:表示要回歸0度,收回輔助輪 * 由2變1:表示要轉到105度,伸出輔助輪 */ void Rotate(int last,int now){ if(last==1 and now==2){ motor.write(0); } else if (last==2 and now==1){ motor.write(105); } delay(2000);//轉完等個2秒 } ``` ### 測試用影片 >傾斜儀感測不傾斜時亮綠燈,傾斜時不亮綠燈 {%youtube XhxbjlHMQT4 %}