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

2023-11-04

目的

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Arduino中使用DS18B20温度传感器(基于OneWire和DallasTemperature库) 的相关文章

  • 读取串行端口 - 忽略在一定时间内写入串行端口的部分数据

    我想定期读取串行端口上的数据和Arduino 所以本质上是这样的 读一读 Wait 读一读 Wait Take etc 我面临的问题是端口将缓冲其信息 因此一旦我调用等待函数 串行端口上的数据就会开始缓冲 等待函数完成后 我尝试再次读取数据
  • 如何将 char 数组定义为常量?

    这里是 C C 菜鸟 我已经在头文件中定义了它 typedef unsigned char BitChar 9 8 data bytes chars and one width byte char extern BitChar BitFon
  • PySerial 从 Arduino 读取线路的延迟

    我正在使用带有基本 DigitalReadSerial 设置的 arduino uno 如下所述 http arduino cc en Tutorial DigitalReadSerial http arduino cc en Tutori
  • sim800L GPRS 发布请求

    我一直在研究 LoNet 迷你 GSM 模块 SIM800L 并将其与 Arduino 连接 我已插入 SIM 移动卡并且可以连接互联网 通过串行监视器 我可以毫无问题地与它通信 但是当向网络服务器页面发出 GET 或 POST 请求时 它
  • Arduino从SD卡读取最后一行

    我对 Arduino 业务还很陌生 如何从 SD 卡读取最后一行 通过以下代码片段 我可以读取第一行 n 之前的所有字符 现在我想添加一个 向后 声明 或其他内容 到目前为止我的代码 include
  • 带/不带类的回调函数指针 C++

    我被困 我正在尝试形成一个函数 它将吃掉无类函数指针和对象中的函数指针 这是我当前的代码 希望能解释更多 它应该在 Arduino 上运行 所以我不能使用大型库 首先 我在 Arduino 上使用这个库 SimpleTimer A time
  • HM10 ble改变特征值AT命令Arduino

    谁能帮我用AT命令写入特征值 或者如何使用Hm10模块将数据从arduino发送到另一个ble设备 HM10发送AT START后 会通告数据包 并且可以检测服务和特征 但特征值是默认的0x00 如何更改 多次检查数据表 但找不到能够执行相
  • 为什么使用 libnfc 和 PN532 SHIELD 时“找不到 NFC 设备”

    我在 ArchLinux 上安装了 libnfc 并通过我的 Adafruit PN532 arduino SHIELD 使用它 nfc list返回消息 未找到 NFC 设备 我在 etc nfc devices d pn532 conf
  • 将浮点数转换为字节数组的 C 函数

    我正在尝试创建一个函数来接受浮点变量并将其转换为字节数组 我找到了一段有效的代码片段 但如果可能的话 希望在函数中重用它 我也在使用 Arduino 环境 但我知道它接受大多数 C 语言 目前工作 float variable 1 11 b
  • 如何为 Arduino 或类似的微控制器编写 JavaScript 编译器? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我意识到这个问题会引起一些人的注意 并且我意识到 JavaScript 传统上是一种解释性语言 请让我解释一下 我是一名专门从事 We
  • 在 Arduino 上将整数/小数转换为十六进制?

    如何将整数或小数变量转换为十六进制字符串 我可以做相反的事情 将十六进制转换为整数 但我无法找出其他方法 这是为了Serial print 数组中的十六进制值 查看 Arduino 字符串教程here http arduino cc en
  • 如何提高 PySerial 读取速度

    我目前正在构建一台使用 Arduino Mega2560 作为主控制器的机器 Arduino 通过串口连接 获取命令 执行它并每 1ms 吐出一堆测量数据 我有一个运行 Python 的 Raspberry Pi 为用户提供一个漂亮的 GU
  • 通过iPhone音频插孔读取数据

    我正在寻找一种方法来读取通过 iPhone 的音频插孔从 Arduino 发送的原始数据 我搜索了很多并发现this https github com sanjibahmad Is Headphone Plugged In tree mas
  • Arduino串口数据解析

    我正在编写一个应用程序 通过蓝牙用我的 Android 手机控制我的机器人 一切都很顺利 数据得到回显和验证 但我在协议方面遇到了一些问题 特别是我希望我的机器人的轮子在我发送时转动一个命令 例如s 10 100 or s 30 10 数值
  • 如何在 Arduino 中将 char 变量作为数字打印到串行端口?

    我正在使用 Arduino Uno 我正在从 EEPROM 读取一个字节值并将该值存储在类型变量中char 1 字节 我想将变量的值作为数字 而不是相应的 ASCII 代码 打印到串行监视器 例如考虑char val 5 我想查看串行监视器
  • Arduino Nano 33 IoT 的软件序列号

    我计划从旧的 5V Arduino Nano 迁移到新的 Arduino Nano 33 IoT 我已经使用软件串行 SoftwareSerial h 为旧的 5V Arduino Nano 编写了一个功能代码 以便与 Sim800L 模块
  • Arduino sprintf float 未格式化

    我有这个arduino草图 char temperature 10 float temp 10 55 sprintf temperature f F temp Serial println temperature 温度打印为 F 关于如何格
  • 如何将 Android 应用程序正确连接到支持蓝牙的 Arduino 微控制器上的 RFCOMM 套接字?

    我正在与我大学的一些学生合作开发一个简单的蓝牙 Android 应用程序 该应用程序将用于与连接有蓝牙模块的 Arduino 微控制器进行串行通信 RFCOMM 据我所知 我正在使用正确的蓝牙地址和 UUIDRFCOMM SPP 00001
  • Arduino 上的串行消息到整数

    我希望我的 Arduino 通过串行通信接收一个整数 你能帮我解决这个问题吗 它应该是这样的形式 int value strtoint Serial read 有多种方法可以读取整数Serial 很大程度上取决于数据发送时的编码方式 Ser
  • Arduino 引导加载程序

    有人可以解释一下如何Arduino引导加载程序 http code google com p arduino source browse tags 0019 hardware arduino bootloaders atmega ATmeg

