顯示具有 函式庫 標籤的文章。 顯示所有文章
顯示具有 函式庫 標籤的文章。 顯示所有文章

2018年1月6日 星期六

DS18B20-溫度值計算

 基本的命令及讀取程序完備後,接下來要進入取值並計算成溫度值的程序。由下面DS18B20的讀取溫度值程序中,可以知道,在Arduino命令DS18B20啟動溫度轉換命令(0x44)後,待待其轉換時間750μs(DS18B20會將溫度值放入暫存區中),再進行重啟、省略ROM確認,再通知DS18B20開始讀取暫存器資料(0xbe),此時DS18B20會依序(從暫存器依序從byte 0開始到byte 8)逐位元(從bit 0到bit 7)傳遞資料給Arduino

而我們會讀取兩次資料,第一次會讀到的Byte為LS Byte(簡寫為LSB)為溫度值的低位元值,再讀一次,會讀到MS Byte(簡稱MSB)為溫度值的高位元值。而溫度值就是MSB+LSB的組合的轉換。

DS18B20的暫存器結構 

 下圖為DS18B20的官方資料,其中左方為暫存器(SCRATCHPAD)結構,及右方EEPROM資料,在此不多介紹EEPROM,簡單的說它就是上下限警告值及位元設定的資料。我們將焦點置於暫存器。
下圖是將官方的暫存器重繪後,並以啟始的狀態呈現。由下圖可看到DS18B20暫存器共有9個byte,但可區分為五個部份


1、溫度值(byte0~1):存放量測到的溫度值,byte 0為溫度值的LSB,而byte 1為溫度值的MSB,以通電後之初值而言,LSB為[01010000]而MSB為[00000101]

2、警示溫度上下限(byte2~3)

3、精確度位元(byte 4): 如下表,使用R1與R0來設定其位元精度(有效值)
4、無效區(byte5~7):未使用

5、CRC檢驗碼(byte 8):通CRC的運算的檢驗碼,可提供Arduino確認資料的正確性。

DS18B20溫測範圍及精度差異

 在了解DS18B20的暫存器後,下圖是DS18B20的量測溫度值、暫存器之二進位元輸出值及十六進位表示值。
由官方資料及表中可知,DS18B20量測的溫度區間為-55~+125℃(-10~85℃時精度為±0.5℃),在12位元的解析度時,其可分辨的溫度最小的量測單位為0.0625℃。

 

由MSB與LSB組成的溫度值

DS18B20的溫度值是用16位元(MSB+LSB)組合,如官方所提供的資料如下:

底下將其區段內容及計算的概念整理之。

溫度值區段


如上圖所示,溫度值位元資料其實是MSB+LSB的組合成十六位元(bit)資料,可區分為符號區、整數值區及精確度區。

符號區(MSB之bit3~bit7):使用5個位元,當溫度值為正時皆為0,而當溫度值為負時則為1,故於程式設計時,只要MSB大於7就意謂著溫度值為負。

整數值區:使用7個位元,MSB之bit 0~2加LSB之bit 4~7組合而成。

精確度區:以12位元為例,正負號(1)+整數值(7)+小數點(4)共計為12位元,而一般作溫度數值計算時,會直接以12位元做計算,再取正確小數點既可。

溫度值計算

 有了上述的基礎知識後,接下來,就是計算的程序,整理如下圖:先判斷正負值,若為負值是做二補數處理並設定負號值,再將兩數結合運算乘於單位量測值0.0625,既得溫度值,若負號值為真,則補上負號,傳回溫度值。
下圖以溫度值-25.0625℃為例(資料於十六位元表示為FE6FH),在12位元的狀態下,其計算的變化:正負號判定、取反值、加1的位元變化(※"~"代表取反值,既0與1互換的動作)。
當初也被LSB負值的計算方式:[取反加一]的為何"加1"所困,後來了解後才知道,因為"0"被算到正值的陣營去了,只好用加1位補足。(詳細的部份,各位可用"二補數"作關鍵字搜索,再細探之)

程式說明

程式中有使用到位元運算反相(~):0與1互換,向左移位(<<)的指令,不難,只是不習慣,可參考上圖的位元變化程序及程式說明,應可掌握

程式碼

