11.Arduino基础入门— 8.收集温度信息,通过WIFI连接Mosquito服务器再存储到Mysql中

前言:很多参考来源于  https://blog.csdn.net/qq_28877125/article/details/78785472

这个东西是通过使用arduino UNO R3板子获取温湿度模块DHT11中的温湿度然后通过ESP8266WiFi模块发送到MQTT服务器上面,然后再在网页上面显示出来的。

自己补充画了一个图

 

涉及到的一些技术:

 

  • Arduino的基本使用:

arduino软件模拟串口的使用(网上资料很多)
DHT11的温湿度读取(有arduino官方库,网上资料也很多)

  • ESP8266WiFi模块AT指令的使用:

    从某宝上面买一块型号为ESP-01的WiFi模块(ESP8266是该类模块的芯片名字),型号有好多种,一开始我也买错了,后面换成ESP-01。
    买来的模块里面已经有程序,上电就可以运行的,一般是官方的AT固件
    该官方AT固件,是有使用指导书的,可以问店家要,也可以从官网下载,然后就可以知道怎么用了。
    arduino模块的串口引脚(我代码里面的串口引脚是软件模拟的)和买来的ESP-01模块的串口引脚相连接(R-T,T-R),然后再在代码里面,使用串口发送例如“AT+RST\r\n”的指令。

  • MQTT服务器的部署使用:

    一般是要有自己的MQTT服务器的,如果没有,网上也有公共的MQTT Broker可以暂时用一下,本篇文章用mosquitto作为消息中间件服务器,

  • 把订阅的消息插入到数据库中

      这里使用的是客户端插件,通过Node把订阅的消息插入到Mysql数据中。

 

 

Arduino所需要使用的库(重要):

arduino的MQTT库:PubSubClient by Nick O’Leary.

arduino的封装好AT指令的WiFi操作库:WiFiEsp by bportaluri

Adafruit Unified Sensor by Adafruit

DHT sensor library by Adafruit

第1个是MQQT用的、第2个是在Wifi执行AT指令的库、第4个是温度计的库

 

 

一、连上wifi

 一个wifi模块,要想连上网络首先得连上WiFi热点,所以使用AT指令来让WiFi模块连接上SSID。如果你的arduino IDE已经安装了以上那些库,那么就可以把下面的代码拷贝再修改一下 ssid 和 password就可以连接WiFi了。

  网上有些代码是调用ESP8266WiFi.h库来完成,一开始找了很久后面发现

  https://tttapa.github.io/ESP8266/Chap01%20-%20ESP8266.html

  ESP8266WiFi.h库适用于ESP8266作为主控芯片的板,不适合UNO R3+ESP8266的模式。

  

 

  所以后面变成下述的代码

 

 1 #include "DHT.h"
 2 #include <WiFiEspClient.h>
 3 #include <WiFiEsp.h>
 4 #include <WiFiEspUdp.h>
 5 #include <PubSubClient.h>
 6 #include "SoftwareSerial.h"
 7 
 8 #define WIFI_AP "jzc_28E7"
 9 #define WIFI_PASSWORD "Jzckj@2017"
10 
11 // DHT
12 //温度指针 7脚
13 //#define DHTPIN 7
14 //#define DHTTYPE DHT11
15 
16 char MqttServer[] = "127.0.0.1";
17 
18 // 初始化以太网客户端对象 -- WiFiEspClient.h
19 WiFiEspClient espClient;
20 
21 // 初始化DHT11传感器
22 //DHT dht(DHTPIN, DHTTYPE);
23 
24 // 初始化MQTT库PubSubClient.h的对象
25 PubSubClient client(espClient);
26 
27 SoftwareSerial soft(3, 2); // RX, TX
28 
29 int status = WL_IDLE_STATUS;
30 unsigned long lastSend;
31 
32 void setup() {
33   Serial.begin(9600);
34 //  dht.begin();
35   
36   InitWiFi();   
37   
38 
39 }
40 
41 void loop() {
42 
43 
44   status = WiFi.status();
45   if ( status != WL_CONNECTED) {
46     while ( status != WL_CONNECTED) {
47       Serial.print("[loop()]Attempting to connect to WPA SSID: ");
48       Serial.println(WIFI_AP);
49       // 连接WiFi热点
50       status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
51       delay(500);
52     }
53     Serial.println("[loop()]Connected to AP");
54   }
55  
56 
57 }
58   
59 void InitWiFi()
60 {
61   // 初始化软串口,软串口连接ESP模块
62   soft.begin(9600);
63   // 初始化ESP模块
64   WiFi.init(&soft);
65   // 检测WiFi模块在不在,宏定义:WL_NO_SHIELD = 255,WL_IDLE_STATUS = 0,
66   if (WiFi.status() == WL_NO_SHIELD) {
67     Serial.println("WiFi shield not present");
68     while (true);
69   }
70 
71   Serial.println("[InitWiFi]Connecting to AP ...");
72   // 尝试连接WiFi网络
73   while ( status != WL_CONNECTED) {
74     Serial.print("[InitWiFi]Attempting to connect to WPA SSID: ");
75     Serial.println(WIFI_AP);
76     // Connect to WPA/WPA2 network
77     status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
78     delay(500);
79   }
80   Serial.println("[InitWiFi]Connected to AP");
81 }
View Code

