【超详细教程】基于华为云IOT平台实现多节点温度采集(STM32+NBIOT)

嵌入式悦翔园 2022-10-31 11:40

关注星标公众号,第一时间获取信息

文章内容较长,下面把目录给大家,需要的小伙伴可以只看自己需要观看对应部分!

  • 一、前言

  • 二、设计思路

  • 三、华为云IOT平台

    • 3.1 创建产品

    • 3.2 创建设备

    • 3.3 模拟设备上云测试

  • 四、设备数据转存

    • 4.1 创建OSB存储桶

    • 4.2 配置数据转发规则

  • 五、应用侧-可视化大屏开发

    • 5.1 应用侧接口

    • 5.2 查询设备影子数据接口

    • 5.3 接口调试

    • 5.5 接口总结

    • 5.5 如何获取X-Subject-Token

    • 5.6 查询设备影子数据代码

    • 5.7 界面设计最终效果

  • 六、硬件部分

    • 6.1 MQTT版本

    • 6.2 BC26上云配置代码

一、前言

当前的场景是,在高速公路上部署温度采集设备,在高速路地表安装温度检测传感器,检测当前路段的路面实际温度。一段高速路上有多个地点需要采集温度数据。 采集温度数据需要上传到云平台进行数据存储,并且通过可视化界面展示温度变化曲线,支持查询最近几天的温度信息。

二、设计思路

(1)云平台选型:使用华为云物联网云平台。

(2)云数据存储: 使用OBS存储,存放设备上传的历史数据。

(3)设备选项:NBIOT模块+温度采集模块,实现温度采集上报。

(4)数据可视化:采用华为云IoT应用侧接口,获取传感器设备上传到云端的数据,在本地设计界面进行可视化显示温度数据。

下面是温度数据可视化展示效果:

本篇文章主要介绍设备上云的详细流程,介绍华为云物联网云端产品、设备创建流程,数据转存方式,应用侧开发接口等等。

硬件选型:

(1)STM32开发板: STM32F103C8T6

(2)NBIOT模块--BC26

BC26模块是一款高性能、低功耗、多频段LTE Cat NB1无线通信模块。

(3)温度采集模块

pt100是铂热电阻,它的阻值会随着温度的变化而改变。PT后的100即表示它在0℃时阻值为100欧姆,在100℃时它的阻值约为138.5欧姆。其工作原理:当PT100在0℃时,其电阻为100欧姆。它的电阻会随着温度的升高而上升,并且它的电阻会匀速增加。

热电阻是一种常用于中低温的温度传感器。它的工作原理是基于电阻的热效应,即电阻的阻值随温度的变化而变化。铂金热敏电阻的热阻精度最高,具有抗振动、稳定性好、耐高压等特点。因此,它被制成各种标准温度计进行测量和校准。

三、华为云IOT平台

3.1 创建产品

官网地址: https://www.huaweicloud.com/

(1)设备接入IOTDA

在产品页面找到iot物联网,选择设备接入IOTDA

设备接入服务(IoT Device Access)是华为云的物联网平台,提供海量设备连接上云、设备和云端双向消息通信、批量设备管理、远程控制和监控、OTA升级、设备联动规则等能力,并可将设备数据灵活流转到华为云其他服务,帮助物联网行业用户快速完成设备联网及行业应用集成,基础版每月一百万条消息免费。

在页面上选择免费试用。

点击后,会进入到设备接入控制台页面。

(2)设备接入地址

在基础版详情页面,点击右边的按需计费详情,可以查看物联网服务器接入的IP地址,端口号、接入方式。

如果是设备接入,可以选择MQTT或者MQTTS协议,在单片机上只有MQTT协议验证比较方便,通过MQTT三元组即可完成设备连接,当前我这里的设备选择是MQTT协议连接华为云平台。

域名:a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com

(3)创建产品

在左边选项卡里点击产品,进入产品页面,点击右上角创建产品。

根据自己的产品信息,填写表单:

(4)完成产品创建

点击查看详情,可以进入到创建成功的产品页面。

(4)定义产品模型

产品创建之后,接着需要在平台上构建一款设备的抽象模型,使平台理解该款设备支持的功能。

比如:温度采集设备肯定会向云平台上传采集的温度信息;在产品模型里就可以定义一个温度的属性字段。

选择下面的自定义模型

添加服务ID。

添加属性。

新增属性字段。

当前在多节点温度采集的设备里,主要是采集温度上传,这里就新增一个温度的属性。

产品模型创建完成。

3.2 创建设备

(1)创建单个设备

设备注册的方式有很多:

【1】创建支持单个设备手动创建。

【2】如果设备特别多可以选择批量注册。

【3】通过API接口进行动态注册。

当前为了演示流程,这里选择第一种方式,手动创建单个设备。

在设备页面,选择所有设备选项,点击右边的注册设备按钮。

(2)单设备注册填写信息

