ESP8266连接自建MQTT服务远程遥控空调

本文介绍了如何利用ESP8266和Arduino解码空调红外信号,将其与NodeMCU结合,同时通过uniapp在移动端编写程序,实现实时控制空调开关。教程涵盖了硬件连接、代码编写、MQTT通信以及移动端应用的开发全过程。
摘要由CSDN通过智能技术生成

1. 解码空调红外键值

1.1 安装 IRremoteESP8266 库
在这里插入图片描述
1.2 把ESP8266红外接收的实例,上传到NodeMCU中.
在这里插入图片描述
在这里插入图片描述

1.3 读取遥控器红外键值
把红外接收模块的信号线连接到GPIO14(Node MCU 对应D5引脚)
在这里插入图片描述
红外接收模块接线图,型号:VS/HX1838B
在这里插入图片描述
打开Arduino 调试串口监视器,选择波特率为115200
在这里插入图片描述
空调遥控器对准红外接收管,按下需要的按键,串口监视器会打印出对应的键值,复制到记事本留着后面步骤用。
在这里插入图片描述

2. Arduino程序的编写,并上传到NodeMCU中

代码参考 太极创客

// 引入对应的头文件
#include <ESP8266WiFi.h>          
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>  
#include <PubSubClient.h>
#include <Ticker.h> 
#include <IRremoteESP8266.h>
#include <IRsend.h>

// 声明对象
Ticker ticker;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

const char* mqttServer = "***.***.***.***";  //常量, mqtt服务器地址
int count;    // Ticker计数用的变量
String messageString = "off";  //发布消息的变量,默认是关闭状态

//定义红外发射的管脚
const uint16_t kIrLed = 5;  // ESP8266 GPIO pin to use. Recommended: 5 (D1).
IRsend irsend(kIrLed);  // Set the GPIO to be used to sending the message.

//空调开,根据遥控器解码后的数据修改 [] 和 {} 里面的数值
uint16_t power_on[227] = {3080, 1608,  472, 1108,  472, 1110,  472, 318,  498, 318,  498, 318,  498, 1108,  472, 320,  496, 318,  498, 1108,  472, 1108,  472, 316,  500, 1108,  472, 322,  494, 320,  496, 1108,  472, 1108,  472, 316,  500, 1108,  472, 1108,  472, 316,  522, 286,  506, 1108,  494, 282,  510, 318,  498, 1108,  496, 284,  508, 316,  524, 280,  514, 316,  522, 280,  536, 278,  512, 318,  498, 318,  518, 280,  536, 280,  534, 282,  526, 302,  522, 282,  534, 280,  534, 282,  512, 316,  522, 280,  536, 1062,  518, 282,  510, 316,  500, 1084,  496, 316,  498, 318,  510, 1072,  498, 1082,  520, 282,  538, 274,  542, 274,  542, 276,  540, 274,  542, 274,  542, 1056,  524, 274,  540, 1056,  524, 276,  540, 276,  540, 276,  542, 274,  540, 276,  542, 274,  542, 1056,  522, 274,  542, 274,  542, 274,  540, 276,  540, 276,  540, 276,  540, 276,  540, 274,  540, 276,  540, 276,  540, 276,  540, 274,  542, 274,  540, 276,  540, 274,  542, 274,  542, 274,  542, 274,  542, 274,  542, 274,  540, 276,  538, 280,  512, 316,  498, 318,  498, 316,  500, 316,  524, 280,  534, 282,  510, 318,  498, 316,  498, 318,  498, 318,  498, 318,  496, 318,  496, 320,  496, 320,  494, 320,  496, 1086,  492, 1088,  492, 1088,  492, 324,  492, 324,  492, 324,  492, 326,  490, 1110,  468, 1112,  468};  // TCL112AC
//空调关
uint16_t power_off[227] = {3078, 1610,  470, 1110,  470, 1112,  468, 346,  468, 348,  466, 350,  466, 1110,  470, 348,  470, 346,  468, 1112,  468, 1090,  492, 346,  468, 1112,  468, 348,  466, 348,  468, 1114,  468, 1112,  470, 324,  492, 1088,  492, 1088,  492, 320,  496, 322,  494, 1084,  496, 318,  498, 316,  502, 1080,  500, 314,  502, 314,  526, 272,  544, 272,  542, 274,  542, 274,  542, 274,  540, 274,  542, 274,  540, 276,  542, 274,  540, 274,  540, 276,  540, 274,  540, 274,  542, 274,  542, 274,  542, 274,  540, 276,  540, 274,  540, 1056,  498, 316,  500, 316,  498, 1084,  496, 1082,  500, 314,  524, 278,  538, 278,  512, 316,  498, 318,  498, 318,  498, 1084,  496, 318,  498, 1084,  496, 318,  496, 320,  496, 320,  496, 322,  496, 320,  494, 320,  494, 1086,  492, 322,  492, 324,  492, 346,  470, 346,  470, 346,  468, 348,  468, 348,  468, 348,  466, 350,  466, 350,  466, 350,  466, 350,  464, 352,  464, 352,  462, 354,  460, 356,  460, 356,  460, 356,  460, 356,  458, 356,  458, 358,  458, 358,  458, 356,  458, 358,  458, 356,  458, 358,  458, 356,  460, 356,  458, 358,  458, 356,  460, 356,  458, 356,  458, 358,  458, 356,  458, 358,  458, 358,  458, 358,  458, 1122,  456, 1124,  456, 1146,  436, 1144,  434, 1146,  434, 1146,  434, 1146,  434, 382,  434, 1146,  434};  // TCL112AC


