基于Arduino Uno的温湿度传感器设计

目录

一、Arduino nano

(一)PIN分析

(二)Blink程序(Arduino基本程序)分析

二、HIGH和LOW引脚的两种状态辨析

三、UNO

四、接线图

五、代码部分

Version 1 —- 单显示屏( LCD1602A General)

Version 2—-双显示屏方案(LCD1602A I2C+ LCD1602A General)

五、IOT物联网方案(Esp8266实现)

Thinkspeak—-Matlab云端数据可视化分析


一、Arduino nano

(一)PIN分析

  • VIN是电源引脚(接+)
  • GND是接地(接-)
  • ANALOG是模拟引脚(模拟信号,可以输出和读取波形电压)
  • DIGITAL式数字引脚(数字信号,即只有高电平和低电平)
  • D13是一个测试引脚它自带一个LED灯名字叫L(用于快速测速板子bootloader是否正常安装)

(二)Blink程序(Arduino基本程序)分析

二、HIGH和LOW引脚的两种状态辨析

  1. HIGH(参考引脚)的含义取决于引脚(pin)的设置,引脚定义为INPUT或OUTPUT时含义有所不同。当一个引脚通过pinMode被设置为INPUT,并通过digitalRead读取(read)时。如果当前引脚的电压大于等于3V,微控制器将会返回为HIGH。 引脚也可以通过pinMode被设置为OUTPUT,并通过digitalWrite设置为HIGH。输入引脚的值将被一个内在的20K上拉电阻 控制 在HIGH上,除非一个外部电路将其拉低到LOW。 当一个引脚通过pinMode被设置为OUTPUT,并digitalWrite设置为HIGH时,引脚的电压应在5V。在这种状态下,它可以输出电流 。例如,点亮一个通过一串电阻接地或设置为LOW的OUTPUT属性引脚的LED
  2. LOW的含义同样取决于引脚设置,引脚定义为INPUT或OUTPUT时含义有所不同。当一个引脚通过pinMode配置为INPUT,通过digitalRead设置为读取(read)时,如果当前引脚的电压小于等于2V,微控制器将返回为LOW。 当一个引脚通过pinMode配置为OUTPUT,并通过digitalWrite设置为LOW时,引脚为0V。在这种状态下,它可以 !!!倒灌!!! 电流。例如,点亮一个通过串联电阻连接到+5V,或到另一个引脚配置为OUTPUT、HIGH的的LED。 数字引脚(Digital pins)定义,INPUT和OUTPUT
  • pinMode() //引脚的模式,step函数开头使用
    • void pinMode (uint8_t pin, uint8_t mode) //设置引脚的模式
    • 参数:
      • pin 引脚编号
      • mode: INPUT, OUTPUT, 或 INPUT_PULLUP.
  • digitalWrite() //写引脚的状态,也就是控制高低电压(LED亮,LED灭) 注意:!!!digital!!!
    • void digitalWrite (uint8_t pin, uint8_t value)
    • 参数
      • pin 参数:需要输出的引脚号。
      • value 参数:需要对应引脚输出的状态,value 只能是一个布尔值,也就是 0 和非 0。当 value 为 0 时,输出为 0V,当 value 为非 0 时,输出 5V。

三、UNO

有I2C模块引脚:

四、接线图

没有I2C整合的情况

LCD1602

电位器/PWN(有待测试)

Arduino Uno 引脚<->LCD1602 引脚
GND<->VSS
5V<->VDD
Pin 6(错误的带PWN功能的引脚会干扰lcd的正常工作)<->V0(用于控制显示屏对比度)
Pin 12<->RS
GND<->RW
Pin 11<->EN
Pin 5<->D4
Pin 4<->D5
Pin 3<->D6
Pin 2<->D7
3.3V<->BLA(A)
GND<->BLK(K)
DHT11
Arduino Uno 引脚<->DHT11 引脚
5V<->VCC
GND<->GND
Pin 13<->DATA
蜂鸣器
Arduino Uno 引脚<->蜂鸣器 引脚
5V<->VCC
GND<->GND
Pin 9<->I/O
LED
Arduino Uno 引脚<->LED引脚
Pin 8<->VCC/IN
GND<->GND

五、代码部分

