Arduino+ESP8266+华为云物联网平台实现智能开关

news2024/11/15 3:53:27

在这里插入图片描述

前言

最近在做一个物联网项目,涉及到智能开关的开发。目前已经实现简单的TCP通信远程控制,但是考虑到后期的设备管理以及设备通信所需要的技术和服务器的维护成本,我决定将设备接入云平台。本文将详细阐述如何利用华为云的物联网平台(IoTDA)实现设备的云上管理与通信。

前提条件

  • 搭建Arduino+ESP8266的开发环境。可以参考: 软件开发人员从0到1实现物联网项目:初步实现智能开关
  • 开通华为云物联网平台服务,并注册一个设备。可以参考官网文档。

准备工作

设备侧选择用MQTT协议,因为对(IoTDA)SDK的编译环境不太了解,这里通过API的方式接入华为云的物联网平台。

获取IoTDA接入信息

首先需要拿到两个信息:

  1. 华为云物联网平台的接入信息,也就是URL和PORT。接入信息通过下图可以看到。

    华为云物联网平台接入信息

  2. 华为云物联网平台的设备连接鉴权信息。可以参考设备连接鉴权 。简单来讲,就是通过注册设备时的设备ID和密钥生成设备连接鉴权所需的参数(ClientId、Username、Password)。生成参数的链接

    ----图

安装代码库

其次,设备侧作为MQTT的客户端,需要编写相关代码。基于Arduino IDE开发,可以使用现成的库减少工作量。

  1. 安装PubSubClient库,用于连接和交互MQTT代理服务器(IoTDA)。
  2. 安装ArduinoJson库,用于解析和生成 JSON 数据。

功能实现

基于IoTDA平台实现智能开关,代码要实现以下功能:

  1. 设备进行WiFi连接与网络通信。
  2. 设备通过MQTT协议接入IoTDA平台。
  3. 设备接收IoTDA平台下发的消息。
  4. 设备根据消息执行相应的控制操作。

WiFi连接

#include <ESP8266WiFi.h>  

const char* ssid = "xxx";   //wifi名称
const char* password = "xxx";  //wifi密码

void setup_wifi() {  
  delay(10);  
  // We start by connecting to WiFi  
  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.print("IP address: ");  
  Serial.println(WiFi.localIP());  
}

对以上的代码进行解释:

ESP8266WiFi.h 库提供了与 WiFi 网络连接相关的功能,WiFi.begin(ssid, password); 这行代码就可以自动连接WiFi。

接入IoTDA

设备要接入IoTDA,就需要上面准备的接入信息。在代码中定义如下:

const char* mqttServer = "xxx.myhuaweicloud.com";  
const int mqttPort = 1883;  
const char* mqttClientId = "xxx";      
const char* mqttUser ="xxx";
const char* mqttPassword = "xxx";

#define deviceId "xxx"

#define mqttTopic "$oc/devices/" deviceId "/sys/messages/down"

mqttTopic是在接入成功后,设备侧订阅的Topic,用来接收平台下发的消息。更多的topic定义参考IoTDA平台预置的topic。

接下来就需要通过PubSubClient库进行接入IoTDA平台了

WiFiClient espClient;  
PubSubClient client(espClient);  

void reconnect() {    
  client.setServer(mqttServer, mqttPort);  
  client.setCallback(callback);  
  while (!client.connected()) {  
    Serial.println("Attempting MQTT connection...");  
    if (client.connect(mqttClientId, mqttUser, mqttPassword)) {  
      Serial.println("connected");  
      client.subscribe(mqttTopic);  
    } else {  
      Serial.print(client.state());
      delay(5000);  
    }  
  }  
}  

接收IoTDA消息&控制开关

client.connect 成功后会订阅Topic,当在IoTDA平台下发消息时,就会在 callback 函数进行 digitalWrite(RELAY_PIN, state); 控制开关了。