点击注册设备之后,会弹出一个表单填写信息。

其中产品就选择刚才创建的产品,设备标识码这一项一般是填设备的ID(设备的唯一标识符,方便绑定设备)。目前还没有对接硬件,我这里就填dev1,方便接下来的测试。

下面的设备ID这一项如果不填,会自动生成,可以不管;最后输入密匙(这个密匙的作用:通过对每个设备进行身份验证,可以安全地将每个设备连接到平台,并且安全地管理这些设备),填好之后点击确定。

(3)设备创建完成

创建好之后,保存生成的设备ID和密匙。

得到的密匙和ID的格式文本如下:

    "device_id""6353a8163ec34a6d03c8dfe5_dev1",

这个设备密匙和ID,后面生成MQTT登录参数时需要用到。

(4)创建多个温度设备节点

由于本项目是实现多节点温度上传到云平台,每个节点都是一个独立的温度采集设备,为了方便演示效果,还需要多创建几个设备。

接下来的创建流程,和刚才第一个设备一样,这里就不再截图演示了。

点击创建设备按钮,继续注册。

目前一共创建了4个设备,其中main_dev设备是用来作为显示终端,在本地用显示屏显示其他温度采集节点采集的温度信息。 剩下3个设备dev1dev2dev3是表示3个独立的温度采集节点。

这4个设备的密匙和ID信息如下:

    "device_id""6353a8163ec34a6d03c8dfe5_dev1",

    "device_id""6353a8163ec34a6d03c8dfe5_dev2",

    "device_id""6353a8163ec34a6d03c8dfe5_dev3",

    "device_id""6353a8163ec34a6d03c8dfe5_main_dev",

3.3 模拟设备上云测试

目前设备创建之后,这些设备都还没有激活。接下来会使用MQTT客户端来模拟真实设备上云,上传温度数据。

这里的上云,包括数据交互都采用MQTT客户端来模拟实现,不涉及到实际的硬件,只要模拟能测试成功,并且能得到自己想要的结果,那硬件就没有问题了。

(1)生成MQTT鉴权三元组

设备要连接华为云平台的方式,在第一节创建产品的时候就已经介绍了,本次项目里的设备是采用MQTT协议接入云平台。 在完成设备模拟上云之前,需要先生成设备的MQTT协议鉴权三元组。

华为云提供了一个在线工具,用来生成MQTT鉴权三元组: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

工具打开的界面如下效果:

前面两行就是填设备创建后生成的设备ID和设备密匙,填好之后,生成下面3行信息,生成的3行就是MQTT协议登录需要用的参数。

按照格式分别生成4个设备的鉴权信息:

得到的三元组如下:

ClientId  6353a8163ec34a6d03c8dfe5_dev1_0_0_2022102209

Username  6353a8163ec34a6d03c8dfe5_dev1

Password  c58c45d514832b119b4302eafb3e74854849ca94079e9aed75efedf176e9c388

ClientId  6353a8163ec34a6d03c8dfe5_dev2_0_0_2022102209

Username  6353a8163ec34a6d03c8dfe5_dev2

Password  c58c45d514832b119b4302eafb3e74854849ca94079e9aed75efedf176e9c388

ClientId  6353a8163ec34a6d03c8dfe5_dev3_0_0_2022102209

Username  6353a8163ec34a6d03c8dfe5_dev3

Password  c58c45d514832b119b4302eafb3e74854849ca94079e9aed75efedf176e9c388

ClientId  6353a8163ec34a6d03c8dfe5_main_dev_0_0_2022102209

Username  6353a8163ec34a6d03c8dfe5_main_dev

Password  c58c45d514832b119b4302eafb3e74854849ca94079e9aed75efedf176e9c388

(2)MQTT客户端模拟设备登录

得到MQTT三元组之后,接下来用MQTT客户端模拟设备登录云平台。

按照软件的输入框提示,输入对应的信息,点击登录。 其中的IP地址和端口号在第一小节的产品创建里就介绍过了。 后面输入的这3行就是上一步生成的MQTT鉴权三元组。

登录成功。

然后打开云平台的控制台,查看设备在线情况:

可以看到dev1已经在线了, 刚才模拟的设备就是dev1。

(3)主题订阅与发布

目前设备已经成功登录,接下来要解决的问题就是数据传输问题了。

MQTT协议里要理解的两个概念就是主题订阅,主题发布。 设备上传数据到平台,属于 主题发布。 设备想要知道其他设备的数据或者云平台下发的指令,需要进行主题订阅。

帮助文档的地址: https://support.huaweicloud.com/api-iothub/iot_06_v5_3002.html

MQTT消息由固定报头(Fixed header)、可变报头(Variable header)和有效载荷(Payload)三部分组成。

其中固定报头(Fixed header)和可变报头(Variable header)格式的填写请参考MQTT标准规范,有效载荷(Payload)的格式由应用定义,即设备和物联网平台之间自己定义。

