风筝
发表于: 2020-4-12 08:23:21 | 显示全部楼层

在本篇文章中,我们将学习如何使用Arduino和4位数码管设计基于DS18B20的温度计。只需简单地将Arduino与DS18B20数字防水温度传感器连接,并在共阳极数码管上以摄氏度显示温度值。


DS18B20温度传感器是1线数字温度传感器。它使用密封包装,可通过简单的1-Wire接口精确测量潮湿环境中的温度。它在公共总线上通信。这意味着它可以连接多个设备并仅使用Arduino的一个数字引脚读取其值。

Digital-Thermometer-in-Celsius.jpg


DS18B20防水数字温度传感器

以下是DS18B20传感器的预接线和防水版。当您需要在远处或潮湿的地方进行测量时,非常方便。传感器可以测量-55至125°C(-67°F至+ 257°F)之间的温度。电缆用PVC护套保护。


因为它是数字的,所以即使在很长的距离上也没有任何信号衰减。这些1线制数字温度传感器相当精确,即在大部分范围内为±0.5°C。板载数模转换器可提供高达12位的精度。它们适用于使用单个数字引脚的任何微控制器。

waterproof-temperature-sensor-ds18b20.jpg


唯一的缺点是它们使用Dallas 1-Wire协议,该协议有些复杂,并且需要一堆代码来解析通信。我们使用一个4.7k电阻,当使用传感器时,这是从DATA数据线引脚到VCC线的上拉电阻。


LM35与DS18B20

DS18B20在出厂时已校准为输出正确的温度。 LM35在出厂时已针对电压(而非温度)进行了校准,而Arduino必须将其转换为温度。


LM35是一个模拟温度传感器,因此输入中的任何失真都会迅速影响读数。但是DS18B20是数字温度传感器,因此输入不会影响输出读数。


如果使用长导线用于一定距离的温度测量,则导线长度会偏离模拟LM35传感器中的值。但是DS18B20是数字传感器,任何输出值都没有影响。


LM35的测量温度范围为−55°C至150°C,而DS18B20的测量温度范围为−50°C至125°C。Arduino的1个数字输出引脚可用于连接多个DS18B20,但LM35则不能。


所需的组件

●    Arduino UNO开发板

●    DS18B20防水温度传感器

●    共阳极7段数码管

●    7HC595

●    面包板

●    连接跳线


连接电路图

CIRCUIT-diagram.png


将DS18B20的VDD引脚连接到5V,将GND引脚连接到地。如下图所示,将其数据引脚连接到Arduino的数字引脚2,还连接到4.7K电阻(将4.7K电阻的​​另一端连接到5V)。


项目工作过程

DS18B20数字温度计提供9至12位(可配置)的温度读数,以指示设备的温度。它通过1-Wire总线进行通信,根据定义,该总线仅需要一条数据线(和地线)即可与中央微处理器进行通信。另外,它可以直接从数据线获取电源,从而无需外部电源。


DS18B20的主要功能是其直接数字温度传感器。用户可将温度传感器的分辨率配置为9、10、11或12位,分别对应于0.5°C、0.25°C、0.125°C和0.0625°C的增量。上电时的默认分辨率为12位。


以摄氏度为单位显示温度的源代码/程序

要使用Arduino和4位7段数码管设计基于DS18B20的温度计,并以摄氏度显示温度,您需要两个不同的库

1.  下载1 Wire库

2.  下载Dallas温度库

