物料准备
NodeMCU V3一块、面包板一块、LED一个、杜邦线若干,0.96寸OLED显示屏(可选)
开发环境
编辑器:Arduino IDE 或 Visual Studio Code(需安装Arduino扩展)
开发语言: C/C++
服务器:目前采用的公有的mosquito服务器,地址是 test.mosquitto.org mqtt默认端口1883,仅作开发测试之用,
若要正式投入使用,建议使用大厂家的物联IoT服务平台,BAT都有~
操作步骤
1. 安装Arduino IDE,至Arduino官网下载安装即可
2. 根据NodeMCU V3的CP2102或CH340芯片的不同,需要自行安装相应驱动
3. Arduino IDE中添加Esp8266开发板
4. 安装PubSubClient模块
5. 导入示例代码,配置网络
6. 准备接线
7. 上传至开发板
8. App发送指令到云端
9. 开发板响应,LED亮或灭,完成
实践解释
由于1至4步骤基本是开发过程基本步骤,故不再赘述,本文主要演示如何使用MQTT加入远程控制。
1. 示例代码
#include <Arduino.h>
#include <U8x8lib.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#ifndef STASSID
#define STASSID "Rasp_1001"
#define STAPSK "rispy123"
#endif
#define LED_DATA 13
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // OLEDs without Reset of the Display
const char* ssid = STASSID;
const char* password = STAPSK;
const char* mqtt_server = "test.mosquitto.org";
const char* mqtt_topic_switch = "rockiot/mqtt@127.0.0.1/light/switch";
const char* mqtt_topic_status = "rockiot/mqtt@127.0.0.1/light/status";
String clientId = "ESP8266Client-" + String(random(0xffff), HEX);
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
int pin_status = LOW;
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(".");
}
randomSeed(micros());
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("] ");
// String topicString = "topic: " + String(topic);
// u8x8.println(topicString.c_str());
String content = "";
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
content = content + (char)payload[i];
}
String onString = "on";
u8x8.println(content.c_str());
u8x8.refreshDisplay();
Serial.println();
// Switch on the LED if an 1 was received as first character
if (onString.equals(content)) {
pin_status = HIGH;
} else {
pin_status = LOW;
}
digitalWrite(LED_DATA, pin_status);
}
boolean reconnect() {
Serial.print("Attempting MQTT connection...");
if (client.connect(clientId.c_str())) {
Serial.println("connected");
client.subscribe(mqtt_topic_switch);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
}
return client.connected();
}
void setup() {
u8x8.begin();
u8x8.setFont(u8x8_font_pxplustandynewtv_r);
pinMode(LED_DATA, OUTPUT);
digitalWrite(LED_DATA, pin_status);
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
long now = millis();
if (now - lastMsg > 5000) {
lastMsg = now;
++value;
if (reconnect()) {
lastMsg = 0;
}
}
} else {
client.loop();
}
long now = millis();
if (now - lastMsg > 5000) {
lastMsg = now;
client.publish(mqtt_topic_status, String(pin_status).c_str());
}
}
其中,将里面的Wifi接入点和密码(STASSID,STAPSK)改成自己的就可以了。
LED_DATA 是控制的引脚,GPIO13即D7,rockiot/mqtt@127.0.0.1/light/switch 与 rockiot/mqtt@127.0.0.1/light/status是自己定义的两个话题,如果读者要自己配置,请自行按需修改
"rockiot/mqtt@127.0.0.1/light/switch" : 此Topic是控制topic,发送on将D7置为高电平,其他的置为低电平。即如果发光二极管,分别接GND、和D7,即可实现开关。
"rockiot/mqtt@127.0.0.1/light/status" : 此Topic为NodeMCU每隔一段时间主动发送当前D7管脚的状态(高、低电平)。 代码中还有将接收到Topic的内容输出到屏幕上的功能,关于如何显示参照上一节即可。 接下来就是接线了。
2. 接线图
模拟接线图
3. 手机控制配置
想要手机控制,就需要安装支持mqtt订阅发布的客户端,我用的是『物联Flow』App,支持任务。
安装『物联Flow』后,创建若干任务,依次是开灯、关灯
配置如下图:
4. 实物图
图中的萝卜,请不要在意,只因找不到Resistor~~ 😄