常见MQTT消息类型主要有CONNECT、SUBSCRIBE、PUBLISH。

CONNECT:指客户端请求和服务端连接。有效载荷(Payload)的主要参数,参考设备连接鉴权填写。

SUBSCRIBE:指客户端订阅请求。有效载荷(Payload)中的主要参数“Topic name”,参考Topic定义中订阅者为设备的Topic。

可变报头(Variable header)中的主要参数“Topic name”,指设备上报到物联网平台时发布者为设备的Topic。详细请参考Topic定义。

有效载荷(Payload)中的主要参数为完整的数据上报和命令下发的消息内容,目前是一个JSON对象。

上行Topic是指设备向平台发送请求,或上报数据,或回复响应。

下行Topic是指平台向设备下发指令,或回复响应。

设备与平台建立连接后,需要订阅下行Topic,否则无法收到平台下发的指令或回复的响应。应用侧接口的调用,需要设备侧的配合,例如应用侧下发命令,设备侧需要先订阅“平台命令下发”的下行Topic,否则设备无法收到平台命令,应用下发命令的接口也会报超时。

在产品页面,可以看到主题的格式,以及对于主题的用途:**

【1】订阅主题

对于设备而言,一般会订阅平台下发消息给设备 这个主题。

设备想接收平台下发的消息,就需要订阅平台下发消息给设备 的主题,订阅后,平台下发消息给设备,设备就会收到消息。

主题的格式如下:

$oc/devices/{device_id}/sys/messages/down

$oc/devices/6353a8163ec34a6d03c8dfe5_dev1/sys/messages/down

【2】发布主题

对于设备,发布主题,也就显示向云平台上传数据。

发布的主题格式如下:

$oc/devices/{device_id}/sys/properties/report

$oc/devices/6353a8163ec34a6d03c8dfe5_dev1/sys/properties/report

发布主题时,需要上传数据,这个数据格式是JSON格式。

上传的JSON数据格式如下:

      "service_id": <填服务ID>,

      "<填属性名称1>": <填属性值>,

      "<填属性名称2>": <填属性值>,

根据JSON格式,一次可以上传多个属性字段。 这个JSON格式里的,服务ID,属性字段名称,属性值类型,在前面创建产品的时候就已经介绍了,不记得可以翻到前面去查看。

根据这个格式,组合温度节点一次上传的数据:

{"services": [{"service_id""temp","properties":{"temp":24.6}}]}

(4)MQTT客户端模拟设备上报数据

打开MQTT客户端填入订阅主题,发布主题,和需要发布的数据,然后分别点击订阅主题按钮,发布主题按钮。 右边提示成功之后,就可以打开云平台看上传的效果了。 (这里是以dev1,设备1为例)

打开云平台看到dev1已经在线。

点击dev1,进去查看设备上传的数据。 可以看到,刚才上传的数据已经收到了。

到此,设备上传数据到云平台已经完成。

四、设备数据转存

如果设备上传的数据需要进行保存,后续进行分析做其他用途,可以利用数据转发服务,让平台将设备上报数据推送给自己的应用服务器,由应用服务器进行保存;也可以选择让平台将设备上报数据转发给OBS对象存储服务,由OBS进行存储,进行永久保存,非常方便。如果存储在OBS里,自己设计应用侧界面时,也可以直接拉取OBS里的数据下来进行显示,处理,分析。

4.1 创建OSB存储桶

对象存储服务(Object Storage Service,OBS)是一个基于对象的存储服务,提供了海量、安全、高可靠、低成本的数据存储能力。

(1)选择管理控制台

(2)创建桶

填充桶信息: 我这里选择的是 华北-北京一

我这里因为要长期使用,这里选择1年的购买权。

(3)创建成功

4.2 配置数据转发规则

(1)创建规则

选择左侧导航栏的规则>数据转发,单击右上角的创建规则

填充规则转发的信息:

(2)设置转发目标

单击添加,设置转发目标。

这里的区域选择--华北-北京一。 因为前面的OBS桶创建的时候,设置区域设置的是北京一,然后点击授权。

授权之后,选择刚才创建的OBS桶,设置存储数据的目录和文件名字。

存储的数据可以直接转存JSON数据到OBS存储桶,也可以存放成CSV文件到存储桶。

如果选择存储JSON,就是直接将设备上传的数据存放到OBS存储里,如果选择存储CSV文件,可以自己选择需要存储的字段。 下面我演示一下存储成CSV文件时如何进行设置。 (选择JSON文件不需要进行任何设置,直接将设备上传的数据JSON存储进去了)。

下面设置转发的字段: (如果提示没有授权,点击授权即可)

这个转发字段就是表示需要存放的数据是那些,对于路灯而言,肯定是需要存储上报的温度、湿度、电量、光照强度的属性的。 这些属性在创建产品的时候设置,设备上报的也是这些属性。

