Paho MQTT 客户端接入阿里云物联网平台(4)| 学习笔记

简介: 快速学习 Paho MQTT 客户端接入阿里云物联网平台(4)

开发者学堂课程【基于STM32的端到端物联网全栈开发Paho MQTT 客户端接入阿里云物联网平台(4)】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/574/detail/7940


Paho MQTT 客户端接入阿里云物联网平台(4)


Paho MQTT 客户端接入阿里云物联网平台示例操作

项目例程软件架构:
应用程序:

1.节点端业务程序

2.阿里云 MQTT 连接适配层

中间件:

1.Paho MQTT embedded C

2.mbedTLSHMAC-SHA1

3.网络接口抽象

底层驱动:

1.STM32L4 Cube HAL 硬件抽象层

2.传感器驱动

3.WIFI 模块驱动

image.png

//例程软件中的 Paho MQTT 协议栈向下通过 ST 提供的网络接口抽象层,来调用底层的 wifi 驱动实现网络数据的通信,向上提供 MQTT API 函数给阿里云 MQTT 连接适配层来完成应用程序的功能

//在接下来的课程中将分别介绍代码中实现网络通信的分层结构,发送和接收数据流的传递过程以及 Paho 向下和网络接口的适配以及向上和阿里云 MQTT 连接适配层的实现

各个软件层中主要对应的c文件以及他们之间的调用关系

---------------1.net_wifi 适配  Wifi 驱动

2.net_c2c 适配 C2c 驱动

3.net_eth 适配 Eth 驱动

image.png

//上边的文件通过下边的软件层通过颜色进行了对应

//节点中的业务程序主要在 main.c 业务中实现

//阿里云 MQTT 连接适配层包括 Ali_iotclient.c 文件和 Ali_iot_network_wrapper.c 文件

//Ali_iotclient.c 文件实现了阿里客户端的功能,包括构建 MQTT 连接的参数,与 MQTT 服务器建立连接,订阅发布消息等函数

//Ali_iot_network_wrapper.c 文件中实现了 MQTT 通信网络接口的封装

//MQTTClient.c Paho 协议栈的文件,它提供了众多 API 给上方的 Ali_iotclient.c 中的函数调用

//net.c 是 ST 的网络接口抽象层的文件,MQTTClient.c 通过 Ali_iot_network_wrapper.c 中封装的网络接口函数向下调用 net.c 中对应的函数,再向下调用 wifi 驱动。在本次例程中只使用到了 wifi 驱动,这个软件结构的好处,是可以很方便的移植到比如2G/3G以及以太网这些网络连接方式去,只需要将 net.c 文件部分下的.c 文件进行替换就能完成,上方的文件代码均不会受到影响。

后端配置代码:    

//AliIoT 路径下有三个适配文件:

Ali_iotclient.c

Ali_iot_network_wrapper.cmqtt_msg_handler.c 文件

// Ali_iot_network_wrapper.c 下封装了5个函数,分别是与服务器创建 tcp 连接,与服务器断开 tcp 连接以及向下对网络接口发送和接收数据的两个函数

//mqtt network 这个函数是在向 mqtt 协议栈新建一个网络接口,并且注册相关的数据收发的函数

// Ali_iotclient.c 文件中主要实现阿里客户端的一些功能,比如如何根据三元组信息来构建 mqtt 服务器的地址,如何得到 mqtt 的主题,如何得到 mqtt 连接的用户名,和 mqtt 连接的密码,还有与 mqtt 服务器创建连接向服务器发送消息和订阅主题的函数

//mqtt 连接创建的过程:

main 函数中,前面的初始化操作和 wifi 都已经连接之后,就会开始与阿里云 iot 平台创建 mqtt 的连接,在 main函数中会调用 connect2Aliiothub 函数,此函数是在 Ali_iotclient.c 文件中实现的,此函数首先会根据三元组的信息来构建 mqtt 服务器的地址。得到服务器的地址后先调用 mqtt_connect_network 函数来与服务器建立 tcp 的连接,此函数是在 Ali_iot_network_wrapper.c 文件中实现的。在 mqtt_connect_network 函数中会调用 net.c 文件中所提供的向上的统一的网络接口函数来实现对网络的一些操作,

