您的位置:首页 > 产品设计 > UI/UE

Arduino--ESP8266--ESP-01学习笔记--连接WiFi、连接MQTT服务器、web显示

2017-12-12 19:59 2366 查看


所有的启发来源–国外网站:https://create.arduino.cc/projecthub/thingsboard/temperature-dashboard-using-arduino-uno-esp8266-and-mqtt-5e26eb

需要的库:

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

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

Adafruit Unified Sensor by Adafruit

DHT sensor library by Adafruit

一、连上wifi

#include "WiFiEsp.h"

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(6, 7); // RX, TX
#endif

char ssid[] = "liefyuan";            // your network SSID (name)
char pass[] = "123456789";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

void setup()
{
// initialize serial for debugging
Serial.begin(9600);
// initialize serial for ESP module
Serial1.begin(115200);
// initialize ESP module
WiFi.init(&Serial1);

// check for the presence of the shield
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue
while (true);
}

// attempt to connect to WiFi network
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network
status = WiFi.begin(ssid, pass);
}

Serial.println("You're connected to the network");
}

void loop()
{
// print the network connection information every 10 seconds
Serial.println();
printCurrentNet();
printWifiData();

delay(10000);
}

void printWifiData()
{
// print your WiFi shield's IP address
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);

// print your MAC address
byte mac[6];
WiFi.macAddress(mac);
char buf[20];
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
Serial.print("MAC address: ");
Serial.println(buf);
}

void printCurrentNet()
{
// print the SSID of the network you're attached to
Serial.print("SSID: ");
Serial.println(WiFi.SSID());

// print the MAC address of the router you're attached to
byte bssid[6];
WiFi.BSSID(bssid);
char buf[20];
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[5], bssid[4], bssid[3], bssid[2], bssid[1], bssid[0]);
Serial.print("BSSID: ");
Serial.println(buf);

// print the received signal strength
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI): ");
Serial.println(rssi);
}


连接成功:



二、真正的干货

问题一:由于波特率导致的ESP-01模块上传数据不成功!这个问题让我痛苦很久,Google、github……各种找——-最后居然是波特率导致!!!!arduino的软串口连接ESP-01wifi模块不适合波特率为115200(出厂时默认设定的!)在AT模式下输入
AT+UART_DEF=9600,8,1,0,0
修改为9600。修改过后问题全部解决!

结论:PubSubClient这个库是个非常优秀的MQTT库。WiFiESP这个底层是AT指令封装的库也是个非常优秀的库!

代码:

#include "DHT.h"
#include <WiFiEspClient.h>
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>
#include <PubSubClient.h>
#include "SoftwareSerial.h"

#define WIFI_AP "liefyuan"
#define WIFI_PASSWORD "123456789"

// DHT
#define DHTPIN 4
#define DHTTYPE DHT11

char MqttServer[] = "101.200.46.138";

// 初始化以太网客户端对象 -- WiFiEspClient.h
WiFiEspClient espClient;

// 初始化DHT11传感器
DHT dht(DHTPIN, DHTTYPE);

// 初始化MQTT库PubSubClient.h的对象
PubSubClient client(espClient);

SoftwareSerial soft(2, 3); // RX, TX

int status = WL_IDLE_STATUS;
unsigned long lastSend;

void setup() {

Serial.begin(9600);
dht.begin();

InitWiFi();                                // 连接WiFi
client.setServer( MqttServer, 1883 );      // 连接WiFi之后,连接MQTT服务器

lastSend = 0;
}

void loop() {
status = WiFi.status();
if ( status != WL_CONNECTED) {
while ( status != WL_CONNECTED) {
Serial.print("[loop()]Attempting to connect to WPA SSID: ");
Serial.println(WIFI_AP);
// 连接WiFi热点
status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
delay(500);
}
Serial.println("[loop()]Connected to AP");
}

if ( !client.connected() ) {
reconnect();
}

if ( millis() - lastSend > 1000 ) { // 用于定时1秒钟发送一次数据
getAndSendTemperatureAndHumidityData(); // 获取温湿度数据发送到MQTT服务器上去
lastSend = millis();
}

client.loop();
}