这是设备上传一次云平台的完整JSON数据格式:

  "resource""device.property",

  "event_time""20221018T131627Z",

  "request_id""5ee95a0c-262d-43c3-8d31-af453f9952ef",

      "app_id""7211833377cf435c8c0580de390eedbe",

      "device_id""634e3e423ec34a6d03c84bfb_1126626497",

      "node_id""1126626497",

      "product_id""634e3e423ec34a6d03c84bfb",

      "gateway_id""634e3e423ec34a6d03c84bfb_1126626497"

          "service_id""temp",

          "properties": {

          "event_time""20221018T131627Z"

当前设备上传到云端服务器有一个温度属性字段temp,如果想转发设备上传的这个温度字段,就可以这样写:

notify_data.body.services[0].properties.temp

后面的存储目标字段,为了好区分,直接填temp即可。

如果设备还上传了其他属性字段也想转发,按照上面格式设置即可。

如果存储数据时,想知道这个数据是那个产品,那个设备上传的,也可以将设备ID和产品ID转发存储起来:格式如下。

notify_data.header.app_id  

notify_data.header.device_id

下面是我设置好,转发存储的字段:

确定后,点击设置完成。

(3)测试规则

设置好之后,在设置转发目标的页面点击测试。

输入数据模板,然后点击连通性测试。如果测试结果显示成功,说明整体流程没有问题了。

(4)启用规则

设置完成后,点击启用规则。

(6)数据上报测试

为了验证转发规则是否生效,接下来使用MQTT客户端多上报几次数据到云平台。

上传之后,打开OBS存储桶的控制台页面。打开转发规则存储的OBS桶。

找到存储数据的文件,点击下载。

下载下来,打开可以看到存储的数据:

到此,数据转发,存储已经成功了。

五、应用侧-可视化大屏开发

对于数据的可视化显示,华为云提供了(Data Lake Visualization)一站式数据可视化平台,数据可视化服务(DLV)可以从OBS文件读取数据呈现为可视化报表,实现数据的可视化显示。

下面是华为云的DLV大屏从OBS读取数据显示的流程:

当前我这里的需求是需要在本地自己设计界面显示数据,没有采用华为云的DLV大屏,如果自己本地软件需要显示设备上传的数据,就需要使用华为云物联网的平台的应用侧API接口,读取设备上传的数据进行,本地进行显示;如果需要历史数据,可以读取OBS存储桶里存储的数据进行显示。

5.1 应用侧接口

帮助文档地址: https://support.huaweicloud.com/usermanual-iothub/iot_01_0045.html

5.2 查询设备影子数据接口

应用侧接口可以查询发送指令给设备查询属性,也可以读取设备的影子数据。

【1】查询设备查询: 这个是实时查询,相当于应用侧接口发送指令给在线设备,设备收到指令,将当前最新的数据再上传。这个需要保证设备在线,离线是无法调用的。

【2】影子数据: 影子数据相当于保存设备上传的最新一次数据。 读取读取影子设备数据,是不需要设备在线。

(1)接口URI地址

(2)请求参数说明

(3)响应参数

(4)请求示例

GET https://{Endpoint}/v5/iot/{project_id}/devices/{device_id}/shadow

Content-Type: application/json

(5)响应示例

Status Code: 200 OK

Content-Type: application/json

  "device_id" : "40fe3542-f4cc-4b6a-98c3-61a49ba1acd4",

    "service_id" : "WaterMeter",

        "temperature" : "60"

      "event_time" : "20151212T121212Z"

        "temperature" : "60"

      "event_time" : "20151212T121212Z"

(6)错误码

5.3 接口调试

在线调试地址:https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IoTDA&api=ShowDeviceShadow

下面是调试影子 数据查询接口,查询设备影子数据: 右边返回的是设备上传的最新数据。

5.5 接口总结

https://iotda.cn-north-4.myhuaweicloud.com/v5/iot/{project_id}/devices/{device_id}/shadow

 "X-Auth-Token""这个需要自己获取",   

 "Content-Type""application/json"

5.5 如何获取X-Subject-Token

使用API访问华为云的所有服务接口,都需要填X-Subject-Token参数,下面介绍步骤:

(1)创建一个新的IAM帐户

鼠标悬停在右上角的用户名称上,弹出下拉框,选择统一身份认证。

(2)选择创建用户

(3)使用调试接口测试获取oken

调试接口地址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IAM&api=KeystoneCreateUserTokenByPassword[1]

右边响应头里的X-Subject-Token就是获取的token。

(4)上面的这些账户名称从哪里获取?

(5)请求地址和数据格式

获取X-Subject-Token请求的地址: https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens[2]

请求头数据:

  "User-Agent""API Explorer",

  "X-Auth-Token""******",

  "Content-Type""application/json;charset=UTF-8"

请求体数据:

             "name""xxxxx"  //这里填当前主账户名称

           "name""xxxx",  //这个新建的子账户名称

           "password""xxxxx"    //这个是新建的子账户密码

         "name""cn-north-4"

(6)代码实现

     QNetworkRequest request;

     requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens")

                  .arg(SERVER_ID);

     //requestUrl="http://10.0.0.6:8080";

     request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));

     url.setUrl(requestUrl);

     request.setUrl(url);

     QString text =QString("{"auth":{"identity":{"methods":["password"],"password":"

     "{"user":{"domain": {"

     ""name":"%1"},"name": "%2","password": "%3"}}},"

     ""scope":{"project":{"name":"%4"}}}}")

             .arg(MAIN_USER)

             .arg(IAM_USER)

             .arg(IAM_PASSWORD)

             .arg(SERVER_ID);

     manager->post(request, text.toUtf8());