float Caculate_Temperature(uint8_t temp_LSB , uint8_t temp_MSB)
{
 boolean  fp_minus = false;        //温度正負標誌:預設為false,因為通常為零度以上
 //當temp_MSB>7代表此溫度為負數值時,測到的數值需要先反相再加 1
 if(temp_MSB > 0x7f)  
 {
  fp_minus = true;      //溫度正負指標,負數時fg_Minus=0
  temp_MSB = ~temp_MSB;     //將temp_MSB中的每一位元反相(0、1互換)
  temp_LSB = ~temp_LSB + 1;
  //將temp_LSB中的每一位元反相(0、1互換),要記得加一,才能正確的反應其值
 }
 //以十六位元空箱來結合MSB及LSB
 uint16_t raw_temp =
     (((uint16_t)temp_MSB) << 8) |   //將MSB先用空的十六位元左移8個位元
     (((uint16_t)temp_LSB));
 //將十六位元的整數值再乘於0.0625的單位值,既得溫度值
 float fp_temp = raw_temp * 0.0625;
 if(fp_minus) {fp_temp = -fp_temp;} //當fp_minus是1,代表是負數,將溫度加上負號
 return fp_temp;
}

結語

此篇資料要花點時間了解,因為包含了DS18B20的硬體、暫存器及位元數值運算、位移等,當初研究時,也不怎麼順利,不過,一去二回,熟了就懂了,但其實只是不習慣而已,只要花點時間,相信就能掌握,而且一旦了解後,你會發覺,好像電子元件的運作就是這麼一回事,很簡單,但這個簡單(Simple)卻不容易(Easy)!

總算完成所有的準備功夫了,下一步,就最讀取溫度值了!

2017年12月9日 星期六

DS18B20的過河導航行前說明!

 想在不用外部程式庫的狀態下,自己能讀取DS18B20嗎?Simple!就是底下這張圖,只要8個步驟,就可以掌握DS18B20喲!想知道嗎?來參加<<DS18B20的過河導航行前說明會吧>>

岸邊熱身(Setup):準備及前置知識

首先,我們會簡介1-Wire通訊的訊息,必須有的常識是DS18B20於"平常"狀態,處於高電位的實現:上拉電阻的使用及直觀替代概念(彈簧)

淺水區(STEP 1-3):工具製作及練習

 以特務接頭的例子,來說明DS18B20如何作啟始(Reset)、命令發佈(Write)及資料讀取(Read),並於階段過程中檢驗官方數據與DS18B20實際表現的差異。

第一島礁(STEP-4):簡易讀取溫度值


常前置基礎工具準備好後,既可以獲得DS18B20的溫度數據組(LSB/MSB),並於了解DS18B20的數據架構及原理後,既可透過轉換程序,獲得初步的溫度值


島礁探索(STEP 5-6):讀取暫存器及CRC檢驗 

 既然,我們可以讀取暫存區的溫度數據組(LSB/MSB),那就可以讀取整組數據,同樣的,也可讀取ROM資料(但不會深入,因為這不是此次的主題),然後,就是數據的檢驗(CRC)的實務操作(不說原理,只明操作)程序,來檢驗溫度數據的正確性。
有了CRC的檢驗,那麼,我們就可以透過測試結果,回頭檢測關鍵程序(Read),並透過合理調整參數值,來增其數據穩定性(小概念:好的產品不是檢查出來的,而是透過檢查改善製程來達到產品的良率提升)

深水區(STEP-7):檢錯/中斷設置及類別化(Object)

 我們強化的工具,並使用CRC檢核DS18B20溫度數據正確性,基本上已完成主要工作,而透過檢錯功能的加入及回饋訊息(-127℃),能讓其安全性提高。禁止/停止中斷的設置,可增加讀取DS18B20的穩定性。
當上述的程序皆已達成後,基本上程式目標已完成。接下來,是將程式碼類別轉換成程式庫的過程,簡單但同樣是不容易,過程中,會說明類別化其實就是從名店轉換成加盟總店的過程的例子讓你更了解。最後,我們會獲得SimpleDs18b20的類別程式碼(.h/.cpp)

彼岸(STEP-8) :程式庫及範例

一步一步的從SimpleDs18b20函式碼(.h/.cpp),先撰寫範例程式(example),確認可正確執行後,再進行程式庫相關文件的生成(keywords-程式關鍵字/README.MD/LICENSE)。
最後,就是上傳到GitHub的簡易程序,到此,搞定,收功,享用海鮮吧!

少說了一個,那個最前面的Ghost是什麼意思?


"Everything you want is on the other side of fear!"

看了行前說明,難嗎?有點,但就是煩了點,不過你會收獲什麼?
嗯!你會知道怎麼看Datasheet、會知道DS18B20的時序圖、內部資料結構、CRC檢核操作、程式類別化、程式庫的建立與上傳!
然後呢?當你完成了這些,我想你已進了Arduino的大門,透過格物的過程,你知了,你就可以善用DS18B20了,既然你會用DS18B20,那麼,其他的又有什麼問題呢?一法通萬法通!