LCD运行一段时间后出现乱码,已解决(4线接法,I2C模块还未测)

1.使用delaymicro(),疑似有效,通过在代码间设置微秒级别的延迟防止lcd读写忙导致数据丢失进而产生乱码

2.接线进行晃动测试,发现乱码问题并非线路接触不良

3.供电排查:v0不要使用pwn,会对lcd造成干扰,解决方法使用电位器串联5v实现降压同时又可以保证不会对lcd造成干扰,从而避免了乱码的问题

Version 1 —- 单显示屏( LCD1602A General)

  1. #include<DHT.h> //加载DHT的库
  2. #include <LiquidCrystal.h> // 加载LCD1602的库
  3. //定义LCD1602a
  4. const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // 定义引脚
  5. LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // 根据引脚,创建一个 lcd 实例
  6. int contrast = 6; // 定义对比度控制引脚,这里需要选择有PWM功能的引脚
  7. byte thisChar[8] = {
  8. 0b00111,
  9. 0b00101,
  10. 0b00111,
  11. 0b00000,
  12. 0b00000,
  13. 0b00000,
  14. 0b00000,
  15. 0b00000,
  16. };
  17. //定义DHT11
  18. int dhtpin = 7;
  19. DHT dht(dhtpin, DHT11);
  20. //定义蜂鸣器
  21. int buzzer = 9;
  22. //定义LED
  23. int led = 8;
  24. void setup()
  25. {
  26. //串口显示
  27. Serial.begin(9600); //设置波特率
  28. //LED启动配置
  29. pinMode(led,OUTPUT);
  30. //buzzer启动配置
  31. pinMode(buzzer, OUTPUT);
  32. //DHT11启动配置
  33. dht.begin();//让传感器开始工作
  34. //LCD启动配置
  35. pinMode(contrast, OUTPUT); // 配置 引脚模式为输出模式
  36. analogWrite(contrast, 120); // 该引脚一个固定频率的PWM信号,例如130
  37. lcd.begin(16, 2); // 初始化lcd ,并定义LCD1602的规格
  38. lcd.createChar(1, thisChar);
  39. lcd.setCursor(0, 0); // 设置指针 在x=0,y=0的位置
  40. lcd.print("Proton17 ^_^"); // lcd 显示字符串
  41. lcd.setCursor(0, 1); // 设置指针 在x=0,y=1的位置
  42. lcd.print("ID:20050102"); // lcd 显示字符串
  43. delay(5000);
  44. lcd.clear();
  45. }
  46. void loop() {
  47. int h = dht.readHumidity();//定义一个浮点数类型的变量,为传感器的湿度
  48. int t = dht.readTemperature();//定义一个浮点数类型的变量,为传感器的温度
  49. lcd.setCursor(0, 0);//显示在第1列,第1行
  50. lcd.print("Temperature:");//在显示屏上打印“温度是:”
  51. lcd.print(t);//在显示屏上打印温度值
  52. lcd.write(1);
  53. lcd.write("C");
  54. lcd.setCursor(0, 1);//显示在第1列,第2行
  55. lcd.print(" Humidity:");//在显示屏上打印“湿度是:”
  56. lcd.print(h);//在显示屏上打印湿度值
  57. lcd.write("%");
  58. if(t > 30 || h > 90){
  59. delay(1000);
  60. }
  61. else{
  62. delay(5000);
  63. }
  64. lcd.clear();
  65. //当温度大于30度或者湿度大于90的时候蜂鸣器报警,显示器给出相应警示
  66. if (t > 30 && h <= 90) {
  67. digitalWrite(led,HIGH);
  68. lcd.clear();
  69. digitalWrite(buzzer,HIGH);
  70. lcd.setCursor(0, 0);
  71. lcd.print("WARNING !!!");
  72. lcd.setCursor(0, 1);
  73. lcd.print("TOO HOT !");
  74. delay(3000);
  75. }
  76. else if(h > 90 && t <= 35){
  77. digitalWrite(led,HIGH);
  78. lcd.clear();
  79. digitalWrite(buzzer,HIGH);
  80. lcd.setCursor(0, 0);
  81. lcd.print("WARNING !!!");
  82. lcd.setCursor(0, 1);
  83. lcd.print("TOO WET");
  84. delay(3000);
  85. }
  86. else if(h > 90 && t > 35){
  87. digitalWrite(led,HIGH);
  88. lcd.clear();
  89. digitalWrite(buzzer,HIGH);
  90. lcd.setCursor(0, 0);
  91. lcd.print("WARNING !!!");
  92. lcd.setCursor(0, 1);
  93. lcd.print("TOO WET AND HOT !");
  94. delay(3000);
  95. }
  96. else{
  97. digitalWrite(led,LOW);
  98. digitalWrite(buzzer,LOW);
  99. }
  100. lcd.clear();
  101. //串口输出部分
  102. Serial.print("Humidity: ");
  103. Serial.print(h);
  104. Serial.print(" %\t");
  105. Serial.print("Temperature: ");
  106. Serial.print(t);
  107. Serial.print(" *C ");
  108. Serial.println(); //输入一个换行符
  109. }