5.6 查询设备影子数据代码

(1)这是请求代码

void Widget::Get_device_properties()

    QNetworkRequest request;

    requestUrl = QString("https://iotda.%1.myhuaweicloud.com/v5/iot/%2/devices/%3/shadow")

                 .arg(SERVER_ID)

            .arg(PROJECT_ID)

            .arg(device_id);

    request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));

    request.setRawHeader("X-Auth-Token",Token);

    url.setUrl(requestUrl);

    manager->get(request);

void Widget::on_pushButton_update_device_clicked()

    Get_device_properties();

(2)这是请求一次返回的JSON数据

  "device_id""6353a8163ec34a6d03c8dfe5_dev1",

      "service_id""temp",

        "properties": null,

        "event_time": null

        "event_time""20221024T013607Z"

5.7 界面设计最终效果

六、硬件部分

6.1 MQTT版本

注意: 华为云、OneNet、腾讯IOT 等平台规定接入的MQTT协议版本必须是3.1.1 。

在BC26里,需要执行这行代码配置MQTT协议版本为3.1.1

AT+QMTCFG="version",0,4

6.2 BC26上云配置代码

    GPIOC->CRL&=0xFFFFFFF0;

    GPIOC->CRL|=0x00000003;

        char *check_data 检测返回的数据

u8 BC26_SendCmd(char *cmd,char *check_data)

   for(i=0;i<5;i++) //测试的总次数

    memset(USART2_RX_BUFFER,0,sizeof(USART2_RX_BUFFER));

    USARTx_StringSend(USART2,cmd); //发送指令

      for(j=0;j<500;j++) //等待的时间(ms单位)

          if(USART2_RX_FLAG)

              USART2_RX_BUFFER[USART2_RX_CNT]='\0';

              if(strstr((char*)USART2_RX_BUFFER,check_data))

                  return 0;

              else break;

          delay_ms(30); //一次的时间

    if(BC26_SendCmd("AT\r\n","OK"))

        USART1_Printf("BC26模块不存在.\r\n");

        USART1_Printf("BC26模块正常!\r\n");

    if(BC26_SendCmd("AT+CIMI\r\n","OK"))

        USART1_Printf("模块未插卡.\r\n");

        USART1_Printf("卡已经插好.\r\n");

    if(BC26_SendCmd("AT+CGATT=1\r\n","OK"))

        USART1_Printf("配置:网络激活失败.\r\n");

        USART1_Printf("配置:网络激活成功.\r\n");

    if(BC26_SendCmd("AT+CGATT?\r\n","OK"))

        USART1_Printf("状态:网络激活失败.\r\n");

        USART1_Printf("状态:网络激活成功.\r\n");

    if(BC26_SendCmd("AT+CSQ\r\n","OK"))

        USART1_Printf("查询信号质量失败.\r\n");

        USART1_Printf("信号质量:%s\r\n",USART2_RX_BUFFER);

//    if(BC26_SendCmd("AT+QGNSSC=1\r\n","OK"))

//        USART1_Printf("激活GPS定位失败.\r\n");

//        USART1_Printf("激活GPS定位成功.\r\n");

//    if(BC26_SendCmd("AT+QGNSSAGPS=1\r\n","OK"))

//        USART1_Printf("开启AGPS定位失败.\r\n");

//        USART1_Printf("开启AGPS定位成功.\r\n");

//    if(BC26_SendCmd("AT+CGPADDR=1\r\n","OK"))

//        USART1_Printf("激活GPRS场景失败.\r\n");

//        USART1_Printf("激活GPRS场景成功.\r\n");

    if(BC26_SendCmd("AT+CEREG?\r\n","+CEREG: 0,1"))

        USART1_Printf("网络注册状态:失败.\r\n");

        USART1_Printf("网络注册状态:成功.\r\n");

char BC26_SEND_BUFF[500];