/*
*
* 读取温湿度数据,然后发送到MQTT服务器上去
*
*/
void getAndSendTemperatureAndHumidityData()
{
Serial.println("Collecting temperature data.");

// 大概250ms读取一次
float h = dht.readHumidity();
float t = dht.readTemperature();

// 查看是否读取温湿度失败的
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}

Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.print(" *C ");

String temperature = String(t);
String humidity = String(h);

// Just debug messages
Serial.print( "Sending temperature and humidity : [" );
Serial.print( temperature ); Serial.print( "," );
Serial.print( humidity );
Serial.print( "]   -> " );

// 构建一个 JSON 格式的payload的字符串
String payload = "{";
payload += "\"temperature\":"; payload += temperature; payload += ",";
payload += "\"humidity\":"; payload += humidity;
payload += "}";

// Send payload
char attributes[100];
payload.toCharArray( attributes, 100 );

// boolean publish(const char* topic, const char* payload);

client.publish( "v1/devices/me/telemetry", attributes );
Serial.print("[publish]-->>");
Serial.println( attributes );
}

void InitWiFi()
{
// 初始化软串口,软串口连接ESP模块
soft.begin(9600);
// 初始化ESP模块
WiFi.init(&soft);
// 检测WiFi模块在不在,宏定义:WL_NO_SHIELD = 255,WL_IDLE_STATUS = 0,
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
while (true);
}

Serial.println("[InitWiFi]Connecting to AP ...");
// 尝试连接WiFi网络
while ( status != WL_CONNECTED) {
Serial.print("[InitWiFi]Attempting to connect to WPA SSID: ");
Serial.println(WIFI_AP);
// Connect to WPA/WPA2 network
status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
delay(500);
}
Serial.println("[InitWiFi]Connected to AP");
}

/**
*
* MQTT客户端断线重连函数
*
*/

void reconnect() {
// 一直循环直到连接上MQTT服务器
while (!client.connected()) {
Serial.print("[reconnect]Connecting to MQTT Server ...");
// 尝试连接connect是个重载函数 (clientId, username, password)
if ( client.connect("liefyuan", NULL, NULL) ) {
Serial.println( "[DONE]" );
} else {
Serial.print( "[FAILED] [ mqtt connect error code = " );
Serial.print( client.state() );
Serial.println( " : retrying in 5 seconds]" );// Wait 5 seconds before retrying
delay( 5000 );
}
}
}


自己用Qt5编译出来的MQTT客户端调试软件:



服务器上:



web显示

效果图:



HTML5网页代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DHT11温湿度WEB显示</title>
<script src="{{ url_for('static', filename=('js/jquery-3.1.1.min.js')) }}"></script>
<script src="{{ url_for('static', filename=('js/echarts.common.min.js')) }}"></script>
<style type="text/css">
#main-container{
margin-top: 20px;
margin-left: 200px;
}

#main-temp{
width: 400px;
height:350px;
float: left;
border:1px solid red;
margin-left: 100px;

}

#main-humi{
width: 400px;
height:350px;
float: left;
border:1px solid red;
margin-left: 100px;
}
</style>
</head>
<body>
<!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
<div id="main-container">

<div id="main-temp"></div>
<div id="main-humi"></div>
</div>