连接成功(以下的信息是打开串口调试助手,arduino会通过串口打印出来的信息,从中我们可以看到已经连接成功!):图是借用的,实际显示的类似。

这里写图片描述


 

二、连上温度传感器

 

  一个DHT11模块

  1 #include "DHT.h"
  2 #include <WiFiEspClient.h>
  3 #include <WiFiEsp.h>
  4 #include <WiFiEspUdp.h>
  5 #include <PubSubClient.h>
  6 #include "SoftwareSerial.h"
  7 
  8 // DHT
  9 #define DHTPIN 7 //温度指针 7脚
 10 #define DHTTYPE DHT11
 11 
 12 #define WIFI_AP "jzc_28E7"         //WIFI SSID
 13 #define WIFI_PASSWORD "Jzckj@2017" //WIFI 密码
 14 char MqttServer[] = "127.0.0.1"; //MQTT服务器
 15 
 16 const int tx = 2; //tx针脚
 17 const int rx = 3; //rx针脚
 18 SoftwareSerial soft(rx, tx); // RX, TX WIFI信号RX,TX针脚
 19 
 20 const int millisecond = 3000; //重复发送的周期, 默认1000毫秒=1秒
 21 
 22 // 初始化以太网客户端对象 -- WiFiEspClient.h
 23 WiFiEspClient espClient;
 24 
 25 // 初始化DHT11传感器
 26 DHT dht(DHTPIN, DHTTYPE);
 27 
 28 // 初始化MQTT库PubSubClient.h的对象
 29 PubSubClient client(espClient);
 30 
 31 int status = WL_IDLE_STATUS;
 32 unsigned long lastSend;
 33 
 34 void setup() {
 35   Serial.begin(9600);
 36   dht.begin();//DHT开始工作
 37   
 38   InitWiFi();   
 39   
 40   lastSend = 0;
 41 
 42 }
 43 
 44 void loop() {
 45 
 46   status = WiFi.status();
 47   if ( status != WL_CONNECTED) {
 48     while ( status != WL_CONNECTED) {
 49       Serial.print("[loop()]Attempting to connect to WPA SSID: ");
 50       Serial.println(WIFI_AP);
 51       // 连接WiFi热点
 52       status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
 53       delay(500);
 54     }
 55     Serial.println("[loop()]Connected to AP");
 56     
 57   }
 58 
 59    if ( millis() - lastSend > millisecond ) { // 用于定时1秒钟发送一次数据
 60     getAndSendTemperatureAndHumidityData(); // 获取温湿度数据
 61     lastSend = millis();
 62   }
 63 
 64 
 65 }
 66   
 67 void InitWiFi()
 68 {
 69   // 初始化软串口,软串口连接ESP模块
 70   soft.begin(9600);
 71   // 初始化ESP模块
 72   WiFi.init(&soft);
 73   // 检测WiFi模块在不在,宏定义:WL_NO_SHIELD = 255,WL_IDLE_STATUS = 0,
 74   if (WiFi.status() == WL_NO_SHIELD) {
 75     Serial.println("WiFi shield not present");
 76     while (true);
 77   }
 78 
 79   Serial.println("[InitWiFi]Connecting to AP ...");
 80   // 尝试连接WiFi网络
 81   while ( status != WL_CONNECTED) {
 82     Serial.print("[InitWiFi]Attempting to connect to WPA SSID: ");
 83     Serial.println(WIFI_AP);
 84     // Connect to WPA/WPA2 network
 85     status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
 86     delay(500);
 87   }
 88   Serial.println("[InitWiFi]Connected to AP");
 89 
 90 }
 91 
 92 //void InitTemp(){
 93 //    float h = dht.readHumidity();//读湿度
 94 //    float t = dht.readTemperature();//读温度,默认为摄氏度
 95 //   Serial.println((String)t+"C");
 96 //  }
 97 
 98 /*
 99  * 
100  * 读取温湿度数据
101  * 
102  */
103 void getAndSendTemperatureAndHumidityData()
104 {
105   Serial.println("Collecting temperature data.");
106 
107   // 大概250ms读取一次
108   float h = dht.readHumidity();
109   float t = dht.readTemperature();
110 
111   // 查看是否读取温湿度失败的
112   if (isnan(h) || isnan(t)) {
113     Serial.println("Failed to read from DHT sensor!");
114     return;
115   }
116 
117   Serial.print("Humidity: ");
118   Serial.print(h);
119   Serial.print(" %\t");
120   Serial.print("Temperature: ");
121   Serial.print(t);
122   Serial.print(" *C ");
123   Serial.println("");
124 
125   String temperature = String(t);
126   String humidity = String(h);
127 
128   // Just debug messages
129 //  Serial.print( "Sending temperature and humidity : [" );
130 //  Serial.print( temperature ); Serial.print( "," );
131 //  Serial.print( humidity );
132 //  Serial.print( "]   -> " );
133 
134 
135   /*
136   // 构建一个 JSON 格式的payload的字符串
137   String payload = "{";
138   payload += "\"temperature\":"; payload += temperature; payload += ",";
139   payload += "\"humidity\":"; payload += humidity;
140   payload += "}";
141 
142   // Send payload
143   char attributes[100];
144   payload.toCharArray( attributes, 100 );
145   
146   // boolean publish(const char* topic, const char* payload);
147   
148   client.publish( "v1/devices/me/telemetry", attributes );
149   Serial.print("[publish]-->>");
150   Serial.println( attributes );
151  */
152 }
View Code

 