//计数
void tickerCount(){
  count++;
}

// 连接MQTT服务器
void connectMQTTServer(){
    // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
    String clientId = "esp8266-" + WiFi.macAddress(); 
    
    if (mqttClient.connect(clientId.c_str())) { 
      Serial.println("MQTT Server Connected.");
      Serial.println("Server Address: ");
      Serial.println(mqttServer);
      Serial.println("ClientId:");
      Serial.println(clientId);
      subscribeTopic(); // ****订阅指定主题****
    } else {
      Serial.print("MQTT Server Connect Failed. Client State:");
      Serial.println(mqttClient.state());
      delay(3000);
    }   
}
 
// 发布信息
void pubMQTTmsg(){   
    // 建立发布主题
    String topicString = "test/esp8266/pub" ;
    char publishTopic[topicString.length() + 1];  
    strcpy(publishTopic, topicString.c_str());
   
    // 建立发布信息,当前D1引脚状态
//    String messageString;
//    if(digitalRead(D1)){
//      messageString = "off"; 
//    } else {
//      messageString = "on"; 
//    }

    // 建立发布信息:设备的状态    
    char publishMsg[messageString.length() + 1];   
    strcpy(publishMsg, messageString.c_str());
    
    // 实现ESP8266向主题发布信息,并在串口监视器显示出来
    if(mqttClient.publish(publishTopic, publishMsg)){
      Serial.println("Publish Topic:");
      Serial.println(publishTopic);
      Serial.println("Publish message:");
      Serial.println(publishMsg);    
    } else {
      Serial.println("Message Publish Failed."); 
    }
}


// 订阅指定主题
void subscribeTopic(){ 
    // 建立订阅主题
    String topicString = "test/esp8266/sub" ;
    char subTopic[topicString.length() + 1];  
    strcpy(subTopic, topicString.c_str());
    
    // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
    if(mqttClient.subscribe(subTopic)){
      Serial.println("Subscribe Topic:");
      Serial.println(subTopic);
    } else {
      Serial.print("Subscribe Fail...");
    }  
}
 
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Message Received [");
    Serial.print(topic);
    Serial.print("] ");
    for (int i = 0; i < length; i++) {
      Serial.print((char)payload[i]);
    }
    Serial.println("");
    Serial.print("Message Length(Bytes) ");
    Serial.println(length);
   
    if ((char)payload[0] == '1') {     // 如果收到的信息以“1”为开始
      //digitalWrite(LED_BUILTIN, LOW);  // 点亮LED。      
      irsend.sendRaw(power_on, 279, 38);  //发送红外指令-开机 (表示发送power_off数组, 数组长度为279, 38kHz的频率)
      messageString = "on";  //更新设备状态
      pubMQTTmsg(); //调用函数发布消息
    } else {                           
      //digitalWrite(LED_BUILTIN, HIGH); // 熄灭LED。      
      irsend.sendRaw(power_off, 279, 38);  //发送红外指令-关机
      messageString = "off";  //更新设备状态
      pubMQTTmsg(); //调用函数发布消息
    }
}