void callback(char* topic, byte* payload, unsigned int length) {  
  StaticJsonDocument<128> doc;  
  DeserializationError error = deserializeJson(doc, payload);  
  if (error) {  
    Serial.print(F("deserializeJson() failed: "));  
    Serial.println(error.c_str());  
    return;  
  }  
  
  const char* stateKey = "state";  
  if (doc.containsKey(stateKey)) {  
    bool state = doc[stateKey];  
    digitalWrite(RELAY_PIN, state);  
    Serial.print("Switch state: ");  
    Serial.println(state ? "ON" : "OFF");  
  }  
}  
  

完整代码


#include <ESP8266WiFi.h>  
#include <PubSubClient.h>  
#include <ArduinoJson.h>  
  
const char* ssid = "xxx";  
const char* password = "xxx.";  
const char* mqttServer = "xxx.myhuaweicloud.com";  
const int mqttPort = 1883;  
const char* mqttClientId = "xxx";      
const char* mqttUser ="xxx";
const char* mqttPassword = "xxx";

#define RELAY_PIN 0


#define deviceId "xxx"

#define mqttTopic "$oc/devices/" deviceId "/sys/messages/down"



WiFiClient espClient;  
PubSubClient client(espClient);  
  
void callback(char* topic, byte* payload, unsigned int length) {  
  StaticJsonDocument<128> doc;  
  DeserializationError error = deserializeJson(doc, payload);  
  if (error) {  
    Serial.print(F("deserializeJson() failed: "));  
    Serial.println(error.c_str());  
    return;  
  }  
  
  const char* stateKey = "state";  
  if (doc.containsKey(stateKey)) {  
    bool state = doc[stateKey];  
    digitalWrite(RELAY_PIN, state);  
    Serial.print("Switch state: ");  
    Serial.println(state ? "ON" : "OFF");  
  }  
}  
  
void reconnect() {  
  while (!client.connected()) {  
    Serial.println("Attempting MQTT connection...");  
    if (client.connect(mqttClientId, mqttUser, mqttPassword)) {  
      Serial.println("connected");  
      client.subscribe(mqttTopic);  
    } else {  
      Serial.print(client.state());
      delay(5000);  
    }  
  }  
}  
  
void setup_wifi() {  
  delay(10);  
  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.print("IP address: ");  
  Serial.println(WiFi.localIP());  
}  
  
void setup() {  
  Serial.begin(115200);  
  pinMode(RELAY_PIN, OUTPUT); 
  digitalWrite(RELAY_PIN, HIGH); 
  
  setup_wifi();  
  client.setServer(mqttServer, mqttPort);  
  client.setCallback(callback);  
}  
  
void loop() {  
  if (!client.connected()) {  
    reconnect();  
  }  
  client.loop();  
}

IoTDA平台下发消息

将编写完成的代码烧录到ESP-01S模块后,就可以通过IoTDA平台进行消息下发了。消息下发位置见下图

IoTDA平台

消息下发格式:

{
    "state":true
}

statetrue时,表示电平状态为HIGH,电路呈开启状态,此时电路不通电。
而当statefalse时,电平状态则为LOW,电路闭合,此时电路处于通电状态。

通过state数值的变化,从而达到远程控制开关。

问题记录

在串口调试时,如果mqtt连接返回-1状态码,意味着连接失败。

那么需要将 PubSubClient.h 库中的两个宏定义MQTT_KEEPALIVEMQTT_MAX_PACKET_SIZE 的数值调大。本文中的代码已分别调整为60和2048。

PubSubClient宏定义

总结

借助华为云的物联网平台IoTDA,可以帮助物联网行业的用户快速完成设备联网及行业应用集成,大大提高了开发人员的工作效率。而且按需计费每月前一百万条消息是免费的,很大程度上降低了设备上云的成本。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1545607.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统下安装部署Linux管理面板1panel

