HOME
BLOG
TAGS
Internet of Things
Aug 01 2023

       大二下期末考试前几天水的两个小比赛都用到了物联网,所以简单学了些相关的东西。



物联网协议

       目前物联网平台还是挺多的,OneNet、阿里云物联网平台等等。物联网设备最重要的就是联网通讯了,上报设备的状态或者信息,接收指令等等。物联网的通讯协议常见的有下面七种:MQTT、 DDS、 AMQP、XMPP、 JMS、 REST、 CoAP。

  • MQTT协议(低带宽)一般适用于设备数据采集从端到服务器的集中星型网络架构
  • DDS协议(高可靠性与实时)广泛应用于国防、民航、工业控制等领域
  • AMQP协议(互操作性)主要适用于移动手持设备与后台数据中心的通信和分析
  • XMPP协议(即时通信)在互联网及时通讯应用中运用广泛
  • REST/HTTP(松耦合服务调用),客户端和服务器之间交互松耦合,适合在物联网的应用层面
  • CoAP (受限应用协议)适用于在资源受限的通信的IP网络
  • JMS (JAVA消息服务)用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信

       MQTT因为其低带宽的优点,现在大部分嵌入式物联网设备都是采用的这种协议。



物联网平台

OneNet/阿里云物联网平台

       这些商用的物联网都有教程和SDK文档,读一读就差不多能上手。我刚开始用的时候主要是被一些概念糊住了。

  • 设备:具体设备,可以通过该设备唯一的DeviceNameDeviceSecret和产品ProductKey等连接云服务器。
  • 产品:产品是一些设备的合集,这些设备有相同的ProductKey
  • 实例:物联网平台提供的产品、设备、规则等资源管理功能。企业版(氪金)比公用(免费)实例的高级功能更多,同时在线设备数和上下行带宽更高。
  • Topic:话题,设备可以发布一个话题,向其上传数据,再由设备订阅该话题获取数据。类似于ROS。
  • 物理型:对设备在云端的功能描述,包括设备的属性、服务和事件。物联网平台通过定义一种物的描述语言来描述物模型,称之为TSL(即 Thing Specification Language),采用JSON格式,可以根据TSL组装上报设备的数据。
  • 属性:设备的功能模型之一,一般用于描述设备运行时的状态,如环境监测设备所读取的当前环境温度等。属性支持GET和SET请求方式。应用系统可发起对属性的读取和设置请求。
  • 服务:设备的功能模型之一,设备可被外部调用的能力或方法,可设置输入参数和输出参数。相比于属性,服务可通过一条指令实现更复杂的业务逻辑,如执行某项特定的任务。
  • 事件:设备的功能模型之一,设备运行时的事件。事件一般包含需要被外部感知和处理的通知信息,可包含多个输出参数。例如,某项任务完成的信息,或者设备发生故障或告警时的温度等,事件可以被订阅和推送。
  • 数据流转:物联网平台消息转发的数据流转功能,可将Topic中的数据转发至其他Topic或其他阿里云服务进行存储或处理。

       例如,新建一个产品监测系统,在其功能定义中创建温度(物理型中的属性),再创建两个设备传感器节点监测软件,前者的实质是一个ESP32和一个温度传感器,后者的实质是电脑上的一个程序。那么就可以实现如下流程(大致是这样):ESP32读取传感器采集的温度数据,连接WiFi并通过阿里云API和传感器节点的信息连接云服务器,将温度上传至云端该设备的物理型话题,通过数据流转设定规则把数据转发到监测软件设备的物理型话题,软件通过API和其设备信息连上阿里云服务器并订阅自身物理型话题就可以获取温度数据。当然这只是一个基本流程,更多操作官方文档都有写。

EMQX平台

       EMQX (Erlang MQTT Broker) 是基于 Erlang/OTP 平台开发的开源物联网 MQTT 消息服务器。Erlang/OTP是出色的软实时 (Soft-Realtime)、低延时 (Low-Latency)、分布式 (Distributed)的语言平台。软件支持多种操作系统,有图形化界面,直接EMQX官网下载使用,用法类似于上面的OneNet/阿里云平台,只是服务器用的是自己设备。