//程序入口 
void setup() {
   //开启串口通讯
    Serial.begin(9600);
           
    // 建立WiFiManager对象
    WiFiManager wifiManager;

    //设置输出信号的引脚,此处是板载的LED
    //pinMode(LED_BUILTIN, OUTPUT);
    
    //红外初始化
    irsend.begin();

    // 如果您希望该WiFi添加密码,可以使用以下语句,第二个参数是密码
    // wifiManager.autoConnect("AutoConnectAP", "12345678");
    // 自动连接WiFi。以下语句的参数是连接ESP8266时的WiFi名称
    wifiManager.autoConnect("AutoConnectAP");     
    
    // WiFi连接成功后将通过串口监视器输出连接成功信息 
    Serial.println(""); 
    Serial.print("ESP8266 Connected to ");
    Serial.println(WiFi.SSID());              // WiFi名称
    Serial.print("IP address:\t");
    Serial.println(WiFi.localIP());           // IP

    // 设置MQTT服务器和端口号 
    mqttClient.setServer(mqttServer, 1883); 
    
    // 收到信息后的回调函数
    mqttClient.setCallback(receiveCallback);
    
    // 连接MQTT服务器
    connectMQTTServer(); 
    
    // Ticker定时对象
    ticker.attach(1, tickerCount);  
}

//循环执行 
void loop() {
    if (mqttClient.connected()) { // 如果开发板成功连接服务器
      // 每隔10秒钟发布一次信息
      if (count >= 10){
        pubMQTTmsg();
        count = 0;
      }    
      // 保持心跳
      mqttClient.loop();
    } else {                  // 如果开发板未能成功连接服务器
      connectMQTTServer();    // 则尝试连接服务器
    }  
}

硬件接线图
带放大电路的接线图,遥控距离5米左右。
型号:5mm白色发射二极管 ,2N2222三极管。
在这里插入图片描述
在这里插入图片描述

3. 使用uniapp 编写移动端程序

<template>
	<view class="content">
		<!-- <image class="logo" src="/static/logo.png" ></image> -->
		<image class="logo" :src="state=='on' ? imgurlon : imgurloff"></image>
		<view class="text-area">
			<view class="title">{{title}}</view>
		</view>
		<view class="btn">
			<button type="default" @click="btnon()"></button>
			<button type="default" @click="btnoff()"></button>
		</view>

	</view>
</template>