int BC26_MQTT_Connect(void)

     USART1_Printf("正在关闭之前的连接...\r\n");

    BC26_SendCmd("AT+QMTCLOSE=0\r\n","OK");

    BC26_SendCmd("AT+QMTCONN?\r\n","OK");

    USART1_Printf("正在连接MQTT服务器..\r\n");

    sprintf(BC26_SEND_BUFF,"AT+QMTOPEN=0,\"%s\",%s\r\n",MQTT_SERVER_ADDR,MQTT_SERVER_PORT);

    if(BC26_SendCmd(BC26_SEND_BUFF,"OK"))

        USART1_Printf("MQTT服务器连接失败:%s\r\n",BC26_SEND_BUFF);

        USART1_Printf("MQTT服务器连接成功.\r\n");

    USART1_Printf("正在登录MQTT服务器...\r\n");

    sprintf(BC26_SEND_BUFF,"AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n",MQTT_CLIENT_ID,MQTT_USERNAME,MQTT_PASSWORD);

    if(BC26_SendCmd(BC26_SEND_BUFF,"OK"))

        USART1_Printf("MQTT服务器登录失败:%s\r\n",BC26_SEND_BUFF);

        USART1_Printf("MQTT服务器登录成功.\r\n");

    USART1_Printf("正在订阅主题...\r\n");

    sprintf(BC26_SEND_BUFF,"AT+QMTSUB=0,1,\"%s\",2\r\n",MQTT_TOPIC_SUB_GET);

    if(BC26_SendCmd(BC26_SEND_BUFF,"OK"))

        USART1_Printf("MQTT主题订阅失败:%s\r\n",BC26_SEND_BUFF);

        USART1_Printf("MQTT主题订阅成功.\r\n");

int MQTT_PublishTheme(char *text)

    sprintf(BC26_SEND_BUFF,"AT+QMTPUB=0,0,0,0,\"%s\"\r\n",MQTT_TOPIC_SUB_SET);

    if(BC26_SendCmd(BC26_SEND_BUFF,">"))

        USART1_Printf("发布主题等待输入失败:%s\r\n",BC26_SEND_BUFF);

    USARTx_StringSend(USART2,text);     //发送主题内容

    if(BC26_SendCmd(send_buf,"OK"))

        USART1_Printf("发布主题内容失败:%s\r\n",BC26_SEND_BUFF);

        return 2; //发送结束符号

        USART1_Printf("发布主题内容成功.\r\n");

     USART1_Printf("发布主题内容:%s\r\n",text);

int MQTT_SendAttribute(char *text,char *request_id)

    sprintf(BC26_SEND_BUFF,"AT+QMTPUB=0,0,0,0,\"%s%s\"\r\n",MQTT_TOPIC_SUB_SET_RUN,request_id);

    if(BC26_SendCmd(BC26_SEND_BUFF,">"))

        USART1_Printf("(响应)发布主题等待输入失败:%s\r\n",BC26_SEND_BUFF);

    USARTx_StringSend(USART2,text);     //发送主题内容

    if(BC26_SendCmd(send_buf,"OK"))

        USART1_Printf("(响应)发布主题内容失败:%s\r\n",BC26_SEND_BUFF);

        return 2; //发送结束符号

        USART1_Printf("(响应)发布主题内容成功.\r\n");

     USART1_Printf("(响应)发布主题内容:%s\r\n",text);

        double *Longitude  :经度

        double *latitude   :纬度

返回值: 0表示定位成功,1表示数据接收失败,2表示定位失败

u8 BC26_GetGPS_Data(double *Longitude,double *latitude)

    if(BC26_SendCmd("AT+QGNSSRD=\"NMEA/RMC\"\r\n""OK\r\n"))return 1;

    if(GPS_GNRMC_Decoding((char *)USART2_RX_BUFFER,Longitude,latitude))return 2;

    if(BC26_SendCmd("AT+QGNSSC?\r\n","+QGNSSC: 1")) 

        if(BC26_SendCmd("AT+QGNSSC=1\r\n","OK\r\n"))

            USART1_Printf("开启GPS功能失败.\r\n");

            return 1;  //GPS功能启动失败

            USART1_Printf("开启GPS功能成功.\r\n");

参考资料

[1]

https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IAM&api=KeystoneCreateUserTokenByPassword: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IAM&api=KeystoneCreateUserTokenByPassword

[2]

https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens: https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens

推荐阅读



01

加入嵌入式交流群


02

嵌入式资源获取


03

STM32中断优先级详解


04

STM32下载程序新思路--使用串口下载程序