首先它会先调用 net_sock_create 来创建一个 socket,在此函数中,他会根据你所使用的不同网络接口来调用对应不同的函数来创建一个 socketsocket 创建成功后,它会将对应的 socket 的操作的函数注册到 sock 结构体中。上层的应用程序来通过 sock 这个结构体来做对应的操作时,实际调用的就是它已经注册的函数。

比如要通过 sock 来进行发送数据,接收输入,那么它调用的就是 net_sock_send_tcp_wifi net_sock_sen_recv_wifi 两个函数,这些函数的实现是在 net.tcp.wifi.c 文件中。mqtt_connect_network 函数首先会创建一个 sock,然后在创建 sock 的过程中,已经注册好一系列对 socket 操作的函数,接收数据,发送数据,断开连接等函数都已经注册成功,然后在对 socket 进行一些配置,最后通过 socket 与服务器建立 tcp 的连接。

#include "main.h"

#include "Ali_iot_network_wrapper.h"

int mqtt_connect_network(letwork* n, const char * host_addressint port)

{

int mqtt_socket_send(Network *network,unsigmed char *bufint len,int timeout){

{

int mqtt_socket_recv(Network *network,unsigmed char *bufint len,int timeout)

{

int mqtt_socket_disconnect(Network *network)

{

//@sz, nev a MQTT netvork interface vith WIFI module

//must called before baidu_connect_netvork_tls/baidu_connect_network

int mqtt_network _new (Network *network)

{

network->my socket = 0;

network->mqttread = mqtt_socket_recv;

network->mqttwrite = mqtt_socket_send;

network->disconnect = mqtt_socket_disconnect;

return SUCCESS;

}

如何构建服务器地址:
extern int PrepareMqttPayload (char * PayloadBuffer,int PayloadSize) ;

extern void Parameters_message_handler(MessageData * data) ;

extern void Service_message_handler(MessageData * data) ;

void calpassword(void) ;

int get_mgtt_server_addr(char* host_addrchar* region_id,char* product_key )

{

//$( YourProductKey}.iot-as-mqtt.$ { YourRegionId}.aliyuncs.com:1883

uint32_t return_len=0;

return_len = snprintf(host_addr,NQTT_CLIENT_INFO_S12E,"4s.iot-a38-mgtt.i8.aliyuncs.com" ,product_key ,regic

n_id) ;

if (return_len >= MQTT_CLIENT_INFO_SIZE)

{

mag_info ("no enough space for host address\n") ;

return -1;

}

msg_info ("MQIT server address is :is\n",host_addr);

return 0;

}

int build_mgtt_topic(void)

{                              

MQTT连接过程:

//WIFI SSID/passov rd config and initializationl

// and config device certificate

ret = initPlatform() ;

if (ret! =0)

{

mag_info ("wifi initial failed! \n");

while(1) ;

// connect to Ali Iot platformret = connect2Aliiothub () :;

if (ret!=0)l

mag_info ("MQIT connection failed! \n");

while(1) ;

}

// subscribe to topicsdeviceSubscribe () ;

/ *USER CODE END 2* /

/*Infinite loop * /

/* USER CODE BEGIN WHILE*/while (1)

{

//MQTT reconnection check

if (rebuildMQTTConnection ( )==0){

doMqttYield( );

/*USER CODE END WHILE*/

int net_sock_create_tcp_wifi(net_hnd_t nethndnet_ockhnd_t * sockhndnet_proto_t proto)

int rc = NET_ERR;

net_ctxt_t *ctxt = (net_ctxt_t *) nethnd;

net_sock_ctxt_t *sock = NULL;

sock = net_malloc (sizeof (net_sock_ctxt_t) );

if (sock == NULL)

mag_error ("net_sock_create allocation failed.in");

rc = NET_ERR;

else

memset (sock, 0, sizeof (net_sock _ctxt_t));sock->net = ctxt;

sock->next = ctxt->sock_list;

sock->methods.create = (net_sock_create_tcp_wifi) ;

sock->methods.open= (net_sock_open_tcp_wifi);

sock->methodg.recv= (net_sock_recv_tcp_wifi);

sock->methoda.send= (net_sock_send_tcp_wifi);

sock->methods.close= (net_sock_close_tcp_wifi) ;

sock->methods.destroy=(net_sock_destroy_tcp_wifi) ;

sock->proto= proto;

sock->blocking= NET_DEFAULT_BLOCKING;

sock->read_timeout= NET_DEFAULT_BLOCKING_READ_TIMEOUT;sock->write_timeout= NET_DEEAULT_BLOCKING_WRITE_TIMEOUT;

ctxt->sock_list= sock; /* Insert at the head of the list */

*sockhnd = (net_sockhnd_t) sock;

rc = NET_OK;

}

return rc;      

网络分层及数据流:

代码中实现网络通信的分层结构,发送和接收数据流的传送过程

//这里所说的网络分层并不是指 tcp 的网络分层,而是指代码中实现网络接口调用程序的时候通过网络接口抽象层,也就是下图中的蓝色部分,将底层实际的网络接口,绿色的 WIFI 驱动部分,与上层的应用程序,黄色的部分独立开,尽量保证底层网络接口的变化不会对上层应用程序产生影响。WIFI 模块驱动也分为了三层,在 emw3080_io.c 文件中是最低层跟外设打交道的部分,包括初始化引脚,从窗口读取和发送数据。

emw3080.c 文件中是对 at 指令的实现。wifi.c wifi 底层驱动和 wifi 网络层面抽象层的接口。从 tcp ip 网络分层的角度,在本例程中的代码仅仅实现了应用层的 mqtt 协议,传输层和网络层都是在 wifi 模块中实现的,从串口传给wifi 模块以及从 wifi 模块接收的都是已经封装完毕的 mqtt 数据包。传输层 tcp 和网络层封装都是由 wifi 模块完成的。

//图中的箭头是接收和发送数据传递的过程

//绿色箭头指发送和接收网络数据,例如发送温湿度信息,接收云端下发的温度阈值。紫色的箭头是 mcu 控制 wifi 模块的 at 指令以及返回值,比如连接 wifi 热点,查询固件版本等等。对于这类指令,只需要将执行的结果返回到上层的应用程序不需要将收到的具体数据向应用层传递。

//图中粉色的变量是数据在传递过程中保存的位置

//应用数据的发送的过程:比如程序要将检测到的温湿度的值从 wifi 发送到云端,应用程序首先会调用 Paho mqtt publish 函数来发送温湿度信息,在 Paho 协议栈中它会将数据封装成数据包的格式并拷贝到 mqtt_write_buf 中,然后通过 mqtt_socket_send 函数向网络接口发送。

通过网络抽象层的函数 net_sock_send net_sock_send_tcp_wifi 来调用 wifi 模块的驱动最后通过EMW3080_IO_Send 函数发送到串口,通过串口发送到 wifi 模块。

//对于云端下发的数据:wifi 模块通过串口将包含温湿度阈值 mqtt 数据包发送,数据首先会保存到 Uart Ring Buffer中,Paho 协议栈中会通过 mqtt 的函数不断的查询是否有新的数据收到,mqtt yarn 的函数会调用 mqtt_socket_recv再通过网络抽象层的函数来调用 WIFI 模块的驱动函数,查询对应的 Socket Buffer 中是否有未读出的数据,如果有就将数据拷贝到 MQTT_read.buf 中,如果则会通过 pullSocktData 函数将串口中 Ring Buffer 新的数据读取到 Socket Buffer 中再拷贝到 MQTT_read_bufMQTT_read_buf 中的数据在 Paho 协议栈中进行分析,再将真正的负载数据,就是温度阈值取出并提供给上层应用程序。

//除了应用数据流的接收,还有连接wifi热点,查询固件版本的 ak 指令的发送和返回值的接收,这部分数据的传递主要在 WIFI 模块驱动这层完成,就是紫色箭头指示的部分,这部分 ak 指令的发送主要在 net_if_int 函数中触发,程序初始化 wifi 模块时调用了 net_interface_ination,然后再此函数中完成 wifi 模块的初始化,wifi 固件版本的查询,以及 wifi 热点连接的工作。

以连接 wifi 热点为例,分析紫色部分传递数据的操作:

连接 wifi 热点是通过调用 WIFI_Connect 函数完成,在这个函数中会调用 emw3080中的函数,在此函数中会进行连接 wifi 热点的 at 指令的组装,然后保存在 Atcmd_buf 中通过 runAtCmd 函数,将数据通过串口发送到 wifi 模块,同时它继续在 runAtCmd 中等待模块发回的at指令返回值,在等待返回值的过程中,通过调用 EMW3080_IO_Receive函数查询串口的 Ring Buffer 中是否收到 wifi 模块的返回值。

问:串口的 Ring Buffer 中既有需要传递到应用层的数据,又有只需要在 WIFI 模块驱动层进行数据处理的数据,程序是如何区分两类数据的呢?

答:wifi 模块在发来的每一个数据都有一定的标识,用来说明这一帧数据的类型,比如 wifi 模块发送从云端收到的温度阈值数据包时,会加上 cip 英文数据的头,从这个标识就可以区分不同的数据包,然后进行数据处理。

网络数据产生/消耗层:Paho

image.png

网络接口:

image.png

WIFI 模块驱动:

image.png

设备端向云端发送数据的过程:

int devicest,atusPub (void)

{

int ret;

MQTTMessage MQTT_mag;

ret =0;

MQTT_msg.qos = Q0S1;  //QoS1 ;

MQTT_msg.dup = 0;//The DUP flag MST be set to 1 by the Client or Server vhen it attemptsto re-deliver a PUBLISH Packet

// The DuP flag MUST be set to 0 for all Qos 0 messages

MQTT_msg.retained = 1; //the Server MJsT store 757 the application Message and its Qos

MQTT_mag.payload = payload_buf;

// TODO:prepare pub payload,@sz

payload_buf [0]= GetTemperaturevalue ( ) ;

payload_buf [1]=GetHumvalue () ;

payload_buf[2]= GetTempratureThreshold( ;

MQTT_mag.payloadlen = 3;

if ( (ret=MQITPublish(zClient,temp_hum_topic, &MQTT_mag)) != 0){

mag_error ("Failed to publish data. td " ,ret) ;

mag_info(": temprature = %d,humidity = %d\n\n",GetTemperatureValue () ,cetHumValue());

}

数据接收的过程:

/**

@brief send data over the vifi connection.

*@paramBuffer: the buffer to send

*@paramLength: the Buffer's data size.

*@retval Returns EMW3080_OK on success and EM3080_ERROR othervise.

*/

EMW3080_StatusTypeDef EMNN3080_SendData(uint8_t socket,uint8_t* Bufferuint32_t Lengthuint32_t Timeout)

EMw3080_statusTypeDef Ret = EMw3080_OK;

if(Buffer != NULL)

uint32_t tickstart;

{

/ *Construct thecommand * /

memset(Atcnd, '1o",MAX_AT_CMD_SIZE);

sprintf( (char * )AtCmd,"AT+CIPSEND=%lu,$lusc", socket,Length,'r');

/ *Tne command doesn't have a return command

until the data is actually sent. Thus ve check here whether

ve got the '>' prompt or not. */

Ret = runAtCmd (AtCmdstrlen ((char *)AtCmd)(uint8_t*)AT_SEND_PROMPT_STRINGTimeout) ;

/ * Return Error */

if (Ret != EMw3080_oK){

return EMN3080_ERROR;

}

/ send the data */

Ret = runAtCmd (Buffer,Length,(uint8_t*)AT_OK_STRINGTimeout) ;

return Ret;

}

驱动和应用层数组定义:

1.Buffer 名称:MQTT_write_buf

默认大小:MQTT_BUFFER_SIZE512字节)
定义所在位置:Ali_iotclient.c
注释:

image.png

2.Buffer 名称:MQTT_read_buf

默认大小:MQTT_BUFFER_SIZE512字节)
定义所在位置:Ali_iotclient.c
注释:

image.png

3.Buffer 名称:AyCmd

默认大小:MAX_AT_SIZE(256字节)
定义所在位置:emw3080.c
注释:

image.png

4.Buffer 名称:RxBuffer

默认大小:MAX_RX_SIZE(1500字节)

定义所在位置:emw3080.c

5.Buffer 名称:WIFIRxBuffer

默认大小: RING_BUFFER_SIZE(1024字节)

定义所在位置:emw3080_io.h

6.Buffer 名称:”sock buffer”

默认大小:MAX_SOCKET_SIZE(512字节)定义所在位置:emw3080.h

WIFI_OpenClientConnection函数中分配内存

Paho MQTT客户端对下(网络连接)的适配

1.  网络接口的适配

typedef struct Network Network;

struct Network

net_sockhnd_t my_socket;

int (*mqttread) (Network*, unsigmed char* , int,int) ;

int (*mqttwrite)(Network* , unsigmed char* , int,int) ;

int (*disconnect)(Network*) ;

};

2.  Timer 的适配

struct Timer {

uint32_t init_tick;

uint32_t timeout_ms;

};

typedef struct Timer Timer;

void TimerCountdownMS(Timer* timerunsigmed int timeout_ms);

void TimerCountdown (Timer* timerunsigmed int timeout);

int TimerLeftMS(Timer* timer);

char TimerIsExpired(Timer* timer);

void TimerInit(Timer* timer) ;

3.  returnCode 枚举与 ST HAL 库的不兼容

Paho MQTT Client 的调用

1.MQTTClientlnit

初始化 MQTT 客户端

2.MQTTConnect

与服务器建立 MQTT 连接

3.MQTTSubscribe

向服务器订阅消息主题,并注册收到消息后的回调函数

4.MQTTPublish

向服务器发布某个主题的消息

5.MQTTYield

根据应用调整周期调用的间隔

Paho MQTT 客户端对上(阿里云 loT)的适配

与阿里云 MQTT 服务器连接需要的参数

1.用户名/密码

2.MQTT ClientID

3.保活时间

4.Cleansession

5.MQTT 服务器域名

typedef struct{

{

/** The eyecatcher for this structure. must be MQTC.*/

char struct_id[4];

/**The version number of this structure.Must be 0 */

int struct_version;

/**version of MQTT to be used. 3 = 3.1 4= 3.1.1

*/

unsigmed char MQITVersion;

MQTTString clientID;

unsigmed short keepAliveInterval;

unsigmed char cleansession;

unsigmed char willElag;

MQTTPacket_wil10ptions will;

MQTTString username;

MQITString password;

}MQTTPacket_connectData;  

构建 MQTT 服务器域名:

MQTT 服务器域名:
${YourProductKey}.iot-as-mqtt.${YourRegionld}.aliyuncs.com:1883

image.png

举例:
1.
服务器域名:

a1b05UeAQ6M.iot-as-mqtt.shanghai-cn.aliyuncs.com

2.端口:1883    

构建 MQTT ClientID

MQTT ClientID: clientld+"[Isecuremode=3,signmethod=hmacsha1,timestamp=132323232

clientld:客户端自己定义的ID号,可以使用 MAC 地址
3:
安全模式,可以选2TLS 直连)和3TCP 直连)

hmacsha1:签名算法支持:

hmacmd5

hmacsha1

hmacsha256
132323232:当前的时间戳。可以通过 HAL_GetTick 获取当前时间戳。

注意:
如果 clientld“b0f8933b9467”',签名算法选择 hmacsha1,当前时间戳为24081

MQTTClientID 为:“b0f8933b9467|securemode=3,signmethod=hmacsha1,timestamp=24081|'    

构建 MQTT 用户名:MQTT 用户名:DeviceName+&+ProductKey

举例:MQTT 用户名就是“smartthermometer&a1b05UeAQ6M”  

构建 MQTT 密码:

MQTT 密码=sign_hmac(DeviceSecret,content)

image.png

Mbedtls:
Demo IAR
工程      

Mbedtls 协议包              

MQTT 主题与消息负载格式:

1.功能:设置温度阈值

MQTT 主题:${productKey}/${deviceName}/tempThresholdSet
操作权限(设备):订阅

消息方向:下行

负载格式:一个字节:温度阈值。直接二进制传输,例如:0x1E 代表30

2.功能:解除警报

MQTT 主题:${productKey}/${deviceName}/clearAlarm
操作权限(设备):订阅

消息方向:下行

负载格式:一个字节,固定位0x01

3.功能:高温报警

MQTT 主题:S{productKey}/${deviceName}/tempAlarm
操作权限(设备):发布

消息方向:上行

负载格式:一个字节,固定位0x01

4.功能:上报属性

MQTT 主题:S{productKey}/${deviceName}/tempHumUpload
操作权限(设备):发布

消息方向:上行

负载格式:  Byte1:温度值

Byte2:湿度值

Byte3:温度阈值

MQTT 订阅消息的回调函数:

image.png

Demo 参数输入:
需要保存在 MCU 闪存中的信息:

1.WIFI 配网参数(串口输入)

2.阿里云 loT 平台三元组信息(串口输入)

3.温度报警阈值(云端下发)      

Demo 参数存储:

1.MCU 用户闪存容量2M,页大小4K(双 bank 下)

2.取末尾32K 作为用户参数存储区

Sensor 数据的读取(1

Sensor 数据的读取(2

项目例程内存占用:

总内存占用(使用 IAR v8.32.3,最高优化等级)

1.Flash52924字节

2.Ram:10874字节(包括4KB 堆栈)

主要模块内存占用:

image.png

相关文章
|
1月前
|
消息中间件 存储 Serverless
【实践】快速学会使用阿里云消息队列RabbitMQ版
云消息队列 RabbitMQ 版是一款基于高可用分布式存储架构实现的 AMQP 0-9-1协议的消息产品。云消息队列 RabbitMQ 版兼容开源 RabbitMQ 客户端,解决开源各种稳定性痛点(例如消息堆积、脑裂等问题),同时具备高并发、分布式、灵活扩缩容等云消息服务优势。
79 2
|
5月前
|
消息中间件 安全 API
《阿里云产品四月刊》—Apache RocketMQ ACL 2.0 全新升级(1)
阿里云瑶池数据库云原生化和一体化产品能力升级,多款产品更新迭代
287 1
《阿里云产品四月刊》—Apache RocketMQ ACL 2.0 全新升级(1)
|
5月前
|
消息中间件 安全 Apache
《阿里云产品四月刊》—Apache RocketMQ ACL 2.0 全新升级(2)
阿里云瑶池数据库云原生化和一体化产品能力升级,多款产品更新迭代
240 0
《阿里云产品四月刊》—Apache RocketMQ ACL 2.0 全新升级(2)
|
25天前
|
存储 边缘计算 物联网
阿里云物联网平台:推动万物互联的智能化解决方案
随着物联网技术的快速发展,阿里云物联网平台为企业提供了一体化的解决方案,包括设备接入、数据管理和智能应用等核心功能。平台支持海量设备接入、实时数据采集与存储、边缘计算,并具备大规模设备管理、高安全性和开放生态等优势。广泛应用于智能制造、智慧城市和智能家居等领域,助力企业实现数字化转型。
125 5
|
2月前
|
消息中间件 弹性计算 运维
阿里云云消息队列RabbitMQ实践解决方案评测报告
阿里云云消息队列RabbitMQ实践解决方案评测报告
72 9
|
4月前
|
存储 运维 监控
阿里云物联网平台的优势
【7月更文挑战第19天】阿里云物联网平台的优势
73 1
|
5月前
|
消息中间件 Apache 数据安全/隐私保护
《阿里云产品四月刊》—Apache RocketMQ ACL 2.0 全新升级(3)
阿里云瑶池数据库云原生化和一体化产品能力升级,多款产品更新迭代
119 0
《阿里云产品四月刊》—Apache RocketMQ ACL 2.0 全新升级(3)
|
20天前
|
存储 供应链 物联网
探索未来:区块链、物联网与虚拟现实技术的融合与创新
【10月更文挑战第15天】本文深入探讨了新兴技术如区块链、物联网(IoT)和虚拟现实(VR)的发展趋势及其在现代社会的应用。通过分析这些技术的独特属性和它们如何相互补充,我们揭示了一个由高度互联、智能化和沉浸式体验定义的未来图景。文章不仅讨论了这些技术当前的挑战,还展望了它们在未来可能带来的转变,旨在为读者提供对这些令人兴奋的技术趋势的全面理解。
|
20天前
|
安全 物联网 区块链
未来已来:探索区块链技术、物联网与虚拟现实的融合趋势
【10月更文挑战第15天】 在数字化浪潮中,区块链、物联网(IoT)和虚拟现实(VR)技术正引领着一场革命。本文将深入探讨这三种技术的发展趋势和相互融合的潜力,以及它们如何共同塑造我们的未来。我们将从基本概念入手,逐步揭示这些技术如何影响经济、社会和日常生活,同时提供具体应用场景以展示其变革力量。
|
7天前
|
供应链 物联网 区块链
未来已来:区块链技术、物联网与虚拟现实的融合与创新
【10月更文挑战第28天】在数字化浪潮的推动下,新兴技术如区块链、物联网(IoT)和虚拟现实(VR)正逐步渗透至我们的日常生活中。本文将探讨这些技术的发展趋势,以及它们如何相互融合,创造出前所未有的应用场景。我们将通过实际案例,展示这些技术如何改变工业、医疗、教育和娱乐等多个领域。最后,我们将展望这些技术未来的发展方向,以及它们可能带来的社会变革。
30 12

热门文章

最新文章

相关产品

  • 物联网平台