自建平台

       自己搭建物联网服务器的话,除了自己电脑,还可以用一些“派”甚至旧笔记本或小主机的主板,这样就可以放那全天运行。

       左边Z83504+64G才360元,右边树莓派4b8G学长友情价980给我(当时淘宝炒到1500😭),还有个4G版本我740元卖出去的(现在降到四百多了)。
       说回搭服务器,最简单的方法就是Flask。搭好Python环境然后:

    pip install flask-mqtt

       接下来就直接写你自己的服务器了,Flask-Mqtt有官方文档方便使用。



设备实例

MQTT.fx

       MQTT.fx是一款基于Eclipse Paho,使用Java语言编写的MQTT客户端工具。支持通过Topic订阅和发布消息,用来前期和物理云平台调试非常方便。官网下载安装后就可以开始用了。打开软件界面如下:

       设置配置文件的界面:

       上手很简单就不细说了。

ESP32(Arduino IDE)

       记得刚开始用ESP32时没啥资料磕磕碰碰的,当时也是用Arduino IDE,没多少代码就实现了摄像头采集视频流并搭建服务器网页查看,给了写STM32代码到自闭的我一点小小的开源生态震撼。现在ESP32也算是国产网红芯片了,各种资料教程一大堆,想拿来干啥都有例程可以套。
       用Arduino IDE编写ESP32的mqtt代码的话我推荐用阿里云物联网服务器,因为有佬封装了aliyun_mqtt并在ESP8266测试,在Arduino管理库能直接下载AliyunIoTSDK使用。代码量非常小:

/*
 * Includes
 */
#include <WiFi.h>
#include <AliyunIoTSDK.h>

/*
 * User Definition
 */
// WIFI
#define WIFI_SSID     "Your_WiFi_ID"
#define WIFI_PASSWD   "Your_WiFi_Password"
static WiFiClient espClient;

// Aliyun-IoT
#define PRODUCT_KEY   "xxxxx"
#define DEVICE_NAME   "NodeX"
#define DEVICE_SECRET "xxxxx"
#define REGION_ID     "cn-shanghai"

void setup()
{
    // Setup
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASSWD);
    while (!WiFi.isConnected())
    {
        WiFi.begin(WIFI_SSID, WIFI_PASSWD);
    }
    AliyunIoTSDK::begin(espClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, REGION_ID);
}

void loop()
{
    // Check WiFi
    while (!WiFi.isConnected())
    {
        WiFi.begin(WIFI_SSID, WIFI_PASSWD);
    }
    
    // 甚至不需要topic设置就能发消息,只需要物理型标识符对应就彳亍。
    AliyunIoTSDK::send((char*)"illuminationstdX",temp.gy3Values.std_illumination);
    
    AliyunIoTSDK::loop();
}


Python API

       Python可以用的库就更多了,paho-mqttaliyunlinkit等等例程都很多。例如paho代码:

# Imports

## std
import json
import queue
## 3p
import paho.mqtt.client as mqtt


# MQTT Settings
PORT=1883
HOST=r"iot-xxxxxxxxxxxx.mqtt.iothub.aliyuncs.com"
DEV_ID = r"xxxxxxxxxx.Desktop|securemode=2,signmethod=hmacsha256,timestamp=xxxxxxxxxxx|" 
PRO_ID = r"xxxxxxxxxx" 
AUTH_INFO = r"xxxxxxxxxxxxxxxxxxxxx"
TOPIC = r"/sys/xxxxxxxxxx/xxxxxxxxx/thing/service/property/set"


# MQTT Functions

## The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.subscribe(TOPIC)

## The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    #print(msg.topic)
    str = json.loads(msg.payload)
    #print(str)
    q_ali.put(str)


# Main Function

if __name__ == '__main__':

    ## message
    q_ali = queue.Queue()

    ## Client Initialization
    client = mqtt.Client(DEV_ID)
    
    client.on_connect = on_connect
    client.on_message = on_message
    
    client.username_pw_set(PRO_ID,AUTH_INFO)
    client.connect(HOST, PORT, 90)
    client.loop_start()

    ## Loop
    while True:
        pass



总结

       以上的物联网相关内容其实CSDN等网站上教程很多,但是过于细碎,我打通物联网通信的过程很不顺,所以就写了些方便以后找文档和快速回忆上手。