想要嗎?那麼就前進吧!開始這偉大的航程!


2017年12月6日 星期三

SimpleDs18b20就是這麼簡單!

你看,這就是我釣的魚!


話說老鄭拿著一條魚向朋友炫耀,說是他自己釣回來的!
然而,朋友們都不相信,此時,老鄭的老婆剛好路過,看了一下魚
就說:「這魚確實是老鄭自己釣的!,因為,市場沒這麼小條的魚!」
老鄭:「再小.........也是魚呀!」

沒有張屠夫,還是得吃肉

標準的使用DS18B20要使用兩個程式庫, OneWire及DallasTemperature,前者是1-Wire通訊協定,後者是此元件的專用程式庫。品牌好且大家使用也沒問題,真是一好三公道,且將DS18B20的功能發揮到完美。
不過, 各位有沒有想過,前面的溫度感測器DHT22、DS18B20、MAX6755等,我們最想要的其實就只是溫度值!
正如同,喝咖啡,你可以用這個頂級咖啡機來沖泡,大約18000美元,可以給你極致的美味咖啡!
圖片來源:https://shop.forfivecoffee.com/products/la-marzocco-strada-mp

也可以用這個越南咖啡壺來沖泡,價格約10元(在越南的價格),也是咖啡
http://oceanlinktravel.vn/news-travel-guide/cafe-sua-da-thuc-qua-rieng-cua-nguoi-sai-gon.html
其實,程式庫就是工具,它可以是豪華也可以簡單,在我眼中,現有的程式庫,就像是高級遊艇,而且功能齊全,又高大上(高端大氣上檔次),不過說穿了,不就是個出海的工具嗎?咱們用保麗龍板拼一拼也是可以出海不是嗎?
別人寫的出來,很好很強大,是否自己也可以寫一個試試!咱們要的也不多,不用功能齊全(什麼設定位元解析度、一線多元件的)!就設一個小目標:自己寫一個程式庫來就讀取溫度值。

是驢子?是馬?拉出來溜一溜就知道了!

對一個初學Arduino的人來說,這有點挑戰,但也還好,花了一點時間,摸著石頭過河,先參考現有的程式庫,不懂的就找Google、Datasheet,就這樣,一步一腳印的摸著石頭過了河,算是達到自己設定的目標-->程式庫名稱:SimpleDs18b20,功能:讀取DS18B20溫度值。

程式庫的限制 


【注意:這個程式庫只能於Arduino 1pin 接1個DS18B20的情況下使用】
使用條件:
1、Arduino 1pin 只能接1個DS18B20
2、外接電源模式
在滿足上述條件下,這個程式庫就能(也只能)讀取溫度值
※注意:當接線有問題或是DS18B20故障時,會出現"-127"異常值

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

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

STEP-2- 程式碼說明

SimpleDs18b20既然是Simple,那就是Simple
只有一個功能,就是讀取攝氏溫度值(Get Temperature)
所以只有一個函式GetTemperature()

範例程式的第15行:
Serial.println(ds01.GetTemperature());

讀取(GetTemperature)感測器物件(ds01)的溫度值,並將其值印出

STEP-3-程式碼及輸出

// 引用程式庫SimpleDs18b20
#include <SimpleDs18b20.h&gt
//將連接Pin腳設定於pin 7
uint8_t dq_pin=7;
//建立物件ds01(它是位於pin7的DS18B20)
SimpleDs18b20 ds01(dq_pin);

void setup() {
    Serial.begin(9600);
}

void loop() {
    Serial.print("Ds18B20's Temperature --> ");
    // 使用GetTemperature()來讀取溫度值,並顯示
    Serial.println(ds01.GetTemperature());
    delay(1000);
}

輸出結果 


STEP-4-下載/安裝程式庫(SimpleDs18b20)

有興趣的朋友,可以到以下的連結下載試用看看!內含接線圖、範例程式及程式庫!

 SimpleDs18b20程式庫下載連結




掌握DS18B20就只要過9塊石 

自己寫程式庫很難嗎?說真的,對一個初學者而言,寫DS18B20真有點難!因為到後來,我才發覺,它的水有點深但還不會太深,摸著石頭過河後,回頭看看,喲!不多,要過DS18B20這條河,就只要過九塊石!想試試嗎?且待下回分曉!。