回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

「雕爷学编程」Arduino动手做(39)——DS18B20温度传感器3 中等

头像 驴友花雕 2023.07.23 22 1

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试多做实验,不管成功与否,都会记录下来——小小的进步或是搞不掂的问题,希望能够抛砖引玉。

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验三十九:DS18B20单总线数字温度传感器模块
 

5.10-01.jpg

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
 

5.10-07.jpg

程序六:高温声光报警器
(1)实验开源图形编程(Mind+、编玩边学)
 

5.10-25.jpg

实验串口返回情况

 

5.10-26.jpg

Arduino实验场景图

 

5.10-27.jpg

程序七:检测不同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设备之一)
 

5.10-28.jpg

实验串口返回情况(18B20设备之二)

 

5.10-29.jpg

程序八:串口打印实时摄氏温度与华氏温度值
(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);
}

实验串口返回情况
 

5.10-30.jpg

程序九:1602LCD屏实时显示摄氏温度与华氏温度值
(1)实验接线示意图(这例18B20接D6)
 

5.10-31.jpg

(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实验场景图

 

5.10-32.jpg
5.10-33.jpg

程序十:从多个 DS18B20 传感器获取温度
(1)实验接线示意图
 

5.10-34.jpg

(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个设备,显示不同温度)
 

5.10-35.jpg

Arduino实验场景图
 

5.10-36.jpg

评论

user-avatar
  • hacker_

    hacker_2023.08.10

    666

    0
    icon 他的勋章
      展开更多