2017年12月20日 星期三

DS18B20-Reset-3-連線檢測

 特務接頭前的觀察要點

一個特務,一定了解執行任何一次的接頭任務前,都要先觀察據點是否正常。意味著,它可能被"破了",若有出現"異常"的訊息,則立馬回報組織。

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的數字是"正確"的嗎?

沒有留言:

張貼留言