目录 一 1panel介绍 1、1Panel简介 2、1Panel特点 二、本地环境规划 1、本此实验目的 2、本地环境部署 三、部署1Panel&#xff08;在线安装&#xff09; 1.创建安装目录 2.一键部署1Panel 3.检查1Panel服务运行状态 4.检查1Panel监听端口 四、关闭防火墙和selinux…

小动物主动跑轮和被动跑轮的功能和目的?

小动物主动跑轮和被动跑轮在运动方式、实验目的和设计构造方面上是有区别的。 运动方式不同。主动跑轮是由动物自主运动来推动跑轮转动的。这种设置可以真实地反映动物自发的运动情况。相对地&#xff0c;被动跑轮则是一种强迫运动的方式&#xff0c;通常由电机带动跑轮转动从…

视频生成Sora的全面解析:从AI绘画、ViT到ViViT、TECO、DiT、VDT、NaViT等

前言 真没想到&#xff0c;距离视频生成上一轮的集中爆发(详见《Sora之前的视频生成发展史&#xff1a;从Gen2、Emu Video到PixelDance、SVD、Pika 1.0》)才过去三个月&#xff0c;没想OpenAI一出手&#xff0c;该领域又直接变天了 自打2.16日OpenAI发布sora以来(其开发团队包…

基于yolov8安全帽检测的系统

基于yolov8安全帽检测的系统 项目描述&#xff1a; 安全头盔检测&#xff08;计算机视觉&#xff09; 1.自训练数据集1538张数据图片&#xff0c;进行标注&#xff0c;并进行100轮的训练&#xff0c;准确率达0.966 2.使用 Flask 和 Ultralytics YOLOv8 模型开发了一个 Web 应…

Matlab有限差分法求解狄利克雷(Dirichlet)边界的泊松(Poisson)问题,边界值为任意值

参考l链接&#xff1a; 有限差分法简介有限差分法-二维泊松方程及其Matlab程序实现弹性力学方程 有限差分法matlab,泊松方程的有限差分法的MATLAB实现 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Matrix method for Poisson Equation …

景联文科技上新高质量大模型训练数据!

在过去的一年中&#xff0c;人工智能领域呈现出了风起云涌的态势&#xff0c;其中模型架构、训练数据、多模态技术、超长上下文处理以及智能体发展等方面均取得了突飞猛进的发展。 在3月24日举办的2024全球开发者先锋大会的大模型前沿论坛上&#xff0c;上海人工智能实验室的领…

[Linux]知识整理(持续更新)

前言 Linux的目录结构 Linux的目录结构是一个树型结构 Windows 系统可以拥有多个盘符, 如 C盘、D盘、E盘 Linux没有盘符这个概念, 只有一个根目录 /, 所有文件都在它下面 Linux路径的描述方式 第一章 基本命令 命令格式 例:ls –la /etc 说明: 1)个别命令使用不遵循…

照片尺寸怎么修改?高效快速处理方法

在分享照片到不同平台时&#xff0c;也需要符合不同尺寸要求&#xff0c;在不同场景中&#xff0c;应该如何修改图片尺寸呢&#xff1f;还有不同的证件类型有着不同的证件照尺寸要求&#xff0c;因此我们需要根据要求对证件照尺寸进行调整&#xff0c;接下来就介绍几个可以图片…

35.基于SpringBoot + Vue实现的前后端分离-在线考试系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统&#xff0c;采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的在线考试系统设计与实现管理工作系统…

Netty学习——源码篇6 Pipeline设计原理 备份

1 Pipeline设计原理 在Netty中每个Channel都有且仅有一个ChannelPipeline与之对应&#xff0c;它们的组成关系如下图&#xff1a; 通过上图可以看到&#xff0c;一个Channel包含了一个ChannelPipeline&#xff0c;而ChannelPipeline中又维护了一个由ChannelHandlerContext组成的…

HTTP工具类封装与http请求响应

