[Arduino] DS18B20 溫度傳感器

DS18B20是一款低成本低開銷的數字溫度傳感器,它的測量范圍在-55℃ ~ 125℃之間,固有誤差為1攝氏度,在-10℃ ~ 85℃之間的精度為0.5℃,能夠滿足日常測溫需求。
DS18B20采用OneWire(單線)通信協議,只需要一根信號線就可以完成數據的讀寫。供電也允許有獨立供電和數據寄生供電兩種模式,在寄生供電模式下電源線接地,電源從數據線上獲取,可以節省一根連接線。

連線方式

DS18B20有三個引腳:

  • VDD,外部電源,如果使用寄生供電模式,該端接地
  • DQ,數據引腳,需要上拉電阻拉高
  • GND,接地端,提供參考低電平

獨立供電模式

需要給DQ提供一個5kΩ的弱上拉電阻


獨立供電電路

寄生供電模式

需要給DQ提供一個5kΩ的弱上拉電阻,在DS18B20工作時,需要給DQ提供一個強上拉。如果DS18B20工作在超過100℃的環境下,漏電流會比較大,寄生供電的工作方式可能無法正常為DS18B20供電,此時需要設計為獨立供電模式。


寄生供電電路

驅動代碼

DS18B20采用OneWire協議通信,OneWire通信協議的實現這里就不詳細說明了,對于Arduino來說已經內建了OneWire庫,可以直接使用。

寄存器結構

DS18B20內建有三種寄存器:

  • 高速緩存,測量的環境溫度會緩存在此
  • 暫存器,上電后對DS18B20的配置以及溫度轉換后的數值都存放在此,以備讀寫
  • EEPROM,配置都可轉儲到這里做永久保存,也可從這里讀取配置到暫存器上去使用,詳見指令寄存轉儲寄存恢復
寄存器結構

指令集

指令 類型 功能 描述
0x33 ROM指令 讀取ROM 讀取64位只讀唯一識別碼,其中第一個字節為固定識別符0x28,最后一個字節為CRC檢驗碼
0x55 ROM指令 查詢ROM 查找總線上是否有指定識別碼的DS18B20存在
0xF0 ROM指令 枚舉ROM 枚舉總線上DS18B20的數量和固定標識符
0xCC ROM指令 忽略ROM 跳過ROM查詢流程
0xEC ROM指令 枚舉告警 枚舉總線上處于告警狀態的DS18B20的標識符
0x44 功能指令 溫度轉換 開始探測環境溫度并存儲到寄存器上
0xBE 功能指令 讀取數據 讀取RAM中的數據
0x4E 功能指令 設置閾值 設置高溫告警溫度TH和低溫告警溫度TL
0x48 功能指令 寄存轉儲 把RAM中TH、TL和配置轉儲到EEPROM中
0xB8 功能指令 寄存恢復 把EEPROM中的數據恢復到RAM中的TH、TL和配置位上
0xB4 功能指令 查詢供電方式 查詢供電方式

和DS18B20通信要遵循一定的訪問時序:

  • 主機下拉DQ腳至少480μs做復位操作,然后恢復上拉等待15-60μs
  • DS18B20下拉DQ腳60~240μs做"存在"應答
  • 主機發送ROM指令,然后拉高DQ
  • [讀取DS18B20的回復]
  • 主機發送功能指令,然后拉高DQ
  • [讀取DS18B20的回復]

DS18B20是指令嚴格流程化的,如果通信指令的時序不正確,DS18B20會不應答主機的請求。每次訪問DS18B20都要重復上面的所有步驟,否則只有不完整的流程時序會得不到DS18B20的應答。

CRC校驗

CRC = X8+X5+X4+1

枚舉ROM

#define DS18B20_PIN 2

OneWire onewire(DS18B20_PIN);
byte    address[8];
int     count = 0;

void enumerateROM() {
    while (onewire.search(address)) {
        count++;
        for (byte i = 0; i < 8; i++) {
            Serial.print(count);
            Serial.print(": 0x");
            if (address[i] < 0x10) Serial.print("0"); Serial.println(address[i], HEX);
        }
    }
}

溫度讀取

#define STARTCONVERT 0x44 
#define READDATA     0xBE
#define DS18B20_PIN  2

OneWire onewire(DS18B20_PIN);
byte    address[8]; // 枚舉ROM時可獲得
bool    isParasite = true; // 是否為寄生供電模式

float readTemperature() {
    byte temperature[2];
    byte highAlarmTemperature;
    byte lowAlarmTemperature;
    byte configuration;
    byte crc;

    // 請求溫度轉換
    onewire.reset();
    onewire.select(address);
    onewire.wirte(STARTCONVERT, isParasite);

    // 等待DS18B20完成溫度轉換
    delay(delayForResolution(bitResolution));
    
    // 開始讀取DS18B20的數據
    int result = onewire.reset();
    if (result == 0) {
        // DS18B20正在做溫度轉換,忙
        return;
    }

    onewire.select(address);
    onewire.write(READDATA);

    // byte 0: temperature LSB
    // byte 1: temperature MSB
    // byte 2: high alarm temp
    // byte 3: low alarm temp
    // byte 4: configuration register
    // byte 5: internal use
    // byte 6: internal use
    // byte 7: internal use
    // byte 8: CRC
    for (byte pos = 0; pos < 9; pos++) {
        switch (pos) {
            case 0: temperature[0]       = onewire.read(); break;
            case 1: temperature[1]       = onewire.read(); break;
            case 2: highAlarmTemperature = onewire.read(); break;
            case 3: lowAlarmTemperature  = onewire.read(); break;
            case 4: configuration        = onewire.read(); break;
            case 8: crc                  = onewire.read(); break;
        }
    }

    onewire.reset();

    // 計算溫度值
    return (((unsigned int) temperature[1]) << 11) |
           (((unsigned int) temperature[0]) << 3);
}

/**
 * 根據DS18B20的說明文檔所述,不同精度的溫度轉換需要的時間不同
 * 需要等待DS18B20完成溫度轉換后再讀取溫度,否則得到的溫度為0℃
 */
unsigned int delayForResolution(byte bitResolution) {
    switch (bitResolution) {
        case  9: return  94; // 9位精度等待94ms
        case 10: return 188; // 10位精度等待188ms
        case 11: return 375; // 11位精度等待375ms
        default:
            return 750; // 默認等待750ms
    }
}
代碼還沒驗證過,大概是這樣啦~→_→←_←
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,406評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,034評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,413評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,449評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,165評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,559評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,606評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,781評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,327評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,084評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,278評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,849評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,495評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,927評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,172評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,010評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,241評論 2 375

推薦閱讀更多精彩內容