「雕爷学编程」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实验场景图