将这些添加到库文件到Arduino IDE,然后编译并上传代码。

  1. #include <OneWire.h>
  2. #include <DallasTemperature.h>
  3. #define ONE_WIRE_BUS 2
  4. OneWire oneWire(ONE_WIRE_BUS);
  5. DallasTemperature sensors(&oneWire);
  6. DeviceAddress insideThermometer;
  7. const int ledPin = 13;// LED connected to digital pin 13
  8. const int latchPin = 8;// Pin connected to ST_CP of 74HC595
  9. const int clockPin = 9;// Pin connected to SH_CP of 74HC595
  10. const int dataPin = 10;// Pin connected to DS of 74HC595
  11. const int digitPins[4] = {3,4,5,6}; //pins to control the 4 common anode pins of display
  12. const byte digit[12] = //seven segment digit bits + blank + minus
  13. {
  14. B00111111, //0
  15. B00000110, //1
  16. B01011011, //2
  17. B01001111, //3
  18. B01100110, //4
  19. B01101101, //5
  20. B01111101, //6
  21. B00000111, //7
  22. B01111111, //8
  23. B01101111, //9
  24. B00000000, //Blank
  25. B01000000 //-
  26. };
  27. int digitBuffer[4] = {
  28. 1};
  29. int digitScan = 0;
  30. int soft_scaler = 0;
  31. float tempC, tempF;
  32. int tmp;
  33. boolean sign = false;
  34. void setup() {
  35. TCCR2A = 0;
  36. TCCR2B = (1<<CS21);
  37. TIMSK2 = (1<<TOIE2);
  38. TCNT2 = 0;
  39. pinMode(ledPin, OUTPUT);
  40. for(int i=0;i<4;i++)
  41. {
  42. pinMode(digitPins[i],OUTPUT);
  43. }
  44. pinMode(latchPin, OUTPUT);
  45. pinMode(clockPin, OUTPUT);
  46. pinMode(dataPin, OUTPUT);
  47. sensors.begin();
  48. sensors.getAddress(insideThermometer, 0);
  49. }
  50. ISR(TIMER2_OVF_vect) {
  51. soft_scaler++;
  52. if(soft_scaler==15)
  53. {
  54. refreshDisplay();
  55. soft_scaler = 0;
  56. }
  57. };
  58. void refreshDisplay()
  59. {
  60. for(byte k=0;k<4;k++)
  61. {
  62. digitalWrite(digitPins[k], LOW);
  63. }
  64. digitalWrite(latchPin, LOW);
  65. shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
  66. digitalWrite(latchPin, HIGH);
  67. delayMicroseconds(50);
  68. digitalWrite(digitPins[digitScan], HIGH);
  69. digitalWrite(latchPin, LOW);
  70. if(digitScan==1)
  71. {
  72. shiftOut(dataPin, clockPin, MSBFIRST, ~(digit[digitBuffer[digitScan]] | B10000000));
  73. }
  74. else
  75. {
  76. shiftOut(dataPin, clockPin, MSBFIRST, ~digit[digitBuffer[digitScan]]);
  77. }
  78. digitalWrite(latchPin, HIGH);
  79. digitScan++;
  80. if(digitScan>3) digitScan=0;
  81. }
  82. void loop()
  83. {
  84. digitalWrite(ledPin, HIGH);
  85. sensors.requestTemperatures();
  86. tempC = sensors.getTempC(insideThermometer);
  87. tmp = int(tempC*10);
  88. if (tempC < 0){
  89. sign = true;
  90. tmp = abs(tmp);
  91. }
  92. else{
  93. sign = false;
  94. }
  95. if (int(tmp)/1000 == 0){
  96. digitBuffer[3] = 10;
  97. if (sign){
  98. digitBuffer[3] = 11;
  99. }
  100. }
  101. else{
  102. digitBuffer[3] = int(tmp)/1000;
  103. }
  104. if (int(tmp)/1000 == 0 && (int(tmp)%1000)/100 == 0) {
  105. digitBuffer[2] = 10;
  106. if (sign){
  107. digitBuffer[2] = 11;
  108. digitBuffer[3] = 10;
  109. }
  110. }
  111. else{
  112. digitBuffer[2] = (int(tmp)%1000)/100;
  113. }
  114. digitBuffer[1] = (int(tmp)%100)/10;
  115. digitBuffer[0] = (int(tmp)%100)%10;
  116. digitalWrite(ledPin, LOW);
  117. delay(500);
  118. }
复制代码

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1479



手机版|

GMT+8, 2024-3-28 23:55 , Processed in 0.095778 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表