「雕爺學編程」Arduino動手做(39)——DS18B20溫度傳感器3

37款傳感器與模塊的提法,在網絡上廣泛流傳,其實Arduino能夠兼容的傳感器模塊肯定是不止37種的。鑑於本人手頭積累了一些傳感器和執行器模塊,依照實踐出真知(一定要動手做)的理念,以學習和交流爲目的,這裏準備逐一動手試試多做實驗,不管成功與否,都會記錄下來——小小的進步或是搞不掂的問題,希望能夠拋磚引玉。

【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)
實驗三十九:DS18B20單總線數字溫度傳感器模塊

18B20數字溫度傳感器模塊實驗所需硬件清單

Arduino Uno開發板 X1
0.96寸OLED顯示屏X1
杜邦線 若干(備了9條)
高電平觸發有源蜂鳴器模塊X1
IIC/I2C 1602 LCD液晶屏模塊X1
18B20數字溫度傳感器模塊X2
LED發光二極管(綠、藍色)X2
高電平觸發單路5V繼電器模塊X1
Proto Shield 原型擴展板(帶mini麪包板)X1

程序六:高溫聲光報警器
(1)實驗開源圖形編程(Mind+、編玩邊學)

實驗串口返回情況

 

Arduino實驗場景圖

 

程序七:檢測不同18B20芯片的唯一編碼
(1)Arduino參考開源代碼

/*
  【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)
   程序七:檢測不同18B20芯片的唯一編碼
*/

#include <OneWire.h>

// 18S20溫度芯片I/O
OneWire ds(7);  // 在引腳 D7 上

void setup(void) {
  // 初始化輸入/輸出
  // 以 9600 的波特率啓動串口
  Serial.begin(9600);
}