三、通过MQTT客户端传送数据

前提是安装好mosquitto服务器,并测试好订阅端和发送端

  1 #include "DHT.h"
  2 #include <WiFiEspClient.h>
  3 #include <WiFiEsp.h>
  4 #include <WiFiEspUdp.h>
  5 #include <PubSubClient.h>
  6 #include "SoftwareSerial.h"
  7 
  8 // DHT
  9 #define DHTPIN 7 //温度指针 7脚
 10 #define DHTTYPE DHT11
 11 
 12 #define WIFI_AP "jzc_28E7"         //WIFI SSID
 13 #define WIFI_PASSWORD "Jzckj@2017" //WIFI 密码
 14 char MqttServer[] = "192.168.0.141"; //MQTT服务器 注意这里已经连上网络需要找到MQTT的实际IP地址,不能用本机的127.0.0.1地址了。
 15 
 16 const int tx = 2; //tx针脚
 17 const int rx = 3; //rx针脚
 18 SoftwareSerial soft(rx, tx); // RX, TX WIFI信号RX,TX针脚
 19 
 20 
 21 const int connect_wifi_delay_millisecond =500; //连接WIFI重试毫秒
 22 const int send_temp_millisecond = 3000; //重复发送温度的周期, 默认1000毫秒=1秒
 23 const int mqqt_retry_connect_millisecond=5000;  //如果连接MQQT服务器不成功,循环直到连接上MQTT服务器
 24 
 25 //串口波特率
 26 const int serial_port =9600;  
 27 
 28 //设置设备ID 
 29 const String deviceID = "tempDevice1";
 30 //mqqt服务器端口 
 31 const int mqqt_server_port = 1883; 
 32 
 33 // 初始化以太网客户端对象 -- WiFiEspClient.h
 34 WiFiEspClient espClient;
 35 
 36 // 初始化DHT11传感器
 37 DHT dht(DHTPIN, DHTTYPE);
 38 
 39 // 初始化MQTT库PubSubClient.h的对象
 40 PubSubClient client(espClient);
 41 
 42 int status = WL_IDLE_STATUS;
 43 unsigned long lastSend;
 44 
 45 void setup() {
 46   Serial.begin(9600);
 47   dht.begin();//DHT开始工作
 48   
 49   InitWiFi();    //初始化WIFI
 50   client.setServer( MqttServer, mqqt_server_port );      // 连接WiFi之后,连接MQTT服务器
 51   lastSend = 0;
 52 
 53 }
 54 
 55 void loop() {
 56 
 57   status = WiFi.status();
 58   if ( status != WL_CONNECTED) {
 59     while ( status != WL_CONNECTED) {
 60       Serial.print("[loop()]Attempting to connect to WPA SSID: ");
 61       Serial.println(WIFI_AP);
 62       // 连接WiFi热点
 63       status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
 64       delay(connect_wifi_delay_millisecond);
 65     }
 66     Serial.println("[loop()]Connected to AP");
 67     
 68   }
 69 
 70   if ( !client.connected() ) {
 71     reconnect();
 72   }
 73   
 74   if ( millis() - lastSend > send_temp_millisecond ) { // 用于定时1秒钟发送一次数据
 75     getAndSendTemperatureAndHumidityData(); // 获取温湿度数据
 76     lastSend = millis();
 77   }
 78 
 79   client.loop();
 80 
 81 }
 82   
 83 void InitWiFi()
 84 {
 85   // 初始化软串口,软串口连接ESP模块
 86   soft.begin(serial_port);
 87   // 初始化ESP模块
 88   WiFi.init(&soft);
 89   // 检测WiFi模块在不在,宏定义:WL_NO_SHIELD = 255,WL_IDLE_STATUS = 0,
 90   if (WiFi.status() == WL_NO_SHIELD) {
 91     Serial.println("WiFi shield not present");
 92     while (true);
 93   }
 94 
 95   Serial.println("[InitWiFi]Connecting to AP ...");
 96   // 尝试连接WiFi网络
 97   while ( status != WL_CONNECTED) {
 98     Serial.print("[InitWiFi]Attempting to connect to WPA SSID: ");
 99     Serial.println(WIFI_AP);
100     // Connect to WPA/WPA2 network
101     status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
102     delay(500);
103   }
104   Serial.println("[InitWiFi]Connected to AP");
105 
106 }
107 
108 
109 /*
110  * 
111  * 读取温湿度数据
112  * 
113  */
114 void getAndSendTemperatureAndHumidityData()
115 {
116   Serial.println("Collecting temperature data...");
117 
118   // 大概250ms读取一次
119   float h = dht.readHumidity();
120   float t = dht.readTemperature();
121 
122   // 查看是否读取温湿度失败的
123   if (isnan(h) || isnan(t)) {
124     Serial.println("Failed to read from DHT sensor!");
125     return;
126   }
127 
128   Serial.print("Humidity: ");
129   Serial.print(h);
130   Serial.print(" %\t");
131   Serial.print("Temperature: ");
132   Serial.print(t);
133   Serial.print(" *C ");
134   Serial.println("");
135 
136   String temperature = String(t);
137   String humidity = String(h);
138 
139 
140 //  PostData2MQTTServer(temperature,humidity);
141   // Just debug messages
142   Serial.print( "Sending temperature and humidity : [" );
143   Serial.print( temperature ); Serial.print( "," );
144   Serial.print( humidity );
145   Serial.print( "]   -> " );
146 
147 
148  
149   // 构建一个 JSON 格式的payload的字符串
150   String payload = "{";
151   payload += "\"temperature\":"; payload += temperature; payload += ",";
152   payload += "\"humidity\":"; payload += humidity;
153   payload += "}";
154 
155   // Send payload
156   char attributes[100];
157   payload.toCharArray( attributes, 100 );
158   
159   // boolean publish(const char* topic, const char* payload);
160   
161   //client.publish( "v1/devices/me/telemetry", attributes );
162   client.publish( "test", attributes );
163   Serial.print("[publish]-->>");
164   Serial.println( attributes );
165 
166 }
167 
168 // void PostData2MQTTServer(String temp,String hum)
169 //{
170 //   // 构建一个 JSON 格式的payload的字符串
171 //  String payload = "{";
172 //  payload += "\"temperature\":"; payload += temp; payload += ",";
173 //  payload += "\"humidity\":"; payload += hum;
174 //  payload += "}";
175 //
176 //  // Send payload
177 //  char attributes[100];
178 //  payload.toCharArray( attributes, 100 );
179 //  
180 //  // boolean publish(const char* topic, const char* payload);
181 //  
182 //  //client.publish( "v1/devices/me/telemetry", attributes );
183 //  client.publish( "test", attributes );
184 //  
185 //  Serial.print("[publish]-->>");
186 //  Serial.println( attributes );
187 //  }
188 
189 
190 /**
191  * 
192  * MQTT客户端断线重连函数
193  * 
194  */
195 
196 void reconnect() {
197   // 一直循环直到连接上MQTT服务器
198   while (!client.connected()) {
199     Serial.print("[reconnect]Connecting to MQTT Server ...");
200     // 尝试连接connect是个重载函数 (clientId, username, password)
201     if ( client.connect(deviceID.c_str()) )//client.connect(deviceID, NULL, NULL) )
202     {
203       Serial.println( "[DONE] MQTT Server is connect Now!Client:"+(String)deviceID.c_str() );
204     } else {
205       Serial.print( "[FAILED] [ mqtt connect error code = " );
206       Serial.print( client.state() );
207       Serial.println( " : retrying in 5 seconds]" );// Wait 5 seconds before retrying
208       delay( mqqt_retry_connect_millisecond );
209     }
210   }
211 }
View Code

传送成功的话会串口工具返回的信息如下

 

 

 

 

四、运行客户端插件把订阅的数据插入到数据库中

关于如何配置,可以参考10.Arduino基础入门— 7.如何把在Mosquitto服务器上订阅到的消息写入到数据库里面

其中在Node客户端获取到订阅的信息

 

 

注意:注意:注意:

ESP8266 ESP-01出厂默认的波特率是115200,需要把波特率改为9600,否则会导致传输数据失败。可以通过安信可的串口调试工具执行命令 AT+UART_DEF=9600,8,1,0,0修改为9600。

 

posted on 2019-09-25 11:31  Neo0820  阅读(142)  评论(0编辑  收藏  举报

导航