在Arduino中使用DS18B20温度传感器(基于OneWire和DallasTemperature库)

目的

DS18B20是常用的温度传感器,功能够用、使用简单,本文将用Arduino第三方的库来驱动DS18B20获取温度值。
DS18B20元件官方链接如下:
https://www.maximintegrated.com/cn/products/sensors/DS18B20.html

快速使用

相关库引入

两个库均在GitHub上,可以在release标签页中下载最新项目文件。

下载两个库的zip包后在Arduino IDE中选择:项目 > 加载库 > 添加一个 .ZIP库 ,两个库添加完成后就可以使用了。

如果你想将库文件都包含在自己的项目中那可以将相关文件和文件加放到项目文件夹里,然后修改DallasTemperature.h文件头部#include <OneWire.h>#include "OneWire.h",之后在项目中使用时用""引用DallasTemperature.h即可,比如#include "DallasTemperature.h"

使用步骤

  1. 引入相关库;
  2. 声明OneWireDallasTemperature对象;
  3. 使用DallasTemperaturebegin方法初始化总线;
  4. 发送温度转换请求;
  5. 读取温度值;

使用演示

演示一

以下演示是最简单的使用方式,但是性能上损失较大:

// #include <OneWire.h> //可以不引入,因为DallasTemperature.h中已经引入了OneWire.h
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 4 //1-wire数据总线连接在IO4
OneWire oneWire(ONE_WIRE_BUS); //声明
DallasTemperature sensors(&oneWire); //声明

void setup(void)
{
  Serial.begin(115200);
  Serial.println("");

  sensors.begin(); //初始化总线
}

void loop(void)
{
  Serial.println("发起温度转换");
  sensors.requestTemperatures(); //向总线上所有设备发送温度转换请求,默认情况下该方法会阻塞
  Serial.println("温度转换完成");

  float tempC = sensors.getTempCByIndex(0); //获取索引号0的传感器摄氏温度数据
  if (tempC != DEVICE_DISCONNECTED_C) //如果获取到的温度正常
  {
    Serial.print("当前温度是: ");
    Serial.print(tempC);
    Serial.println(" ℃\n");
  }

  delay(2000);
}

在这里插入图片描述

演示二

以下演示是一种非阻塞获取温度的方式,性能上消耗较少:

// #include <OneWire.h> //可以不引入,因为DallasTemperature.h中已经引入了OneWire.h
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 4               //1-wire数据总线连接在IO4
OneWire oneWire(ONE_WIRE_BUS);       //声明
DallasTemperature sensors(&oneWire); //声明

void setup(void)
{
  Serial.begin(115200);
  Serial.println("");

  sensors.begin(); //初始化总线
  sensors.setWaitForConversion(false); //设置为非阻塞模式
}

unsigned long previousMillis = 0; //毫秒时间记录
const long interval = 1000;       //时间间隔
void loop(void)
{
  //以下段落相当于每秒读取前次温度,并发起新一次温度转换
  unsigned long currentMillis = millis();         //读取当前时间
  if (currentMillis - previousMillis >= interval) //如果和前次时间大于等于时间间隔
  {
    previousMillis = currentMillis; //更新时间记录

    float tempC = sensors.getTempCByIndex(0); //获取索引号0的传感器摄氏温度数据
    if (tempC != DEVICE_DISCONNECTED_C)       //如果获取到的温度正常
    {
      Serial.print("\n当前温度是: ");
      Serial.print(tempC);
      Serial.println(" ℃");
    }

    Serial.println("发起温度转换");
    sensors.requestTemperatures(); //发起新的温度转换
  }

  delay(20);
  Serial.print(".");
}

在这里插入图片描述
上图可以看到在转换温度过程中用户还可以做别的事(这里打印了".")

演示三

以下演示中展示了更多DallasTemperature库中的方法:

// #include <OneWire.h> //可以不引入,因为DallasTemperature.h中已经引入了OneWire.h
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 4               //1-wire数据总线连接在IO4
OneWire oneWire(ONE_WIRE_BUS);       //声明
DallasTemperature sensors(&oneWire); //声明

DeviceAddress myDS18B20; //声明一个地址对象

