深度优先

这个家伙好懒,除了文章什么都没留下

0%

使用MQTT先要有一个MQTT服务器,具体如何搭建可以看上一篇文章

https://blog.csdn.net/qq_32688731/article/details/87702787

这一篇主要讲下NodeMCU的使用,以及MQTT介绍和如何接发消息

NodeMCU

1. ESP8266介绍

介绍NodeMCU前需要先了解ESP8266,它是一个完整自称体系的WiFi网络解决方案,能独立运行也可为从部件连接单片机运行

具有以下特点:

  • 超小尺寸
  • 低功耗
  • 内置TCP/IP协议
  • 可编程
  • 低成本

    2. NodeMCU介绍

NodeMCU是一款基于ESP8266模块的开源硬件,符合Arduino框架。同时可使用Node.js编程

NodeMCU引脚:

3. WiFi测试

先要安装Arduino IDE For ESP8266
Arduino IDE For ESP8266是根据Arduino修改的专门烧写ESP8266开发板的IDE。在装好Arduino IDE后:

  1. 打开Arduino 文件->首选项,在 附加开发管理网站 中填入http://arduino.esp8266.com/stable/package_esp8266com_index.json,然后点击确定保存
  1. 重启IDE后,打开 工具->开发板->开发板管理器;搜索ESP8266,选择esp 8266 by ESP8266 Community安装
  1. 下载完成后可以在开发板选项中看到ESP8266 Module,以及NodeMCU等可选开发板
  • 将NodeMCU通过usb连接到电脑,在工具下选择相应配置

波特率越大烧录程序速度越快但有可能出错
端口选择NodeMCU对应端口,如果没看到端口,那是驱动没有装,装驱动可以看这里

http://www.arduino.cn/thread-1008-1-1.html

  1. 打开示例选择ESP8266WiFi中的WiFiScan

烧到板子上打开窗口监视器可以看到扫描出来的附近热点

MQTT

1. MQTT介绍

消息队列遥测传输(MQTT)是IBM开发的即时通讯协议,为计算能力有限且工作在低带宽、不可靠网络的传感器或控制设备而设计。比如对于移动开发,它可以用于消息推送,即时通讯等等

特性:

  • 发布/订阅的消息模式,提供一对多的消息发布
  • 使用TCP/IP提供网络连接
  • 有三种消息发布服务质量,至多一次,至少一次,只有一次
  • 传输小、开销小
  • LastWill通知中断机制

    2. MQTT原理介绍

  • 客户端:发布者(Publish)、订阅者(SubScribe),客户端有ID,ID冲突会挤掉先连接客户端。
  • 服务器端:代理(Broker)
  • 消息:主题(Topic)+负载(payload)

举个场景为例:

QQ用户2(账号QQ1000)向QQ用户1(QQ9999)发送消息“Hello World”.
发送者:QQ用户2
订阅者:QQ用户1
消息:QQ9999+”Hello World”.

消息发送至服务器,服务器查找QQ9999对应的用户后,发送信息给QQ用户2.

3. MQTT ESP8266库

菜单“项目”-“加载库”-“管理库”,搜索安装“PubSubClient”

PubSubClient有一些示例可以打开mqtt_esp8266看下

4. MQTT接发消息体验

这里做两个示例
1. NodeMCU接受消息:服务器来控制LED灯状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "******";
const char* password = "******";
const char* mqtt_server = "******";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
int LED = 5; // LED引脚
void setup() {
pinMode(LED, OUTPUT); // Initialize the pin as an output
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}

void setup_wifi() {

delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();

// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '1') {
digitalWrite(LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is acive low on the ESP-01)
} else {
digitalWrite(LED, HIGH); // Turn the LED off by making the voltage HIGH
}

}

void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
// ... and resubscribe
client.subscribe("inTopic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void loop() {

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

long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
++value;
snprintf (msg, 75, "hello world #%ld", value);
Serial.print("Publish message: ");
Serial.println(msg);
client.publish("outTopic", msg);
}
}

2. NodeMCU发送消息:向服务器上传温度湿度信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <SimpleDHT.h>

WiFiClient espClient;
PubSubClient client(espClient);

int pinDHT11 = 5;
SimpleDHT11 dht11(pinDHT11);


const char* ssid = "1705";
const char* password = "Zoor170302";
const char* mqtt_server = "*****";


long lastMsg = 0;
char msg[50];
int value = 0;
int LedStatus = 4;
int LedOutPut = 14;