<script src="https://cdn.bootcss.com/paho-mqtt/1.0.2/mqttws31.min.js"></script>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var temprature = [];
var humidity = [];
var myChart = echarts.init(document.getElementById('main-temp'));
var mychart2 = echarts.init(document.getElementById('main-humi'));
option = {
title: {
text: '温度动态数据图'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#283b56'
}
}
},
toolbox: {
show: true,
feature: {
dataView: {readOnly: false},
restore: {},
saveAsImage: {}
}
},
dataZoom: {
show: false,
start: 0,
end: 100
},
xAxis: [
{
type: 'category',
boundaryGap: true,
data: (function (){
var now = new Date();
var res = [];
var len = 10;
while (len--) {
res.unshift(now.toLocaleTimeString().replace(/^\D*/,''));
now = new Date(now - 2000);
}
return res;
})()
},
{
type: 'category',
name: '时间',
boundaryGap: true,
data: (function (){
var res = [];
var len = 10;
while (len--) {
res.push(len + 1);
}
return res;
})()
}
],
yAxis: [
{
type: 'value',
scale: true,
name: '温度(℃)',
max: 100,
min: 0,
boundaryGap: [0.2, 0.2]
},
{
type: 'value',
scale: true,
max: 100,
min: 0,
boundaryGap: [0.2, 0.2]
},
],
series: [{
name:'温度',
type:'line',
xAxisIndex: 1,
yAxisIndex: 1,
data:(function (){
var res = [];
var len = 10;
while (len--) {
res.push(0);
}
return res;
})()
}
]
};

option2 = {
title: {
text: '湿度动态数据图'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#283b56'
}
}
},
toolbox: {
show: true,
feature: {
dataView: {readOnly: false},
restore: {},
saveAsImage: {}
}
},
dataZoom: {
show: false,
start: 0,
end: 100
},
xAxis: [
{
type: 'category',
boundaryGap: true,
data: (function (){
var now = new Date();
var res = [];
var len = 10;
while (len--) {
res.unshift(now.toLocaleTimeString().replace(/^\D*/,''));
now = new Date(now - 2000);
}
return res;
})()
},
{
type: 'category',
name: '时间',
boundaryGap: true,
data: (function (){
var res = [];
var len = 10;
while (len--) {
res.push(len + 1);
}
return res;
})()
}
],
yAxis: [
{
type: 'value',
scale: true,
name: '湿度(%)',
max: 100,
min: 0,
boundaryGap: [0.2, 0.2]
},
{
type: 'value',
scale: true,
max: 100,
min: 0,
boundaryGap: [0.2, 0.2]
},
],
series: [{
name:'湿度',
type:'line',
xAxisIndex: 1,
yAxisIndex: 1,
data:(function (){
var res = [];
var len = 10;
while (len--) {
res.push(0);
}
return res;
})()
}
]
};

client = new Paho.MQTT.Client("www.liefyuan.top", Number(9001), "websockets-test");//建立客户端实例
client.connect({onSuccess:onConnect});//连接服务器并注册连接成功处理事件
function onConnect() {
console.log("onConnected");

topic = 'v1/devices/me/telemetry';

client.subscribe(topic);//订阅主题
console.log("subscribed");
//发送消息
}
client.onConnectionLost = onConnectionLost;//注册连接断开处理事件
client.onMessageArrived = onMessageArrived;//注册消息接收处理事件
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
console.log("连接已断开");
}
}
function onMessageArrived(message) {

console.log("收到消息:"+message.payloadString);
console.log("主题:"+message.destinationName);

temprature = message.payloadString.slice(15,20);
humidity = message.payloadString.slice(32,37);

//console.log(temprature.slice(15,20));
//console.log(temprature.slice(32,37));

}

count = 11;
setInterval(function (){
axisData = (new Date()).toLocaleTimeString().replace(/^\D*/,'');
var data0 = option.series[0].data;
//            var data1 = option.series[1].data;
var data3 = option2.series[0].data;
//            var data4 = option2.series[1].data;

data0.shift();
data0.push(temprature);

//            data1.shift();
//            data1.push(humidity);

data3.shift();
data3.push(humidity);

//            data4.shift();
//            data4.push(humidity);

option.xAxis[0].data.shift();
option.xAxis[0].data.push(axisData);

option.xAxis[1].data.shift();
option.xAxis[1].data.push(count++);

option2.xAxis[0].data.shift();
option2.xAxis[0].data.push(axisData);

option2.xAxis[1].data.shift();
option2.xAxis[1].data.push(count++);

myChart.setOption(option);
mychart2.setOption(option2);
}, 2100);
</script>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: