特務接頭前的觀察要點
一個特務,一定了解執行任何一次的接頭任務前,都要先觀察據點是否正常。意味著,它可能被"破了",若有出現"異常"的訊息,則立馬回報組織。Arduino與DS18B20的連接檢測
上一篇[DS18B20-Reset-02-啟動程序]中,執行時可以重啟DS18B20,且當收到DS18B20的應答訊息後,會顯示"DS18B20 Exist"的回饋訊息,而當無法重啟DS18B20時,它會顯示"No DS18B20 right here"。當一切連線正常時,它會如實的執行,不過此程式只能偵測DS18B20的正常反應,卻無法處理另一狀態,就是Arduino與DS18B20斷線時的錯誤回饋,而此篇的程式就是補強此一短處。
而程式設計的關鍵也不難,如Datasheet中第10頁[Hardware Configuration]中所言,就是當Arduino與DS18B20正常連接並外接一上拉電阻時,它會處於高電位的狀態。反之,當未執行任何執行命令時,連線若出現低電位既是異常。
程式設計說明
簡單而言,程式設計的理念就是在執行啟動程序前,先觀察連線的電位狀態一段時間,期間若有任何的低電位出現,就是連線異常。※ 硬體連線資料請參考[DS18B20-Reset-02-啟動程序]
STEP-1-程式架構
此程式使用了四個副程式,其架構如下圖:1.TestConnect():測試連線副程式,為此篇的重點,主要是偵測輸入pin腳,當出現低電位時, 就顯示錯誤訊息"DQ_pin no connect",並傳"0"值給ResetResult()副程式,若通過觀察期, 它仍處於高電位,就傳"1"值給ResetResult()副程式。
2.ResetResult():啟動結果副程式,統合連線測試及啟動測試兩功能,但先測連線,再測啟動, 兩者皆OK才傳"1"值給ShowOkInfo(),否則傳"0"值給ShowOkInfo()。
3.isReset():啟動程序副程式,主要功能為傳回重啟狀態值
4.ShowOkInfo():顯示程程式,當一切正常為"Reset OK",有任何異常顯示"Reset Fail"
STEP-2-關鍵程式碼說明
此次程式的關鍵是測試連線副程式TestConnect(),觀察期間為240μs,每隔4μs觀察一次電位值,觀察60次,中間若有任何一次出現低電位,則傳回"0"值並結束程式,若整個觀察期間皆為高電位,則傳回"1"值。uint8_t TestConnect()
{
uint8_t retries = 60;
//先拉高電位(轉為讀取狀態)
pinMode(g_dq_pin, INPUT);
//若是正常就會處於高電位(DS18B20的一般狀態)
while(!digitalRead(g_dq_pin))
{
retries--;
if(retries == 0) {
Serial.println("DQ_pin no connect!");
return 0;
}
delayMicroseconds(4);
}
return 1;
}
STEP-3-程式碼
#define g_dq_pin 7
void setup(){
Serial.begin(9600);
Serial.println("<>");
}
void loop(){
ShowOkInfo(ResetResult()) ;
delay(2000);
}
uint8_t ResetResult()
{
//傳回檢測Arduino與DS18B20連接狀態
if(!TestConnect()) {return 0;}
//直接傳回Reset結果,1既存在,0為非
return isReset();
}
void ShowOkInfo(uint8_t isOk)
{
if(isOk) {
Serial.println("Reset OK");
} else {
Serial.println("Reset Fail");
}
}
//測試Arduino與DS18B20的連接狀態並傳回測試值
uint8_t TestConnect()
{
uint8_t retries = 60;
//先拉高電位(轉為讀取狀態)
pinMode(g_dq_pin, INPUT);
//若是正常就會處於高電位(DS18B20的一般狀態)
while(!digitalRead(g_dq_pin))
{
retries--;
if(retries == 0) {
Serial.println("DQ_pin no connect!");
return 0;
}
delayMicroseconds(4);
}
return 1;
}
//啟動程序並傳回狀態值
uint8_t isReset() {
pinMode(g_dq_pin, OUTPUT);
digitalWrite(g_dq_pin, LOW);
delayMicroseconds(720);
pinMode(g_dq_pin, INPUT);
delayMicroseconds(70);
uint8_t is_exist = !digitalRead(g_dq_pin);
delayMicroseconds(410);
return is_exist;
}
STEP-4-程式輸出
輸出結果中,可看出有成功四次Reset,然後兩次的失敗,因為我將Arduino與DS18B20的連線拔除, 然後,再插回去就顯示重啟正常。結語
其實此一功能是整個讀取溫度程序都完成了之後,到[檢錯/中斷設置及類別化(Object)]時才加上去,當初認為是多此一舉,沒必要,但後來考量到整體的檢錯功能時,就知道不加不行,且要能防止系統出問題,需傳回一異常值(-127℃),才能保證系統就算有硬體連線/元件異常時,也不會出大錯。當然,先在此補充了此功能,也讓各位有一個觀念。接下來,要用實際數值,來檢驗Datasheet的數字是"正確"的嗎?
沒有留言:
張貼留言