void setup() {
pinMode(LedStatus, OUTPUT);
pinMode(LedOutPut, OUTPUT);
Serial.begin(115200);

setup_wifi();

client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
// 连接wifi
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
digitalWrite(LedStatus, HIGH);
delay(500);
digitalWrite(LedStatus, LOW);
Serial.print(".");
}

Serial.println(WiFi.localIP());
}

// 订阅信息
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();

// // Switch on the LED if an 1 was received as first character
// if ((char)payload[0] == '1') {
// digitalWrite(LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// // but actually the LED is on; this is because
// // it is acive low on the ESP-01)
// } else {
// digitalWrite(LED, HIGH); // Turn the LED off by making the voltage HIGH
// }

}

void reconnect() {
while (!client.connected()) {
if (client.connect("ESP8266Client")) {
client.subscribe("inTopic");
digitalWrite(LedStatus, HIGH);
} else {
Serial.println("mqtt failed");
digitalWrite(LedStatus, HIGH);
delay(5000);
digitalWrite(LedStatus, LOW);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();

long now = millis();
if (now - lastMsg > 10000) {
lastMsg = now;

byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;

if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
delay(1000);
return;
}

float tep = formatFloat((float)temperature);
float hum = formatFloat((float)humidity);

snprintf(msg, 75, "{Tep: %ld,Hum: %ld}", temperature, humidity);

client.publish("outputDHT11", msg);
Serial.println(msg);
digitalWrite(LedOutPut, HIGH);
delay(50);
digitalWrite(LedOutPut, LOW);
}
}

float formatFloat(float f)
{
int temp = (f * 100);
return float(temp / 100);
}

3、向阿里云Iot平台上传数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <SimpleDHT.h>

WiFiClient espClient;
PubSubClient client(espClient);

int pinDHT11 = 5;
SimpleDHT11 dht11(pinDHT11);

const char* ssid = "1705";
const char* password = "Zoor170302";

const char* mqtt_server = "a1PifWnko4O.iot-as-mqtt.cn-shanghai.aliyuncs.com";
const char* mqtt_username = "vCgnBR7ax2AQIFFjo8mf&a1PifWnko4O";
const char* mqtt_password = "******";
const char* mqtt_clientId = "FESA234FBDS24|securemode=3,signmethod=hmacsha1,timestamp=789|";

const char* body = "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}"
const char* inTopic = "/sys/a1PifWnko4O/vCgnBR7ax2AQIFFjo8mf/thing/service/property/set";

#define ALINK_BODY_FORMAT "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST "/sys/a1PifWnko4O/vCgnBR7ax2AQIFFjo8mf/thing/event/property/post"

long lastMsg = 0;
char msg[50];
int value = 0;
int LedStatus = 4;
int LedOutPut = 14;

void setup() {
pinMode(LedStatus, OUTPUT);
pinMode(LedOutPut, OUTPUT);
Serial.begin(115200);

setup_wifi();

client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
// 连接wifi
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
digitalWrite(LedStatus, HIGH);
delay(500);
digitalWrite(LedStatus, LOW);
Serial.print(".");
}

Serial.println(WiFi.localIP());
}

// 订阅信息
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();

// // Switch on the LED if an 1 was received as first character
// if ((char)payload[0] == '1') {
// digitalWrite(LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// // but actually the LED is on; this is because
// // it is acive low on the ESP-01)
// } else {
// digitalWrite(LED, HIGH); // Turn the LED off by making the voltage HIGH
// }

}