Version 2—-双显示屏方案(LCD1602A I2C+ LCD1602A General)

ADDRESS的寻找 Arduino实践(二)lcd1602使用说明,源码,寻找IIC

商家:0x27

  1. #include<DHT.h> //加载DHT的库
  2. #include <LiquidCrystal.h> // 加载LCD1602的库
  3. #include <LiquidCrystal_I2C.h>//调用LCD1602 I2c显示屏的库
  4. //定义LCD1602a I2C
  5. LiquidCrystal_I2C lcd_1(0x27, 20, 4);//将 LCD 地址设置为???,用于 16 个字符和 2 行显示,ADDRESS
  6. //定义LCD1602a General
  7. const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // 定义引脚
  8. LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // 根据引脚,创建一个 lcd 实例
  9. //定义°这个符号默认字库中没有
  10. byte thisChar[8] = {
  11. 0b00111,
  12. 0b00101,
  13. 0b00111,
  14. 0b00000,
  15. 0b00000,
  16. 0b00000,
  17. 0b00000,
  18. 0b00000,
  19. };
  20. //警报温度和湿度的修改
  21. const int W_Ham = 65;
  22. const int W_Temp = 29;
  23. //定义DHT11
  24. int dhtpin = 10; //定义一个int类型的
  25. DHT dht(dhtpin, DHT11); //利用DHT这个类(class)创建一个对象名字叫dht,C++面对对象(这个创建过程叫实例化)部分
  26. //定义蜂鸣器
  27. int buzzer = 9;
  28. //定义LED
  29. int led = 8;
  30. void setup()
  31. {
  32. //当看见xxx.xx()是代表调用的是方法,.是成员运算符,作用是可以是访问类中的成员函数或者成员变量(访问成员变量这里没有出现)
  33. //串口显示
  34. Serial.begin(9600); //设置波特率,对应IDE中的设置,串口监视器中可以看到目前的波特率
  35. /*方法:类中的成员函数。为什么我没有看到
  36. Serial的实例化过程却可以使用它对应的方法,这是因为Serial是一个内置对象
  37. (Arduino已经为我们实例化了)*/
  38. //LED启动配置
  39. pinMode(led, OUTPUT); //pinMode()是Arduino的内置函数,意为设置对应编号引脚的模式
  40. //buzzer启动配置
  41. pinMode(buzzer, OUTPUT);
  42. //DHT11启动配置
  43. dht.begin(); //让DHT11传感器开始工作,语句为调用dht这个对象begin()这个方法
  44. //LCD启动配置
  45. lcd.begin(16, 2); //初始化lcd ,并定义LCD1602的规格,调用lcd这个实例的begin()方法
  46. lcd.createChar(1, thisChar); //初始化字库中没有的字符,调用lcd实例的createChar()方法
  47. //LCD_1启动配置,这个LCD和上面的LCD不是一块屏幕
  48. lcd_1.backlight(); //打开显示屏背光灯,调用lcd_1这个实例的backlight()方法
  49. lcd_1.init(); //初始化液晶屏,调用lcd_1这个实例的init()方法
  50. lcd_1.begin(16, 2); //设置行列值,调用lcd_1这个实例的begin()方法,后面类似
  51. lcd_1.setCursor(0, 0); //设置输入光标位置这个(0,0)可以将显示屏理解成二维数组,从0开始(不理解不看)
  52. lcd_1.print("Proton17 ^_^"); //打印名字
  53. lcd_1.setCursor(0, 1); //设置光标位置
  54. lcd_1.print("ID:20050102"); //打印一卡通号
  55. }
  56. void loop() {
  57. int h = dht.readHumidity();//定义一个浮点数类型的变量,为传感器的湿度
  58. int t = dht.readTemperature();//定义一个浮点数类型的变量,为传感器的温度
  59. lcd.setCursor(0, 0);//显示在第1列,第1行
  60. delayMicroseconds(1);
  61. lcd.print("Temperature:");//在显示屏上打印“温度是:”
  62. delayMicroseconds(1);
  63. lcd.print(t);//在显示屏上打印温度值
  64. delayMicroseconds(1);
  65. lcd.write(1);
  66. delayMicroseconds(1);
  67. lcd.write("C");
  68. delayMicroseconds(1);
  69. lcd.setCursor(0, 1);//显示在第1列,第2行
  70. delayMicroseconds(1);
  71. lcd.print(" Humidity:");//在显示屏上打印“湿度是:”
  72. delayMicroseconds(1);
  73. lcd.print(h);//在显示屏上打印湿度值
  74. delayMicroseconds(1);
  75. lcd.write("%");
  76. delayMicroseconds(1);
  77. if(t > W_Temp || h > W_Ham ){
  78. delay(500);
  79. }
  80. else{
  81. delay(1500);
  82. }
  83. lcd.clear();
  84. //当温度大于29度或者湿度大于65的时候蜂鸣器报警,显示器给出相应警示
  85. if (t > W_Temp && h <= W_Ham ) {
  86. digitalWrite(led,HIGH);
  87. lcd.clear();
  88. digitalWrite(buzzer,HIGH);
  89. lcd.setCursor(0, 0);
  90. delayMicroseconds(1);
  91. lcd.print("WARNING !!!");
  92. delayMicroseconds(1);
  93. lcd.setCursor(0, 1);
  94. delayMicroseconds(1);
  95. lcd.print("TOO HOT !");
  96. delay(1500);
  97. lcd.clear();
  98. }
  99. else if(h > W_Ham && t <= W_Temp){
  100. digitalWrite(led,HIGH);
  101. lcd.clear();
  102. delayMicroseconds(1);
  103. digitalWrite(buzzer,HIGH);
  104. lcd.setCursor(0, 0);
  105. delayMicroseconds(1);
  106. lcd.print("WARNING !!!");
  107. delayMicroseconds(1);
  108. lcd.setCursor(0, 1);
  109. delayMicroseconds(1);
  110. lcd.print("TOO WET");
  111. delay(1500);
  112. lcd.clear();
  113. }
  114. else if(h > W_Ham && t > W_Temp){
  115. digitalWrite(led,HIGH);
  116. lcd.clear();
  117. digitalWrite(buzzer,HIGH);
  118. lcd.setCursor(0, 0);
  119. delayMicroseconds(1);
  120. lcd.print("WARNING !!!");
  121. delayMicroseconds(1);
  122. lcd.setCursor(0, 1);
  123. delayMicroseconds(1);
  124. lcd.print("TOO WET AND HOT !");
  125. delayMicroseconds(1);
  126. delay(1500);
  127. lcd.clear();
  128. }
  129. else{
  130. digitalWrite(led,LOW);
  131. digitalWrite(buzzer,LOW);
  132. lcd.clear();
  133. }
  134. //串口输出部分,随便看看
  135. Serial.print("Humidity: ");
  136. Serial.print(h);
  137. Serial.print(" %\t");
  138. Serial.print("Temperature: ");
  139. Serial.print(t);
  140. Serial.print(" *C ");
  141. Serial.println(); //输入一个换行符
  142. }

五、IOT物联网方案(Esp8266实现)

Arduino IOT: Temperature and Humidity ( With ESP8266 WiFi)

Thinkspeak—-Matlab云端数据可视化分析

如何使用ThingSpeak和Arduino制作一款温度传感器

API Keys - ThingSpeak IoT

ESP8266 IOT Using Arduino and ThingSpeak : 5 Steps

GitHub - mathworks/thingspeak-arduino: ThingSpeak Communication Library for Arduino, ESP8266 and ESP32