2017年12月16日 星期六

DS18B20-Reset-02-啟動程序

A特務與D特務的無聲接頭暗號

各位可以將Arduino與DS18B20的訊息交流,想像成兩個「啞巴」特務的接頭暗號
而訊息的交換是透過一個被彈簧繩(上接電阻)拉著的小球高低(電位狀態)來呈現
1-A特務(Arduino)拉低小球至低於80cm(<0.8V)約480秒,再放開
2-小球會被彈簧繩拉回原來的高度250cm(>2.2V)
3-D特務(DS18B20)會於15-60秒內,將小球再拉低60-240秒
當A特務於放開小球後的第70秒內看到小球是低於80cm(低電位)
代表D特務在線並能正常反應!

時序才是重點

由於DS18B20與Arduino只透過單一線傳遞訊息,因此,時序(包含時間及順序)就很重要,所以對於訊息傳遞過程中,什麼時候"發送"、什麼時段"接收",電位狀態就十分重要。底下,就解析其時序。

DS18B20啟動資料

此部份,先從Datasheet中截取關鍵說明及其時序圖,然後再加上自製的圖形及解說,掌握後既可輕鬆的寫出程式碼。

啟動之文字說明

底下為Datasheet第15頁中關於啟動程序(Initialization Procedure)的說明,簡單的說就是Arduino先發出重置(Reset)命令,接下來就是上拉電阻動作,然後是DS18B20的答應作業。
英文不難,各位可以看看先!(請注意電位的變化及時間數字)

啟動之官方時序圖

 上述的文字下方,就附上了DS18B20的初啟時序圖,可對照一下上述的文字參考之!

 時序圖解析

整個啟動程序(Initialization Procedure)主要可分為兩個部份Arduino發送重置(Reset)與DS18B20應答(Presence)脈沖,我將其細分為6個步驟:
一、Arduino發送重置脈沖(請問有人在嗎?)
1-Arduino先將電位拉高
2-再將電位接低
3-持續低電位至少480μ
4-Arduino釋放控制,然後,上接電阻會動作,將電位拉回高電位

二、DS18B20發送應簽脈沖(有,有人在!)
5-DS18B20於Arduino釋放控制開始,於15-60μs的時間後,將電位拉低並維持60-240μs
【Arduino就於此時段讀取電位值既可判斷是否有DS18B20的存在】
●當讀取的電位為高電位時,代表沒有DS18B20或是已故障
○當讀取的電位為低電位時,代表存有DS18B20
6-應答作業完成後,DS18B20釋放控制,上拉電阻將電位拉回至高電位 
※重置脈沖及接收訊息時段,建議都要超過480μs


程式設計步驟

掌握了Arduino與DS18B20之間的初啟程序後,我們底下就將其硬體接線、關鍵程式說明並將其程式碼及結果整理於下:

STEP-1-零配件清單及接線圖

此圖依序為Datasheet上之外部接線圖、材料清單及零件示意圖


此圖為Arduino與DS18B20接線圖及其局部放大,要注意的是DS18B20之接腳的接線:
1- GND 為電源地。
2- DQ 為數位資號輸入/輸出端。
3-VDD 為外接供電電源輸入端。
【注意:我使用的是Pin 7不是Pin 2喲!】

STEP-2-關鍵程式碼說明 

1、釋放電位控制
於上序時序圖中,Step-4為釋放電位控制,對Arduino而言,其程式碼就是
pinMode(DQ_Pin, INPUT);
代表著釋放控制,並將角色轉換為"聽"的狀態

2、讀取的時間點
由於DS18B20會於Arduino釋放電位後開始計時於15-60μs後將電位接低,
乾脆以最久的時間再加10μs來讀取其狀態,最保險!但最好不要超過120μs!

STEP-3-程式碼

//Arduino數位腳位7接到DS18B20的第2腳(DQ),DQ為Data input/output的縮寫
#define DQ_Pin 7            

void setup() {
 Serial.begin(9600);
 char is_exist = 0;  //有無DS18B20之變數,先預設為不存在(0)
 Serial.println("Start Reset DS18B20 in the Wire Bus...");
}

void loop() {
 //Tx階段:Step 1.主機發送重置脈沖
 pinMode(DQ_Pin, OUTPUT);    //將DQ_Pin調整為輸出狀態,自動會回歸HIGH電位
 //Tx階段:Step 2.主機拉低電位
 digitalWrite(DQ_Pin, LOW);  
 //Tx階段:Step 3.主機持續於低電位480us
 delayMicroseconds(480);     
 //Tx階段:Step 4.主機釋放電位控制,轉為輸入狀態
 pinMode(DQ_Pin, INPUT);  //將DQ_Pin設定作數位輸入動作
 //Rx階段:Step 5.讀取DS18B20電位值
 delayMicroseconds(70);  //此值為DS18B20 max回應反應時間60us再加10us

 //將讀取的電位值反轉,所以是低電位為有DS18B20
 char is_exist = !digitalRead(DQ_Pin);

 //Rx階段:Step 6.延時至超過主機接收訊息時段
 delayMicroseconds(410);

 //結果輸出
 if(is_exist) {
  Serial.println("DS18B20 Exist");
 } else {
  Serial.println("No DS18B20 right here");
 }
 delay(2000);
}

STEP-4-結果輸出 


結語

 是的,透過啟動程序的解析及撰寫,我們寫下了一個不用引用任何程式庫,並能正確的讀取DS18B20是否於線上的程式,踏出了第一步。

接下來,要再補充一下,初始之前還要作的一件事!


沒有留言:

張貼留言