天天看點

【用Proteus仿真Arduino】 05 -DS18B20數字式溫度測量

5.1 簡介

使用數字式溫度傳感器DS18B20實作溫度測量,并且序列槽輸出溫度測量值

5.2 關于DS18B20

DS18B20元件官方連結如下:

https://www.maximintegrated.com/cn/products/sensors/DS18B20.html

【用Proteus仿真Arduino】 05 -DS18B20數字式溫度測量

DS18B20引腳定義:

  • DQ為數字信号輸入/輸出端;
  • GND為電源地;
  • VDD為外接供電電源輸入端(在寄生電源接線方式時接地)

5.3 原理圖

添加DS18B20元件,在元器件搜尋欄中輸入“DS18B20”,并添加至元器件選擇欄,如圖

【用Proteus仿真Arduino】 05 -DS18B20數字式溫度測量

并将其DQ管腳接至數字口2腳,也就是ATmega328P的4管腳,同時接10kΩ的上拉電阻,VCC接至+5V,GND接至地端,修改後的Arduino UNO仿真圖如圖所示

【用Proteus仿真Arduino】 05 -DS18B20數字式溫度測量

編輯DS18B20參數屬性,彈出如圖所示的DS18B20設定框。設定框裡有内部序列号、目前溫度值、調節的最小變化量。

内部序列号用于單總線上挂有多個DS18B20的情況下,甄别不同的傳感器。隻有内部序列号相同的DS18B20才會響應單總線上的指令并作出相應的響應。
【用Proteus仿真Arduino】 05 -DS18B20數字式溫度測量

5.4 編輯代碼

DS18B20設定完成後,下面進入Arduino程式設計部分。

相關庫引入

兩個庫均在GitHub上,可以在release标簽頁中下載下傳最新項目檔案。

  • OneWire庫

    項目位址:https://github.com/PaulStoffregen/OneWire,官網位址

  • DallasTemperature庫

    項目位址:https://github.com/milesburton/Arduino-Temperature-Control-Library

下載下傳兩個庫的zip包後在Arduino IDE中選擇:項目 > 加載庫 > 添加一個 .ZIP庫 ,兩個庫添加完成後就可以使用了。

在開始編寫代碼之前将Paul Stoffregen的OneWire包括在庫管理器中,這是為了 DallasTemperature庫的調用,在編寫代碼時,可以不用包含此庫。

啟動arduino IDE,選擇DallasTemperature中示例simple檔案并打開,複制代碼,在protues中切換到“Source Code”标簽,粘貼代碼,然後編譯代碼。

【用Proteus仿真Arduino】 05 -DS18B20數字式溫度測量

5.5 運作仿真

【用Proteus仿真Arduino】 05 -DS18B20數字式溫度測量

oneWire 和DallasTemperature庫說明

OneWire庫

這是用于1-Wire總線通訊的庫,1-Wire總線是達拉斯半導體(已經被美信收購)推出的一種總線技術,一根線完成資料雙向通訊,甚至總線上的裝置還能從這條線取電。對于布線和現場施工來說這個技術蠻好的,但是這方面友善了别的地方就需要犧牲點了,具體來說1-Wire總線對通訊時間控制有些要求,通常通過程式來讀寫的話就需要犧牲一些性能了,因為讀寫過程中很多時候是阻塞的,OneWire庫中可以看到很多延時存在。隻用OneWire庫就可以操作DS18B20了,可以參考該庫的例程。

下面是OneWire庫中部分方法說明(這個庫不用太在意因為我們主要用的是下面那個庫):

  • OneWire(uint8_t pin) { begin(pin); }

    構造方法,指定總線接入的pin号;

  • void begin(uint8_t pin)

    初始化總線接口;

  • uint8_t reset(void)

    複位總線,如果總線上有可用裝置則傳回1,沒有則傳回0;

  • void select(const uint8_t rom[8])

    選擇指定裝置,rom[8]為裝置序列号;

  • void skip(void)

    發送跳過指令(0xCC);

  • void write(uint8_t v, uint8_t power = 0)
  • void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0)
  • uint8_t read(void)
  • void read_bytes(uint8_t *buf, uint16_t count)
  • void write_bit(uint8_t v)
  • uint8_t read_bit(void)

    讀寫相關操作;

  • void depower(void)

    停止向總線供電;

  • void reset_search()
  • void target_search(uint8_t family_code)
  • bool search(uint8_t *newAddr, bool search_mode = true)

    搜尋裝置相關操作;

  • static uint8_t crc8(const uint8_t *addr, uint8_t len)
  • static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0)
  • static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0)

    計算CRC校驗;