一、前言 在Java web系统中经常需要与外部接口进行对接&#xff0c;比较多的方式就是是http的方式。在springboot中&#xff0c;我们可以直接使用封装的feign如&#xff1a;我们去请求微信的接口&#xff0c;定义一个client客户端&#xff0c;使用feign框架去请求就可以。但是…

全志A33编译踩坑!

领导给了个新sdk。然后开编。 编译的标准流程是这样 cd lichee ./build.sh config 这还得了&#xff0c;每次都选很烦&#xff08;虽然只需要选一次&#xff09;&#xff0c;于是新写法是这样 ./build.sh -p sun8iw5p1_android -k linux-3.4 -b evb 果断提示 ERROR: inv…

[深度学习]yolov8+streamlit搭建精美界面GUI网页设计源码实现三

【设计思路介绍】 为了使用YOLOv8和Streamlit搭建一个精美的界面GUI网页&#xff0c;你需要遵循几个关键步骤。以下是一个简化的流程&#xff0c;帮助你设计并实现这一目标&#xff1a; 1. 环境准备 安装YOLOv8 YOLOv8是一个先进的实时目标检测模型。你需要先下载并安装YOL…

Excel双击单元格后弹窗输入日期

Step1. 在VBE界面新建一个窗体(Userform1),在窗体的工具箱的空白处右键,选中添加附件,勾选Calendar control 8.0,即可完成日历的添加。 PS:遗憾的是, Office 64 位没有官方的日期选择器控件。唯一的解决方案是使用Excel 的第三方日历。 参考链接:How to insert calen…

2024最新最全Selenium自动化测试面试题!

1、什么是自动化测试、自动化测试的优势是什么&#xff1f; 通过工具或脚本代替手工测试执行过程的测试都叫自动化测试。 自动化测试的优势&#xff1a; 1、减少回归测试成本 2、减少兼容性测试成本 3、提高测试反馈速度 4、提高测试覆盖率 5、让测试工程师做更有意义的…

vue echarts 记录一个带tab切换的echarts页面 切换的时候如果有一个tab里的echarts没有数据 该如何清空echarts图的数据的问题

<template><div class"app-container"><el-form :model"queryParams" ref"queryForm" size"small" v-show"showSearch" label-width"85px"><el-form-item label"园所名称" prop&q…

Matlab从入门到精通课程

教程介绍 MATLAB是美国MathWorks公司出品的商业数学软件&#xff0c;用于数据分析、无线通信、深度学习、图像处理与计算机视觉、信号处理、量化金融与风险管理、机器人&#xff0c;控制系统等领域。 学习地址 链接&#xff1a;https://pan.baidu.com/s/1PxGarBwQusMzwPVqcE…

动态内存管理一一常见错误与习题练习

目录 前言 一、常见错误 1、对NULL指针的解引用操作 2、 对动态开辟空间的越界访问 3、对非动态开辟内存使用free释放 4、使用free释放一块动态开辟内存的一部分 5、对同一块动态内存多次释放 6、动态开辟内存忘记释放&#xff08;内存泄漏&#xff09; 二、习题练习…

一篇文章带你搞定接单的多种渠道,赶紧码住!!!

相信大家也看到了不少人通过网络接单实现年入30W&#xff0c;彻底财富自由&#xff01;咱看了&#xff0c;真的很难不心痒痒&#xff0c;想加入其中&#xff0c;大干一场&#xff01;毕竟搞钱嘛&#xff01;才是王道。但是呢&#xff0c;也有很多人心向往之&#xff0c;奈何不知…

STM32在使用CAN通信时需要注意哪些配置和设置?

STM32微控制器在使用CAN通信时&#xff0c;需要进行一系列的配置和设置以确保通信的可靠性和有效性。以下是一些关键的配置和设置注意事项&#xff1a; 1. 选择合适的CAN外设 STM32系列微控制器通常包含一个或多个CAN外设。首先需要确定使用哪个CAN外设&#xff0c;并了解其特…