void setup(void)
{
  Serial.begin(115200);
  Serial.println("");

  sensors.begin(); //初始化总线

  Serial.print("总线上DS18系列设备数量为:");
  Serial.println(sensors.getDS18Count());

  Serial.print("总线是否需要寄生供电(1-true; 0-false):");
  Serial.println(sensors.isParasitePowerMode());

  Serial.print("总线上设备数据最大分辨率为:");
  Serial.println(sensors.getResolution());

  sensors.setResolution(9); //设置总线上所有设备数据分辨率

  sensors.getAddress(myDS18B20, 0); //获取索引号0的设备地址(设备序列号)
}

void loop(void)
{
  Serial.println("\n发起温度转换");
  sensors.requestTemperaturesByAddress(myDS18B20); //向总线上指定地址传感器发送温度转换请求
  Serial.println("温度转换完成");

  int16_t temp = sensors.getTemp(myDS18B20); //获取指定地址传感器温度数据
  if (temp != DEVICE_DISCONNECTED_RAW) //如果获取到的温度正常
  {
    Serial.print("当前温度数据是: ");
    Serial.println(temp);
    Serial.print("当前摄氏是: ");
    Serial.println(DallasTemperature::rawToCelsius(temp));
  }

  delay(5000);
}

在这里插入图片描述

相关库说明

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

  • 27
    点赞
  • 240
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
### 回答1: DS18B20是一种常用的数字温度传感器,可以通过一根数据线与Arduino连接。它可以测量-55°C到125°C范围内的温度,并且具有高精度和高分辨率。使用Arduino来读取DS18B20传感器的温度需要使用OneWireDallasTemperature。 ### 回答2: arduino ds18b20温度传感器是一种数字式温度传感器。数字式温度传感器适用于各种工业、商业、办公环境下的温度测量以及各种设备的温度监控。 arduino ds18b20温度传感器是一种针对现代化的微电子设备而特别设计的一种传感器,具有精度高、速度快、模拟度低、功耗少和体积小等优点。其测温范围从-55℃ 到 +125℃,精确度可达到±0.5℃,在同类传感器属于较高水平。 arduino ds18b20温度传感器最大的特点是采用1-Wire协议传输数据,所需引脚只有一个,从而简化了使用难度和硬件实现。同时,可通过对其内部不同的ROM值区分不同的设备,从而方便设备的管理和使用。 除此之外,arduino ds18b20温度传感器还可以进行温度报警功能,即当温度低于或高于设定的范围时,可利用数字管或者其他适配装置来进行报警提示。 总之,arduino ds18b20温度传感器具有精度高、速度快、模拟度低、功耗少和体积小等优点,适用于各种工业、商业、办公环境下的温度测量以及各种设备的温度监控。同时,其简单易用的特点,也使得该传感器广泛应用于各种基于arduino开发板的DIY制作。 ### 回答3: Arduino DS18B20温度传感器是一种数字温度传感器,它可以与Arduino开发板一起使用来测量环境的温度。这个温度传感器具有一些很棒的特性,例如它只需要一个数字引脚进行通讯,而且可以在一个单独的芯片内处理温度测量。 Arduino DS18B20温度传感器采用的是1-Wire总线通讯协议,因此通过使用仅一个引脚来处理数据和电力,您可以同时连接多个传感器,这使得数据采集非常方便。另外,这个传感器也比较精度高,精度为±0.5°C(在-10°C至+85°C范围内)。 关于Arduino DS18B20温度传感器使用,有几个需要注意的事项。首先,您需要将传感器的信号引脚连接到Arduino的数字引脚,同时将其连接到电源和地线,以提供传感器所需的电力。然后,您需要下载并安装OneWireDallasTemperature,以便在Arduino IDE进行编程。 在编写代码方面,您可以使用DallasTemperature提供的函数来获取传感器的温度,并将其输出到串口监视器使用其他通讯方式传递数据。此外,您还可以使用传感器的ROM地址来识别不同的传感器和读取多个温度值,以对同一环境的不同温度进行测量。 总之,Arduino DS18B20温度传感器是一种非常好用的数字温度传感器,它易于使用且精度高,可以在许多应用使用。如果您需要测量环境温度,它可能会成为一个很好的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naisu Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值