<script>
	var mqtt = require('../../mqtt.min.js')  //引入mqtt库
	var ntime = 0  //计时初始值

	export default {
		data() {
			return {
				title: '设备离线',						
				state:'off',  //改变图标状态
				imgurloff:'/static/off.png',
				imgurlon:'/static/on.png',
				timer: null,
				
				//app端和小程序端必须用【 wx:// 或者 wxs:// 】
				urls: 'wx://43.***.***.46:3000/mqtt',
				client: null,
				//MQTT连接的配置
				options: {
					clientId: '',
					clean: false,
					password: 'admin',
					username: 'public',
					keepalive: 0, //心跳时间
				}
			}
		},
		
		onLoad() {			
			// 多设备登录的时候 clientId 不能重复,否则消息订阅会有冲突,此处以时间戳作为clientId
			this.options.clientId = 'App' + Math.round(new Date() / 1000)
			
			//延迟一秒再调用方法,作用是等待赋值给clientId 			 
			setTimeout( ()=> {				
				this.mqttconnect()
			},1000)			
         
		},
		
		onShow() {
			// esp8266每10秒发布一次消息,num清零一次,如果30秒后变量num还没有清零,判断设备离线了			
			//建立定时器10秒运行一次
			this.timer = setInterval( () => {				
				ntime = ntime + 10
				if(ntime >= 30 ){
					this.title = '设备离线 XXX'
					this.state = 'off'
				}				
			}, 10000)	
		},
		
		onHide() {
			// 清除定时器			
			if(this.timer) {  
				clearInterval(this.timer);  
				this.timer = null;  
			} 
		},
		
		methods: {
			mqttconnect() {
				this.client = mqtt.connect(this.urls,this.options)
				
				//连接服务器
				this.client.on('connect', () => {
					// 订阅默认主题
					this.client.subscribe('test/esp8266/pub', (err) => {
						console.log(err || '订阅默认主题成功')
					})
					//发布消息  
					// this.client.publish('test/esp8266/pub', 'testmsg', (err) => {
					// 	console.log(err || '发送信息成功')
					// })
				})
				
				//收取消息
				this.client.on('message', (topic, message) => {
					let msg = message.toString()
					this.title = '设备在线'					
					this.state = msg
					console.log('收到来自'+ topic + '的消息:' + message.toString())
					ntime = 0
				})	
			},

			btnon() {
				//发布开灯指令
				this.client.publish('test/esp8266/sub', '1', (err) => {
					console.log(err || '发送信息成功')
				})				
				this.state = 'on'
			},

			btnoff() {
				//发布关灯指令
				this.client.publish('test/esp8266/sub', '0', (err) => {
					console.log(err || '发送信息成功')
				})				
				this.state = 'off'
			}

		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
	.btn{
		display: flex;
		flex-direction: row;
		margin: 20rpx;
	}
	button{
		margin: 20rpx;
		border-radius: 5rpx;
		color: #0055ff;
		background-color: #909090;
	}
</style>

运行效果图
在这里插入图片描述

4. MQTT服务器搭建

请看另一篇文章:nodejs + uniapp 联合开发MQTT服务端与移动端app

  • 3
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要将ESP8266连接到阿里云的MQTT,你可以按照以下步骤进行操作: 1. 首先,确保你已经在ESP8266上安装了Arduino IDE,并且在库管理器中安装了PubSubClient库。你可以使用以下命令在终端中克隆PubSubClient库:git clone https://github.com/knolleary/pubsubclient.git 2. 在Arduino IDE中打一个新的Sketch,并在代码中引入必要的库:#include <ESP8266WiFi.h>和#include <PubSubClient.h> 3. 设置你的Wi-Fi连接信息,包括SSID和密码: const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; 4. 设置阿里云MQTT服务器的信息: const char* mqttServer = "your_MQTT_SERVER"; const int mqttPort = 1883; const char* mqttUsername = "your_MQTT_USERNAME"; const char* mqttPassword = "your_MQTT_PASSWORD"; 5. 在setup函数中,连接到Wi-Fi网络: WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi!"); 6. 在setup函数中,设置MQTT客户端: WiFiClient espClient; PubSubClient client(espClient); client.setServer(mqttServer, mqttPort); client.setCallback(callback); // 设置回调函数,处理从阿里云收到的消息 7. 在loop函数中,连接MQTT服务器并处理消息: if (!client.connected()) { reconnect(); } client.loop(); 8. 创建一个回调函数callback,用于处理从阿里云收到的消息: void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived in topic: "); Serial.println(topic); Serial.print("Message:"); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); } 9. 创建一个重新连接函数reconnect,用于在连接时重新连接MQTT服务器: void reconnect() { while (!client.connected()) { Serial.print("Connecting to MQTT..."); if (client.connect("ESP8266Client", mqttUsername, mqttPassword)) { Serial.println("Connected to MQTT!"); client.subscribe("your_TOPIC"); // 订阅你感兴趣的主题 } else { Serial.print("Failed, rc="); Serial.print(client.state()); Serial.println("Retrying in 5 seconds..."); delay(5000); } } } 10. 编译并上传代码到ESP8266上进行测试。在串口监视器中,你将看到ESP8266连接到Wi-Fi并成功连接到阿里云的MQTT服务器。你也可以通过在回调函数中打印消息来验证是否成功接收到从阿里云发送过来的消息。 以上是将ESP8266连接到阿里云MQTT的简要步骤。通过这些步骤,你可以将串口接收到的数据上传到云服务器,并将从云服务器发送过来的数据输出到串口。希望能对你有所帮助!<span class="em">1</span><span class="em">2</span>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值