DallasTemperature庫

這個庫在上面那個庫之上再封裝了一層,友善直接使用DS18B20等系列的溫度傳感器。這個庫中溫度轉換可以設定為阻塞或非阻塞模式,阻塞模式下運作溫度轉換請求方法時會阻塞一段時間。這個庫中通路裝置可以通過裝置位址(序列号)或是索引,通過索引方式通路相對會耗更多時間。

部分方法說明如下:

  • DallasTemperature(OneWire*)

    構造函數;

  • void begin(void)

    初始化總線,擷取總線上有多少OneWire裝置和其中多少為DS18等系列裝置;

  • uint8_t getDS18Count(void)

    傳回DS18等系列裝置數量;

  • bool getAddress(uint8_t* deviceAddress, uint8_t index)

    擷取指定索引裝置的位址到deviceAddress對象;

  • bool isConnected(const uint8_t* deviceAddress, uint8_t* scratchPad)

    傳回指定位址(序列号)裝置是否連接配接到總線,并讀取裝置寄存器資料到scratchPad對象;

  • uint8_t getResolution()

    傳回全局裝置最大分辨率;

  • void setResolution(uint8_t newResolution)

    設定所有裝置資料分辨率;

  • uint8_t getResolution(const uint8_t* deviceAddress)

    傳回指定位址(序列号)裝置分辨率;

  • bool setResolution(const uint8_t* deviceAddress, uint8_t newResolution, bool skipGlobalBitResolutionCalculation)

    設定指定位址(序列号)裝置分辨率;

  • void setWaitForConversion(bool flag)

    設定溫度轉換時是否阻塞,true則阻塞,預設為true;

  • bool getWaitForConversion(void)

    傳回溫度轉換時是否阻塞;

  • void setCheckForConversion(bool flag)

    設定是否在阻塞時檢查轉換完成,true則檢查,預設為true;

  • bool getCheckForConversion(void)

    傳回是否在阻塞時檢查轉換完成;

  • void requestTemperatures(void)

    向總線上所有裝置發送溫度轉換指令,阻塞模式下該方法将阻塞一定時間;

    阻塞時間和全局裝置最大分辨率以及是否在阻塞時檢查轉換完成标志有關,

    分辨率影響: 9:最大94ms;10:最大188ms;11:最大375ms;其它:最大750ms;

  • bool requestTemperaturesByAddress(const uint8_t* deviceAddress)

    向總線上指定位址(序列号)裝置發送溫度轉換指令,阻塞模式下該方法将阻塞一定時間;

  • bool requestTemperaturesByIndex(uint8_t deviceIndex)

    向總線上指定索引裝置發送溫度轉換指令,阻塞模式下該方法将阻塞一定時間;

  • int16_t getTemp(const uint8_t* deviceAddress)

    傳回指定位址(序列号)裝置溫度資料,資料分辨率為1/128℃,如果發生錯誤則傳回DEVICE_DISCONNECTED_RAW(-7040,預設值);

    為了相容性考慮這裡溫度資料的分辨率和DS18B20有所不同,DS18B20預設分别率為1/16℃;

  • float getTempC(const uint8_t* deviceAddress)

    傳回指定位址(序列号)裝置攝氏溫度,如果發生錯誤則傳回DEVICE_DISCONNECTED_C(-127,預設值);

  • float getTempF(const uint8_t* deviceAddress)

    傳回指定位址(序列号)裝置華氏溫度,如果發生錯誤則傳回DEVICE_DISCONNECTED_F(-196.6,預設值);

  • float getTempCByIndex(uint8_t deviceIndex)
  • float getTempFByIndex(uint8_t deviceIndex)

    傳回指定索引裝置溫度,如果發送錯誤則傳回預設值;

  • bool isParasitePowerMode(void)

    傳回是否需要總線寄生供電,需要則傳回true;

    警報相關方法不在此列出,請自行查詢源碼

  • static float toFahrenheit(float)

    将攝氏溫度轉為華氏溫度;

  • static float toCelsius(float)

    将華氏溫度轉為攝氏溫度;

  • static float rawToCelsius(int16_t)

    将原始溫度轉換為攝氏溫度;

  • static float rawToFahrenheit(int16_t)

    将原始溫度轉換為華氏溫度;

總結

基于OneWire和DallasTemperature庫使用DS18B20主要内容就是上面這些了,更多資訊可以參考美信對于1-Wire總線的引用筆記:

https://www.maximintegrated.com/cn/app-notes/index.mvp/id/126

https://www.maximintegrated.com/cn/app-notes/index.mvp/id/187

繼續閱讀