void reconnect() {
while (!client.connected()) {
if (client.connect(mqtt_clientId,mqtt_username , mqtt_password)) {
// client.subscribe("inTopic");
digitalWrite(LedStatus, HIGH);
} else {
Serial.println("mqtt failed");
digitalWrite(LedStatus, HIGH);
delay(5000);
digitalWrite(LedStatus, LOW);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();

long now = millis();
if (now - lastMsg > 10000) {
lastMsg = now;

byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;

if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
delay(1000);
return;
}

char param[32];
char jsonBuf[128];

sprintf(param, "{\"CurrentTemperature\":%d},\"RelativeHumidity:%d\"",temperature,humidity);
sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
Serial.println(jsonBuf);
boolean d = client.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
Serial.print("publish:0 失败;1成功");
Serial.println(d);

digitalWrite(LedOutPut, HIGH);
delay(50);
digitalWrite(LedOutPut, LOW);
}
}

float formatFloat(float f)
{
int temp = (f * 100);
return float(temp / 100);
}

阿里云栗子:

https://help.aliyun.com/document_detail/104070.html?spm=a2c4g.11186623.6.773.5d2578dc2DCPeE

1、MQTT Server使用EMQTTD开源库,自行安装配置;
2、JS使用Websocket连接通信。
3、JS的MQTT库为paho-mqtt,git地址:https://github.com/eclipse/paho.mqtt.javascript.git

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<title></title>
<!-- <script src=“https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js” type=“text/javascript”> </script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>

<script>
var hostname = 'ip',
port = 8083,
clientId = 'client-' + Math.ceil(Math.random() * 1000),
timeout = 5,
keepAlive = 100,
cleanSession = false,
ssl = false,
userName = 'mao2080',
password = '123',
topic = '/World';
client = new Paho.MQTT.Client(hostname, port, clientId);
//建立客户端实例
var options = {
invocationContext: {
host: hostname,
port: port,
path: client.path,
clientId: clientId
},
timeout: timeout,
keepAliveInterval: keepAlive,
cleanSession: cleanSession,
useSSL: ssl,
userName: userName,
password: password,
onSuccess: onConnect,
onFailure: function (e) {
console.log(e);
s = "{time:" + new Date().Format("yyyy-MM-dd hh:mm:ss") + ", onFailure()}";
console.log(s);
}
};
client.connect(options);
//连接服务器并注册连接成功处理事件
function onConnect() {
console.log("onConnected");
s = "{time:" + new Date().Format("yyyy-MM-dd hh:mm:ss") + ", onConnected()}";
console.log(s);
client.subscribe(topic);
}

client.onConnectionLost = onConnectionLost;

//注册连接断开处理事件
client.onMessageArrived = onMessageArrived;

//注册消息接收处理事件
function onConnectionLost(responseObject) {
console.log(responseObject);
s = "{time:" + new Date().Format("yyyy-MM-dd hh:mm:ss") + ", onConnectionLost()}";
console.log(s);
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:" + responseObject.errorMessage);
console.log("连接已断开");
}
}

function onMessageArrived(message) {
s = "{time:" + new Date().Format("yyyy-MM-dd hh:mm:ss") + ", onMessageArrived()}";
console.log(s);
console.log("收到消息:" + message.payloadString);
}

function send() {
var s = document.getElementById("msg").value;
if (s) {
s = "{time:" + new Date().Format("yyyy-MM-dd hh:mm:ss") + ", content:" + (s) + ", from: web console}";
message = new Paho.MQTT.Message(s);
message.destinationName = topic;
client.send(message);
document.getElementById("msg").value = "";
}
}

var count = 0;

function start() {
window.tester = window.setInterval(function () {
if (client.isConnected) {
var s = "{time:" + new Date().Format("yyyy-MM-dd hh:mm:ss") + ", content:" + (count++) +
", from: web console}";
message = new Paho.MQTT.Message(s);
message.destinationName = topic;
client.send(message);
}
}, 1000);
}

function stop() {
window.clearInterval(window.tester);
}
function startLED() {
message = new Paho.MQTT.Message("1");
message.destinationName = topic;
client.send(message);
}
function stopLED() {
message = new Paho.MQTT.Message("0");
message.destinationName = topic;
client.send(message);
}

Date.prototype.Format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[
k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
</script>
</head>

<body>
<input type="text" id="msg" />
<input type="button" value="Send" onclick="send()" />
<input type="button" value="Start" onclick="start()" />
<input type="button" value="Stop" onclick="stop()" />

<input type="button" value="开灯" onclick="startLED()" />
<input type="button" value="关灯" onclick="stopLED()" />
</body>

</html>

转自:https://www.cnblogs.com/farmerkids/p/9133044.html

1、安装M2MQTT

注:.Net Core 项目是安装M2MqttDotnetCore

2、建立连接/订阅/发送消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{

MqttClient client = new MqttClient("IPAddress");

// 注册消息接收处理事件,还可以注册消息订阅成功、取消订阅成功、与服务器断开等事件处理函数
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

//生成客户端ID并连接服务器
string clientId = Guid.NewGuid().ToString();
client.Connect(clientId,"UserName","Password");

//// 订阅主题"/home/temperature" 消息质量为 2
client.Subscribe(new string[] { "/WorldTest" }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });


// 发布消息到主题 "/home/temperature" 消息质量为 2,不保留
client.Publish("/WorldTest", Encoding.UTF8.GetBytes("你是谁?"), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, false);

Console.ReadLine();
}

static void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
//处理接收到的消息
string msg = System.Text.Encoding.Default.GetString(e.Message);
Console.WriteLine("收到消息:" + msg + "\r\n");
}
}
}

3、参考文献

https://github.com/mohaqeq/paho.mqtt.m2mqtt

https://blog.csdn.net/Leytton/article/details/51896738