嵌入式悦翔园 专注于嵌入式技术,包括但不限于STM32、Arduino、51单片机、物联网、Linux等编程学习笔记,同时包含大量的学习资源。欢迎关注,一同交流学习,共同进步!
评论
  • ‌一、高斯计的正确选择‌1、‌明确测量需求‌‌磁场类型‌:区分直流或交流磁场,选择对应仪器(如交流高斯计需支持交变磁场测量)。‌量程范围‌:根据被测磁场强度选择覆盖范围,例如地球磁场(0.3–0.5 G)或工业磁体(数百至数千高斯)。‌精度与分辨率‌:高精度场景(如科研)需选择误差低于1%的仪器,分辨率需匹配微小磁场变化检测需求。2、‌仪器类型选择‌‌手持式‌:便携性强,适合现场快速检测;‌台式‌:精度更高,适用于实验室或工业环境。‌探头类型‌:‌横向/轴向探头‌:根据磁场方向选择,轴向探头适合
    锦正茂科技 2025-05-06 11:36 437浏览
  • 在过去的很长一段时间里,外卖市场呈现出美团和饿了么双寡头垄断的局面。美团凭借先发优势、强大的地推团队以及精细化的运营策略,在市场份额上长期占据领先地位。数据显示,截至2024年上半年,美团外卖以68.2%的市场份额领跑外卖行业,成为当之无愧的行业老大。其业务广泛覆盖,从一线城市的繁华商圈到二三线城市的大街小巷,几乎无处不在,为无数消费者提供便捷的外卖服务。饿了么作为阿里本地生活服务的重要一环,依托阿里强大的资金和技术支持,也在市场中站稳脚跟,以25.4%的份额位居第二。尽管市场份额上与美团有一定
    用户1742991715177 2025-05-06 19:43 69浏览
  • 文/Leon编辑/cc孙聪颖‍《中国家族企业传承研究报告》显示,超四成“企二代” 明确表达接班意愿,展现出对家族企业延续发展的主动担当。中国研究数据服务平台(CNRDS)提供的精准数据进一步佐证:截至 2022 年,已有至少 280 家上市家族企业完成权杖交接,其中八成新任掌门人为创始人之子,凸显家族企业代际传承中 “子承父业” 的主流模式。然而,对于“企二代” 而言,接棒掌舵绝非易事。在瞬息万变的商业环境中,他们既要在白热化的市场竞争中开拓创新、引领企业突破发展瓶颈,又需应对来自父辈管理层的经
    华尔街科技眼 2025-05-06 18:17 27浏览
  • 二位半 5线数码管的驱动方法这个2位半的7段数码管只用5个管脚驱动。如果用常规的7段+共阳/阴则需要用10个管脚。如果把每个段看成独立的灯。5个管脚来点亮,任选其中一个作为COM端时,另外4条线可以单独各控制一个灯。所以实际上最多能驱动5*4 = 20个段。但是这里会有一个小问题。如果想点亮B1,可以让第3条线(P3)置高,P4 置低,其它阳极连P3的灯对应阴极P2 P1都应置高,此时会发现C1也会点亮。实际操作时,可以把COM端线P3设置为PP输出,其它线为OD输出。就可以单独控制了。实际的驱
    southcreek 2025-05-07 15:06 427浏览
  • 硅二极管温度传感器是一种基于硅半导体材料特性的测温装置,其核心原理是利用硅二极管的电学参数(如正向压降或电阻)随温度变化的特性实现温度检测。以下是其工作原理、技术特点及典型应用:一、工作原理1、‌PN结温度特性‌硅二极管由PN结构成,当温度变化时,其正向电压 VF与温度呈线性负相关关系。例如,温度每升高1℃,VF约下降2 mV。2、‌电压—温度关系‌通过jing确测量正向电压的微小变化,可推算出环境温度值。部分型号(如SI410)在宽温域内(如1.4 K至475 K)仍能保持高线性度。
    锦正茂科技 2025-05-09 13:52 119浏览
  • 后摄像头是长这个样子,如下图。5孔(D-,D+,5V,12V,GND),说的是连接线的个数,如下图。4LED,+12V驱动4颗LED灯珠,给摄像头补光用的,如下图。打开后盖,发现里面有透明白胶(防水)和白色硬胶(固定),用合适的工具,清理其中的胶状物。BOT层,AN3860,Panasonic Semiconductor (松下电器)制造的,Cylinder Motor Driver IC for Video Camera,如下图。TOP层,感光芯片和广角聚焦镜头组合,如下图。感光芯片,看着是玻
    liweicheng 2025-05-07 23:55 308浏览
  • 2024年初,OpenAI公布的Sora AI视频生成模型,震撼了国产大模型行业。随后国产厂商集体发力视频大模型,快手发布视频生成大模型可灵,字节跳动发布豆包视频生成模型,正式打响了国内AI视频生成领域第一枪。众多企业匆忙入局,只为在这片新兴市场中抢占先机,却往往忽视了技术成熟度与应用规范的打磨。以社交平台上泛滥的 AI 伪造视频为例,全红婵家人被恶意仿冒博流量卖货,明星们也纷纷中招,刘晓庆、张馨予等均曾反馈有人在视频号上通过AI生成视频假冒她。这些伪造视频不仅严重侵犯他人权
    用户1742991715177 2025-05-05 23:08 115浏览
  • Matter协议是一个由Amazon Alexa、Apple HomeKit、Google Home和Samsung SmartThings等全球科技巨头与CSA联盟共同制定的开放性标准,它就像一份“共生契约”,能让原本相互独立的家居生态在应用层上握手共存,同时它并非另起炉灶,而是以IP(互联网协议)为基础框架,将不同通信协议下的家居设备统一到同一套“语义规则”之下。作为应用层上的互通标准,Matter协议正在重新定义智能家居行业的运行逻辑,它不仅能向下屏蔽家居设备制造商的生态和系统,让设备、平
    华普微HOPERF 2025-05-08 11:40 289浏览
  • 这款无线入耳式蓝牙耳机是长这个样子的,如下图。侧面特写,如下图。充电接口来个特写,用的是卡座卡在PCB板子上的,上下夹紧PCB的正负极,如下图。撬开耳机喇叭盖子,如下图。精致的喇叭(HY),如下图。喇叭是由电学产生声学的,具体结构如下图。电池包(AFS 451012  21 12),用黄色耐高温胶带进行包裹(安规需求),加强隔离绝缘的,如下图。451012是电池包的型号,聚合物锂电池+3.7V 35mAh,详细如下图。电路板是怎么拿出来的呢,剪断喇叭和电池包的连接线,底部抽出PCB板子
    liweicheng 2025-05-06 22:58 530浏览
  • UNISOC Miracle Gaming奇迹手游引擎亮点:• 高帧稳帧:支持《王者荣耀》等主流手游90帧高画质模式,连续丢帧率最高降低85%;• 丝滑操控:游戏冷启动速度提升50%,《和平精英》开镜开枪操作延迟降低80%;• 极速网络:专属游戏网络引擎,使《王者荣耀》平均延迟降低80%;• 智感语音:与腾讯GVoice联合,弱网环境仍能保持清晰通话;• 超高画质:游戏画质增强、超级HDR画质、游戏超分技术,优化游戏视效。全球手游市场规模日益壮大,游戏玩家对极致体验的追求愈发苛刻。紫光展锐全新U
    紫光展锐 2025-05-07 17:07 281浏览
  • 文/郭楚妤编辑/cc孙聪颖‍相较于一众措辞谨慎、毫无掌舵者个人风格的上市公司财报,利亚德的财报显得尤为另类。利亚德光电集团成立于1995年,是一家以LED显示、液晶显示产品设计、生产、销售及服务为主业的高新技术企业。自2016年年报起,无论业绩优劣,董事长李军每年都会在财报末尾附上一首七言打油诗,抒发其对公司当年业绩的感悟。从“三年翻番顺大势”“智能显示我第一”“披荆斩棘幸从容”等词句中,不难窥见李军的雄心壮志。2012年,利亚德(300296.SZ)在深交所创业板上市。成立以来,该公司在细分领
    华尔街科技眼 2025-05-07 19:25 352浏览
  • 飞凌嵌入式作为龙芯合作伙伴,隆重推出FET-2K0300i-S全国产自主可控工业级核心板!FET-2K0300i-S核心板基于龙芯2K0300i工业级处理器开发设计,集成1个64位LA264处理器,主频1GHz,提供高效的计算能力;支持硬件ECC;2K0300i还具备丰富的连接接口USB、SDIO、UART、SPI、CAN-FD、Ethernet、ADC等一应俱全,龙芯2K0300i支持四路CAN-FD接口,具备良好的可靠性、实时性和灵活性,可满足用户多路CAN需求。除性价比超高的国产处理器外,
    飞凌嵌入式 2025-05-07 11:54 65浏览
  • 随着智能驾驶时代到来,汽车正转变为移动计算平台。车载AI技术对存储器提出新挑战:既要高性能,又需低功耗和车规级可靠性。贞光科技代理的紫光国芯车规级LPDDR4存储器,以其卓越性能成为国产芯片产业链中的关键一环,为智能汽车提供坚实的"记忆力"支持。作为官方授权代理商,贞光科技通过专业技术团队和完善供应链,让这款国产存储器更好地服务国内汽车厂商。本文将探讨车载AI算力需求现状及贞光科技如何通过紫光国芯LPDDR4产品满足市场需求。 车载AI算力需求激增的背景与挑战智能驾驶推动算力需求爆发式
    贞光科技 2025-05-07 16:54 190浏览
  • 温度传感器的工作原理依据其类型可分为以下几种主要形式:一、热电阻温度传感器利用金属或半导体材料的电阻值随温度变化的特性实现测温:l ‌金属热电阻‌(如铂电阻 Pt100、Pt1000):高温下电阻值呈线性增长,稳定性高,适用于工业精密测温。l ‌热敏电阻‌(NTC/PTC):NTC 热敏电阻阻值随温度升高而下降,PTC 则相反;灵敏度高但线性范围较窄,常用于电子设备温控。二、热电偶传感器基于‌塞贝克效应‌(Seebeck effect):两种不同
    锦正茂科技 2025-05-09 13:31 109浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