void loop(void) {
  //用於將原始數據轉換爲C
  int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;

  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];

  //查找oneWire Bus上連接的所有設備
  if ( !ds.search(addr)) {
    Serial.print("沒有更多地址。\n");
    ds.reset_search();
    return;
  }

  Serial.print("R=");
  for ( i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX);
    Serial.print(" ");
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
    Serial.print("CRC 無效!\n");
    return;
  }

  if ( addr[0] == 0x10) {
    Serial.print("設備爲 18S20 系列設備。\n");
  }
  else if ( addr[0] == 0x28) {
    Serial.print("設備爲 18S20 系列設備。\n");
  }
  else {
    Serial.print("設備系列無法識別:0x");
    Serial.println(addr[0], HEX);
    return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);  // 開始轉換,最後備份電源開啓

  delay(1000);     // 也許 750 毫秒就足夠了,也許不行
  // 我們可能會在這裏執行 ds.depower(),但重置會處理它。

  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);    // 讀取便籤本

  Serial.print("P=");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {  // 我們需要 9 個字節
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print( OneWire::crc8( data, 8), HEX);
  Serial.println();

  //原始數據到C的轉換
  LowByte = data[0];
  HighByte = data[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // 測試大多數 sig 位
  if (SignBit) // 負數
  {
    TReading = (TReading ^ 0xffff) + 1; // 2 的補償
  }
  //乘以 (100 * 0.0625) 或 6.25
  Tc_100 = (6 * TReading) + TReading / 4;

  Whole = Tc_100 / 100;  // 將整數部分和小數部分分開
  Fract = Tc_100 % 100;

  Serial.print("溫度:");
  if (SignBit) // 如果是負數
  {
    Serial.print("-");
  }
  Serial.print(Whole);
  Serial.print(".");
  if (Fract < 10)
  {
    Serial.print("0");
  }
  Serial.print(Fract);

  Serial.print("\n");
  //結束轉換爲C
}

  

(2)實驗串口返回情況(18B20設備之一)

實驗串口返回情況(18B20設備之二)

 

程序八:串口打印實時攝氏溫度與華氏溫度值
(1)Arduino參考開源代碼

/*
  【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)
   程序八:串口打印實時攝氏溫度與華氏溫度值
*/

// 首先我們包含二個庫
#include <OneWire.h>
#include <DallasTemperature.h>

// 數據線插入 Arduino 上的引腳D7
#define ONE_WIRE_BUS 7

// 設置 oneWire 實例以與任何 OneWire 設備進行通信
//(不僅僅是Maxim/Dallas溫度IC)
OneWire oneWire(ONE_WIRE_BUS);

// 將我們的 oneWire 引用傳遞給達拉斯溫度。
DallasTemperature sensors(&oneWire);

void setup(void) {
  // 啓動串口
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");
  // 啓動庫
  sensors.begin();
}

void loop(void) {
  // 調用sensors.requestTemperatures() 來發布全球溫度
  // 請求總線上的所有設備
  Serial.print(" Requesting temperatures...");
  sensors.requestTemperatures(); //發送命令以獲取溫度讀數
  delay(1000); // 等待 1 秒讓溫度抓取穩定
  Serial.println("done");

  Serial.print("Temperature is: ");

  // 爲什麼是“byIndex”?
  // 同一總線上可以有多個 18B20。
  // 0指的是線上的第一個IC

  Serial.print(sensors.getTempCByIndex(0));
  Serial.print("° C  (");

  Serial.print(sensors.getTempFByIndex(0));
  Serial.print("° F) -");

  // 讀數之間暫停 1 秒
  delay(1000);
}

  

實驗串口返回情況

程序九:1602LCD屏實時顯示攝氏溫度與華氏溫度值
(1)實驗接線示意圖(這例18B20接D6)

(2)Arduino參考開源代碼

/*
  【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)
   程序九:1602LCD屏實時顯示攝氏溫度與華氏溫度值
*/

#include <OneWire.h>//導入相關庫
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>

const int SENSOR_PIN = 6; // Arduino 引腳連接到 18B20 傳感器的 DQ 引腳
OneWire oneWire(SENSOR_PIN);         // 設置一個 oneWire 實例
DallasTemperature sensors(&oneWire); // 將 oneWire 傳遞給 DallasTemperature 庫
LiquidCrystal_I2C lcd(0x27, 16, 2);  // I2C地址0x27,16列2行
float tempCelsius;    // 攝氏溫度
float tempFahrenheit; // 華氏溫度

void setup(){
  sensors.begin();    //初始化傳感器
  lcd.init();         //初始化液晶屏
  lcd.backlight();    // 打開背光 
}

void loop(){
  sensors.requestTemperatures();             // 發送命令獲取溫度
  tempCelsius = sensors.getTempCByIndex(0);  // 讀取攝氏溫度
  tempFahrenheit = tempCelsius * 9 / 5 + 32; // 將攝氏度轉換爲華氏度

  lcd.clear();
  lcd.setCursor(0, 0);       // 從第一行開始打印
  lcd.print(tempCelsius);    // 打印攝氏溫度
  lcd.print((char)223);      //打印°字符
  lcd.print("C");
  lcd.setCursor(0, 1);       // 從第二行開始打印
  lcd.print(tempFahrenheit); // 打印華氏溫度
  lcd.print((char)223);      //打印°字符
  lcd.print("F");

  delay(500);
}

  Arduino實驗場景圖

程序十:從多個 DS18B20 傳感器獲取溫度
(1)實驗接線示意圖

(2)Arduino參考開源代碼

/*
  【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)
   程序十:從多個 DS18B20 傳感器獲取溫度
*/

#include <OneWire.h>//導入驅動庫
#include <DallasTemperature.h>

// 數據線插入 Arduino 上的端口D4
#define ONE_WIRE_BUS 4
// 設置一個 oneWire 實例以與任何 OneWire 設備
//進行通信(不僅僅是 Maxim/Dallas 溫度 IC)
OneWire oneWire(ONE_WIRE_BUS);

// 將我們的 oneWire 引用傳遞給達拉斯溫度。
DallasTemperature sensors(&oneWire);

int numberOfDevices; //找到的溫度設備數量
// 我們將使用這個變量來存儲找到的設備地址
DeviceAddress tempDeviceAddress;

void setup(void) {
  // 啓動串口
  Serial.begin(9600);

  // 啓動庫
  sensors.begin();

  /// 獲取網絡上的設備數量
  numberOfDevices = sensors.getDeviceCount();

  // 定位總線上的設備
  Serial.print("Locating devices...");
  Serial.print("Found ");
  Serial.print(numberOfDevices, DEC);
  Serial.println(" devices.");

  // 循環遍歷每個設備,打印出地址
  for (int i = 0; i < numberOfDevices; i++) {
    //在線路中搜索地址
    if (sensors.getAddress(tempDeviceAddress, i)) {
      Serial.print("Found device ");
      Serial.print(i, DEC);
      Serial.print(" with address: ");
      printAddress(tempDeviceAddress);
      Serial.println();
    } else {
      Serial.print("Found ghost device at ");
      Serial.print(i, DEC);
      Serial.print(" but could not detect address. Check power and cabling");
    }
  }
}

void loop(void) {
  sensors.requestTemperatures(); // 發送命令獲取溫度
  //循環遍歷每個設備,打印出溫度數據
  for (int i = 0; i < numberOfDevices; i++) {
    //在線路中搜索地址
    if (sensors.getAddress(tempDeviceAddress, i)) {

      // 輸出設備ID
      Serial.print("Temperature for device: ");
      Serial.println(i, DEC);

      // 打印數據
      float tempC = sensors.getTempC(tempDeviceAddress);
      Serial.print("Temp C: ");
      Serial.print(tempC);
      Serial.print(" Temp F: ");
      // 將 攝氏溫度轉換爲華氏溫度
      Serial.println(DallasTemperature::toFahrenheit(tempC));
    }
  }
  delay(5000);
}

// 打印設備地址的函數
void printAddress(DeviceAddress deviceAddress) {
  for (uint8_t i = 0; i < 8; i++) {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

  

實驗串口返回情況(發現3個設備,顯示不同溫度)

Arduino實驗場景圖

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章