随机推荐

  • (三)运行微信小程序:在主页加入扫码组件

    制作了多个页面后 我们试图在小程序中添加些其他功能 比如实现扫码功能 1 在二维码生成网站上 生成一张二维码或条形码照片 百度 二维码生成 即可找到生成网站 这里我们使用 2023你好吗 数字加文字的形式生成如下二维码 并保存到本地 供后续
  • OpenCV获取摄像头编号及名称

    欢迎使用Markdown编辑器 你好 这是你第一次使用 Markdown编辑器 所展示的欢迎页 如果你想学习如何使用Markdown编辑器 可以仔细阅读这篇文章 了解一下Markdown的基本语法知识 方法 OpenCV的VideoCapt
  • Github 项目托管

    为了方便代码的管理 可以使用 github 来托管我们的项目 把每次更新的代码放到 github 上还能够提高代码的共享性 首先需要注册并登我们的 github 账号 https github com 新建仓库 New repository
  • DataPipeline如何实现数据质量管理

    数据质量管理已经成为数据治理的重要组成部分 高质量的数据是企业进行决策的重要依据 DataPipeline数据质量平台整合了数据质量分析 质量校验 质量监控等多方面特性 以保证数据质量的完整性 一致性 准确性及唯一性 帮助企业解决在数据集成
  • vue+webpack实现异步组件加载

    8 9更新 之前想搬迁到csdn的时候由于邀请码问题迟迟没把博客转过来 所以跑去博客园了 今天发现csdn已经帮我把文章搬过来 有必要修正一下这篇文章 写这篇文章的时候因为刚接触vue 所以捣鼓的时候有些迷糊 以下可以跳过 本来很简单的事情
  • Centos8 Failed to download metadata for repo ‘AppStream‘解决

    1 这个问题主要原因是 CentOs Linux 8 从 2021 10 31 号后已经停止维护 CentOS 8 将不再从 CentOS 官方项目获得开发资源 所以之后更新镜像需要通过 vault centos org来获取更新 2 进入
  • 无向图的表示:邻接矩阵和邻接表

    这里将一个无向图用邻接表和邻接矩阵表示 输入 顶底个数n 图中的各个边 用两个顶点表示 输出 这个无线图的邻接矩阵和邻接表 其中邻接表中的链接按元素大小升序排列 先给出一个例子说明 假设有无向图如下 则其邻接矩阵和邻接表如提示框中所示 其实
  • javaweb项目实战(附有源码)

    这个代码是我做微信小程序的时候 专门用java做的web项目 主要是为前端提供接口 便于前端调用数据 如果有想要参考javaweb项目如何做的小伙伴 可以到github上下载 github上有前端和后端代码 在wiki上还有表结构和接口文档
  • VIM 点滴积累

    删除列 1 光标定位到要操作的地方 2 CTRL v 进入 可视 块 模式 选取这一列操作多少行 3 d 删除 插入列 插入操作的话知识稍有区别 例如我们在每一行前都插入 1 光标定位到要操作的地方 2 CTRL v 进入 可视 块 模式
  • java stream SONObject和JSONArray操作

    转自 https zhuanlan zhihu com p 36865573 1 取最后一条数据 stream对象存在方法findFirst 我们可以很方便的取到第一条数据 但它却没有findLast方法 需要取到最后一条数据 我们可以将数
  • 模型微调(Finetune)

    参考 https zhuanlan zhihu com p 35890660 ppt下载地址 https github com jiangzhubo What is Fine tuning 一 什么是模型微调 给定预训练模型 Pre tra
  • IDDPM论文阅读

    论文链接 Improved Denoising Diffusion Probabilistic Models 文章目录 摘要 引言 去噪扩散概率模型 定义 实际训练 对数似然改善 可学习的
  • Linux-Shell技巧-参数化alias

    shell脚本提供了改写命令方式 alias 但是alias改写常用的是直接改写方式 比如如下操作 alias ll ls alt alias g gvim 但通常情况下 有的明林需要传递参数 或者用户可以自定义话一些常用的路径 但有些文件
  • docker-/var/lib/docker数据迁移

    docker默认目录是 var lib docker 位于系统盘上 占用空间比较大 计划迁移到新挂在的盘上 第一步 在新盘上创建文件夹 mkdir p data docker lib 第二步 复制文件到新目录 rsync avz var l
  • 数据结构与算法(二十)快速排序、堆排序(四)

    数据结构与算法 三 软件设计 十九 https blog csdn net ke1ying article details 129252205 排序 分为 稳定排序 和 不稳定排序 内排序 和 外排序 内排序指在内存里 外排序指在外部存储空
  • electron-vue工程创建

    创建工程 创建一个工作文件夹用于存放所有Electron工程 设为 D work 打开CMD cd到 D work 文件夹下 然后执行命令 创建 electron vue 工程 创建过程会多次提示输入信息 vue init simulate
  • 【2011集训队出题】Digit

    Description 在数学课上 小T又被老师发现上课睡觉了 为了向全班同学证明小T刚才没有好好听课 数学老师决定出一道题目刁难一下小T 如果小T答不出 那么 情节就按照俗套的路线发展下去了 小T显然无法解决这么复杂的问题 可怜的小T只能
  • 联想拯救者系统重装?不求人教程

    前阵子帮人重装了联想原装系统 今天总结一下步骤 造福那些想给女同志装联想原装系统而无从下手的工具人 哈哈哈哈哈 进入正题 既然要重装系统 就绕不开做启动盘 要做一个玉洁冰清 小声BB 纯净无插件 的启动盘 U盘启动盘制作工具的选择就很关键
  • 爬虫毕设(三):爬取动态网页

    动态网页分析 按照上一篇的分析 直接使用XPath找到该标签 然后通过parse提取出数据 在写入到item中就完事了 但是 当信心满满的写完代码后却发现 控制台输入了一个简简单单的 小问号你是否有很多朋友 一顿操作猛如虎 一看输出数据无
  • 在Arduino中使用DS18B20温度传感器(基于OneWire和DallasTemperature库)

    文章目录 目的 快速使用 相关库引入 使用步骤 使用演示 演示一 演示二 演示三 相关库说明 OneWire库 DallasTemperature库 总结 目的 DS18B20是常用的温度传感器 功能够用 使用简单 本文将用Arduino第