-
为了实现您所描述的功能,建议使用以下工具和技术:QFileDialog 用于选择二进制文件。QPlainTextEdit 或自定义控件用于显示十六进制内容。QScrollBar 用于处理滚动事件。多线程读取文件,以便不会卡死界面。搜索功能包括输入框和按钮,处理搜索匹配。下面是实现所需的主要代码片段,包括 .h 和 .cpp 文件。hexviewer.h#ifndef HEXVIEWER_H #define HEXVIEWER_H #include <QWidget> #include <QFile> #include <QPlainTextEdit> #include <QLineEdit> #include <QPushButton> #include <QVBoxLayout> #include <QHBoxLayout> #include <QScrollBar> #include <QThread> #include <QMutex> class HexViewer : public QWidget { Q_OBJECT public: HexViewer(QWidget *parent = nullptr); ~HexViewer(); private slots: void selectFile(); void displayFileContent(); void search(); void nextMatch(); void prevMatch(); void loadMoreData(); private: void loadFile(const QString &fileName); QString readBytesToHex(qint64 start, qint64 count); void highlightMatches(); void scrollToMatch(int index); QFile file; QPlainTextEdit *textEdit; QLineEdit *searchBox; QPushButton *searchButton; QPushButton *nextButton; QPushButton *prevButton; QVector<int> matchPositions; int currentMatchIndex; QThread *loadThread; QMutex mutex; bool loading; }; #endif // HEXVIEWER_Hhexviewer.cpp#include "hexviewer.h" #include <QFileDialog> #include <QMessageBox> #include <QScrollBar> HexViewer::HexViewer(QWidget *parent) : QWidget(parent), currentMatchIndex(-1), loading(false) { textEdit = new QPlainTextEdit(this); textEdit->setReadOnly(true); searchBox = new QLineEdit(this); searchButton = new QPushButton("Search", this); connect(searchButton, SIGNAL(clicked()), this, SLOT(search())); nextButton = new QPushButton("Next", this); connect(nextButton, SIGNAL(clicked()), this, SLOT(nextMatch())); nextButton->setEnabled(false); prevButton = new QPushButton("Previous", this); connect(prevButton, SIGNAL(clicked()), this, SLOT(prevMatch())); prevButton->setEnabled(false); QPushButton *selectFileButton = new QPushButton("Select File", this); connect(selectFileButton, SIGNAL(clicked()), this, SLOT(selectFile())); QPushButton *displayButton = new QPushButton("Display", this); connect(displayButton, SIGNAL(clicked()), this, SLOT(displayFileContent())); QVBoxLayout *mainLayout = new QVBoxLayout; QHBoxLayout *topLayout = new QHBoxLayout; topLayout->addWidget(selectFileButton); topLayout->addWidget(displayButton); mainLayout->addLayout(topLayout); mainLayout->addWidget(textEdit); QHBoxLayout *searchLayout = new QHBoxLayout; searchLayout->addWidget(searchBox); searchLayout->addWidget(searchButton); searchLayout->addWidget(nextButton); searchLayout->addWidget(prevButton); mainLayout->addLayout(searchLayout); setLayout(mainLayout); } HexViewer::~HexViewer() { if (loadThread) { loadThread->quit(); loadThread->wait(); delete loadThread; } } void HexViewer::selectFile() { QString fileName = QFileDialog::getOpenFileName(this, "Select a binary file"); if (!fileName.isEmpty()) { file.setFileName(fileName); } } void HexViewer::displayFileContent() { if (!file.open(QIODevice::ReadOnly)) { QMessageBox::critical(this, "Error", "Could not open the file"); return; } textEdit->clear(); if (!loadThread) { loadThread = new QThread(this); connect(loadThread, &QThread::finished, loadThread, &QObject::deleteLater); } loading = true; QMetaObject::invokeMethod(this, "loadMoreData", Qt::QueuedConnection); connect(textEdit->verticalScrollBar(), &QScrollBar::valueChanged, this, &HexViewer::loadMoreData); } void HexViewer::loadMoreData() { if (!loading) return; static const qint64 chunkSize = 1024; // Load 1KB at a time QByteArray data = file.read(chunkSize); if (data.isEmpty()) { loading = false; disconnect(textEdit->verticalScrollBar(), &QScrollBar::valueChanged, this, &HexViewer::loadMoreData); return; } QString hexData = readBytesToHex(file.pos() - data.size(), data.size()); textEdit->appendPlainText(hexData); } QString HexViewer::readBytesToHex(qint64 start, qint64 count) { file.seek(start); QByteArray data = file.read(count); QString hexData; for (char byte : data) { hexData.append(QString("%1 ").arg(static_cast<unsigned char>(byte), 2, 16, QChar('0')).toUpper()); } return hexData; } void HexViewer::search() { QString keyword = searchBox->text(); if (keyword.isEmpty()) return; matchPositions.clear(); currentMatchIndex = -1; QString content = textEdit->toPlainText(); int pos = 0; while ((pos = content.indexOf(keyword, pos)) != -1) { matchPositions.append(pos); pos += keyword.length(); } if (!matchPositions.isEmpty()) { currentMatchIndex = 0; highlightMatches(); scrollToMatch(currentMatchIndex); nextButton->setEnabled(true); prevButton->setEnabled(true); } else { nextButton->setEnabled(false); prevButton->setEnabled(false); } } void HexViewer::nextMatch() { if (currentMatchIndex < matchPositions.size() - 1) { currentMatchIndex++; scrollToMatch(currentMatchIndex); } } void HexViewer::prevMatch() { if (currentMatchIndex > 0) { currentMatchIndex--; scrollToMatch(currentMatchIndex); } } void HexViewer::highlightMatches() { QTextCursor cursor(textEdit->document()); cursor.movePosition(QTextCursor::Start); QTextCharFormat defaultFormat; cursor.setCharFormat(defaultFormat); QTextCharFormat highlightFormat; highlightFormat.setBackground(Qt::yellow); for (int pos : matchPositions) { cursor.setPosition(pos); cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, searchBox->text().length()); cursor.setCharFormat(highlightFormat); } } void HexViewer::scrollToMatch(int index) { if (index >= 0 && index < matchPositions.size()) { QTextCursor cursor(textEdit->document()); cursor.setPosition(matchPositions[index]); textEdit->setTextCursor(cursor); textEdit->ensureCursorVisible(); } }以上代码实现了一个基本的Hex Viewer,具备以下功能:选择文件:用户可以选择一个二进制文件。显示内容:以十六进制格式递增加载显示文件内容。搜索功能:用户可以输入十六进制数进行搜索并高亮显示匹配项。提供“下一个”和“上一个”按钮来遍历匹配项。运行代码确保您的项目中已经包含了必要的Qt模块,比如 widgets 和 core。以下是一个简单的 main.cpp 文件:#include <QApplication> #include "hexviewer.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); HexViewer viewer; viewer.show(); return app.exec(); }说明多线程部分:为了简化示例,该代码中的多线程处理只是预留了一些位置,实际应用中应在读取大数据时启用线程。UI细节调优:可以根据需求进一步美化UI,比如增加不同的布局、优化文本显示等。
-
如下图所示,出现了竖纹和压缩图像问题,我用的转换语句为:QImage img(frame.getPtr(), mWidth, mHeight,QImage::Format_Grayscale16);
-
按着网上的教程,在代码中加入了QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);这个语句,然后发现界面在第一次打开时会超出了屏幕大小(界面大小是1920*180, 屏幕分辨率为2560*1440),然后往小分辨率界面中便能完美适应(小分辨率屏幕为1920*1080)
-
我想实现的功能,在视频流中做一个roi(就是重写绘图和鼠标响应事件),但是我目前写完了之后发现有问题。我写的方式是创建了一个类然后让这个类继承了wodget,在这个类里面重写了上述响应函数,然后在主界面中new出来这个类,其中给这个类传入的parent指针是我主界面创建好的qgraphicsview指针,但是我发现这样子并没有成功调用自己写好的类里面的响应函数(就绘图鼠标的那个),就是无法在我当前显示视频流的界面中实现roi功能。然后我在思考是不是需要在主界面里面重写哪些响应函数才可以,而不是单独创建一个类去实现,然后再去调用
-
一般在项目中经常需要组合路径,与其他程序进行相互调用传递消息通信。 经常可能因为多加斜杠、少加斜杠等问题导致很多问题。 为了解决这些问题,我们可以使用QDir来完成路径的拼接,不要直接拼接字符串。QDir的静态方法QDir::cleanPath() 是为了规范化路径名的,在使用QDir组合路径时,只需使用/作为路径分隔符即可。 例如:#include <QCoreApplication> #include <QDir> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QString dirPath = QDir::cleanPath(QDir::homePath() + "/Documents/data"); qDebug() << dirPath; return a.exec(); }上述代码中,使用QDir::homePath()获取用户文档目录,并使用/作为路径分隔符将其与子目录data组合起来,得到了完整的目录路径。QDir::cleanPath() 可以删除路径中多余的斜杠。例如,如果路径中有多个连续斜杠或末尾斜杠,则该方法将它们替换为单个斜杠。以下是一个示例代码:#include <QCoreApplication> #include <QDir> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QString path1 = QDir::cleanPath("/home/binjie09//Documents/");// 多个连续的斜杠 qDebug() << "Cleaned path1:" << path1; QString path2 = QDir::cleanPath("/home/binjie09/Documents/images/");// 末尾斜杠 qDebug() << "Cleaned path2:" << path2; return a.exec(); }上述代码中,使用QDir::cleanPath()清理了两个路径,分别是/home/binjie09//Documents/和/home/binjie09/Documents/images/。在清理后,多个连续斜杠被替换成一个斜杠,末尾斜杠被去除,得到了规范化后的路径。使用QDir拼接多个路径,可以使用QDir::filePath()方法。例如:QString path1 = "C:/documents"; QString path2 = "work"; QString path3 = "project1"; QDir dir(path1); QString result = dir.filePath(path2); dir.setPath(result); result = dir.filePath(path3); qDebug() << result; // 输出:C:/documents/work/project1上述代码中,我们首先定义了三个路径,分别是"C:/documents"、"work"和"project1"。然后,我们创建了一个QDir对象,用于表示第一个路径"C:/documents"。接下来,使用filePath()方法将其他两个路径拼接起来。首先将"path2"添加到QDir对象中生成新的路径,然后将"path3"再添加到新生成的路径中。最终,得到了拼接后的路径"C:/documents/work/project1"。需要注意的是,在调用filePath()方法之前,要先创建一个QDir对象,用于表示第一个路径。这是因为filePath()方法是QDir类的方法,只能通过QDir对象调用。
-
在Ubuntu18下成功编译了ffmpeg442-Android,尝试在qt中使用硬件解码。qt的环境如下:qt版本:5.12.6qt编译器:Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a整个硬件解码的代码如下: //1. 根据名称查找解码器的类型 type = av_hwdevice_find_type_by_name(m_HardwareName.data()); if (type == AV_HWDEVICE_TYPE_NONE) { qDebug()<<"未找到解码器的类型:"<<m_HardwareName; fprintf(stderr, "Device type %s is not supported.\n",m_HardwareName.data()); fprintf(stderr, "可用设备类型:"); while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE) fprintf(stderr, " %s", av_hwdevice_get_type_name(type)); fprintf(stderr, "\n"); return -1; } qDebug()<<"已经找到解码器:"<<m_HardwareName<<"其枚举值:"<<type; //2. 打开多媒体流,并且获取一些信息 if (avformat_open_input(&input_ctx,m_MediaFile.data(), NULL, NULL) != 0) { qDebug()<<"无法打开输入文件:"<<m_MediaFile; return -1; } //3. 读取媒体文件的数据包以获取流信息 qDebug()<<"读取媒体文件的数据包以获取流信息"; if (avformat_find_stream_info(input_ctx, NULL) < 0) { qDebug()<<"找不到输入流信息:"<<m_MediaFile; return -1; } qDebug()<<"查找视频流信息"; /* 查找视频流信息*/ ret = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); if (ret < 0) { qDebug()<<"在输入文件中找不到视频流"; return -1; } video_stream = ret; for (i = 0;; i++) { const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i); if (!config) { qDebug("Decoder %s does not support device type %s.\n", decoder->name, av_hwdevice_get_type_name(type)); return -1; } if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && config->device_type == type) { hw_pix_fmt = config->pix_fmt; break; } } 代码执行到这边的时候,便会出现如下报错:测试发现小米的手机可以正常通过此处代码,而联想、华为无法通过。怀疑是ffmpeg的代码流程及对应不同手机的适配有问题
-
[问题求助] QT 5.12.6 下调用FFMPEG android 4.2.2 出现“Decoder h264 does not support device type mediacodec”的问题已经成功编译了 FFMPEG-ANDRIOD 4.2.2,编译的选项如下:#!/bin/bashexport NDK=/home/sqm/ndk/android-ndk-r20b #NDK的路径TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64function build_android{./configure \--prefix=$PREFIX \--enable-neon \--enable-shared \--enable-gpl \--enable-hwaccels \--enable-runtime-cpudetect \--enable-postproc \--enable-small \--enable-jni \--enable-mediacodec \--enable-decoder=h264_mediacodec \--enable-decoder=hevc_mediacodec \--enable-decoder=mpeg4_mediacodec \--enable-hwaccel=h264_mediacodec \--enable-static \--enable-pic \--enable-avdevice \--disable-doc \--disable-debug \--enable-ffmpeg \--disable-ffplay \--disable-ffprobe \--disable-symver \--cross-prefix=$CROSS_PREFIX \--target-os=android \--arch=$ARCH \--cpu=$CPU \--cc=$CC \--cxx=$CXX \--enable-cross-compile \--sysroot=$SYSROOT \--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \--extra-ldflags="$ADDI_LDFLAGS"make cleanmake -j8make installecho "============================ build android $CPU success =========================="}#arm64-v8aARCH=arm64CPU=armv8-aAPI=21CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clangCXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysrootCROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-PREFIX=$(pwd)/android/$CPUOPTIMIZE_CFLAGS="-march=$CPU"build_android#armv7-aARCH=armCPU=armv7-aAPI=21CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clangCXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysrootCROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-PREFIX=$(pwd)/android/$CPUOPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "build_androidQT 的.pro文件中引用如下:整个工程编译正常,但是一旦调试、打开视频流,就会报如下错误:代码中是在如下地方出现问题:
-
qmake中进行如下声明:#指定库文件的路径LIBS += -L$$PWD/ffmepg422_android/arm64/lib -lavcodecLIBS += -L$$PWD/ffmepg422_android/arm64/lib -lavfilterLIBS += -L$$PWD/ffmepg422_android/arm64/lib -lavdeviceLIBS += -L$$PWD/ffmepg422_android/arm64/lib -lavutilLIBS += -L$$PWD/ffmepg422_android/arm64/lib -lavformatLIBS += -L$$PWD/ffmepg422_android/arm64/lib -lpostprocLIBS += -L$$PWD/ffmepg422_android/arm64/lib -lswscaleLIBS += -L$$PWD/ffmepg422_android/arm64/lib -lswresample#指定头文件的路径INCLUDEPATH+=$$PWD/ffmepg422_android/arm64/includecontains(ANDROID_TARGET_ARCH,arm64-v8a) { ANDROID_EXTRA_LIBS = \ $$PWD/ffmepg422_android/arm64/lib/libswscale.so \ $$PWD/ffmepg422_android/arm64/lib/libswresample.so \ $$PWD/ffmepg422_android/arm64/lib/libpostproc.so \ $$PWD/ffmepg422_android/arm64/lib/libclang_rt.ubsan_standalone-aarch64-android.so \ $$PWD/ffmepg422_android/arm64/lib/libavutil.so \ $$PWD/ffmepg422_android/arm64/lib/libavformat.so \ $$PWD/ffmepg422_android/arm64/lib/libavfilter.so \ $$PWD/ffmepg422_android/arm64/lib/libavdevice.so \ $$PWD/ffmepg422_android/arm64/lib/libavcodec.so ANDROID_PACKAGE_SOURCE_DIR = \ $$PWD/android}DISTFILES += \ android/AndroidManifest.xml \ android/build.gradle \ android/gradle/wrapper/gradle-wrapper.jar \ android/gradle/wrapper/gradle-wrapper.properties \ android/gradlew \ android/gradlew.bat \ android/res/values/libs.xml使用Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a对工程进行编译,出现如下报错:
-
按照https://bbs.huaweicloud.com/forum/thread-104581-1-1.html这个我已经成功编译到了最后2000个包但是报了这个错误,这个该如何排查呢
-
如题,想在自己的Qt项目中加入mindspore lite的API进行推理,有没有什么示例可以参考?
-
【功能模块】Atlas 200 DK运行Qt界面很卡,是板子的问题??还是Qt设计的问题??有没有运行良好的相关的案例可以借鉴??非常感谢【操作步骤&问题现象】1、2、【截图信息】【日志信息】(可选,上传日志内容或者附件)
-
## 1. 前言 随着人们生活水平的提高及科学技术的发展,个人信息保护显得至关重要,设计了一款物联网智能电子密码锁,以STM32单片机为主控制器,由触摸矩阵键盘、ESP8266、步进电机等模块组成,具有远程控制、随机密码生成等功能。经软硬件测试,系统响应迅速,灵敏度高,实时性好,系统识别准确率高达99%,该系统运行稳定,安全可靠,功耗低及具有较好的扩展性。 当前支持的开锁方式: (1)支持手机APP远程开锁。通过华为云物联网平台实现远程发送指令开锁,设备上的ESP8266通过连接家里路由器,在连接华为云物联网平台,可以在手机APP上对设备端的RTC时间进行校准,设备唯一ID获取,生成随机开锁密码,可以点击APP上的开锁按钮,通过物联网平台提供的API发送指令给STM32设备完成开锁。 (2)随机密码开锁。手机APP与本地设备都采用时间、作为算法种子,采用算法生成开锁密码,每一串的密码有效时间为一分钟。查看手机APP上显示的密码之后,在本地设备上输入完成密码对比开锁。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815683392894589.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815698406672293.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815711686853937.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815723624805330.png) ## 2. 手机APP设计 ### 2.1 开发环境介绍 上位机软件采用Qt框架设计,Qt是一个跨平台的C++图形用户界面应用程序框架。Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。简单来说,QT可以很轻松的帮你做带界面的软件,甚至不需要你投入很大精力。 **QT官网:** https://www.qt.io/ ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815768467682212.png) ### 2.2 学习教程 QT入门实战专栏: https://blog.csdn.net/xiaolong1126626497/category_11400392.html QT5环境安装教程:https://xiaolong.blog.csdn.net/article/details/120654599 下载QT5.12.6下载地址: https://download.qt.io/archive/qt/5.12/5.12.6/ 打开链接后选择: qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details 软件安装时断网安装,否则会提示输入账户。 **安装的时候,勾选一个mingw 32编译器即可。** ### 2.3 实现效果 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815817999192909.png) ## 3. 创建云端设备 ### 3.1 创建设备 登录官网: https://www.huaweicloud.com/ 直接搜索物联网,打开页面。 https://www.huaweicloud.com/product/iothub.html ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815848341445174.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815860048859822.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815871392302261.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815881353480125.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815889535554908.png) 得到产品ID,保存好ID,点击查看详情: ```cpp 产品ID为:61b9ba3a2b2aa20288c1e7f1. ``` ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815905135424681.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815915023263824.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815923588447711.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815932354385979.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815939351293807.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815946838269282.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815955230222345.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815963988623042.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815971502147090.png) ### 3.2 创建MQTT登录账号和密匙 设备创建完成接来下生成MQTT登录账号、密匙,方便设备登录云端平台。 官网工具地址: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/ ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649815998992450512.png) ## 4. STM32设备端代码设计 ### 4.1 硬件相关原理图 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/13/1649816048198235511.png) ### 4.2 硬件接线 ```cpp 1. 板载ESP8266串口WIFI模块与STM32的串口3相连接。 PB10--RXD 模块接收脚 PB11--TXD 模块发送脚 PB8---CH-PD---悬空 PB9---RST---悬空 GND---GND 地 VCC---VCC 电源(3.3V~5.0V) 2. 触摸按键使用TTP229型号的驱动芯片 SCL接PC11 SDA-OUT接PC10 电源接VCC-3.3 GND接GND 3. ULN2003控制28BYJ-48步进电机接线: ULN2003接线: IN4: PC9 d IN3: PC8 c IN2: PC7 b IN1: PC6 a + : 5V - : GND 4. OLED显示屏 D0----SCK-----PB14 D1----MOSI----PB13 RES—复位(低电平有效)—PB12 DC---数据和命令控制管脚—PB1 CS---片选引脚-----PA7 5. 板载按键 KEY1---PA0 KEY2---PC13 6.板载LED灯 LED1---PB5 LED2---PB0 LED3---PB1 7. 板载蜂鸣器 BEEP---PA8 ``` ### 4.3 服务器连接核心代码 ```cpp //华为物联网服务器的设备信息 #define MQTT_ClientID "61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510" #define MQTT_UserName "61b9ba3a2b2aa20288c1e7f1_QQ1126626497" #define MQTT_PassWord "385ce91dfe7da5b7431868d5d87e7998163c493344040935d5a00024d6324242" //订阅与发布的主题 #define SET_TOPIC "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/messages/down" //订阅 #define POST_TOPIC "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/properties/report" //发布 char mqtt_message[200];//上报数据缓存区 int main() { u32 time_cnt=0; u32 i; u8 key; LED_Init(); BEEP_Init(); KEY_Init(); USART1_Init(115200); TIMER1_Init(72,20000); //超时时间20ms USART2_Init(9600);//串口-蓝牙 TIMER2_Init(72,20000); //超时时间20ms USART3_Init(115200);//串口-WIFI TIMER3_Init(72,20000); //超时时间20ms USART1_Printf("正在初始化WIFI请稍等.\n"); if(ESP8266_Init()) { USART1_Printf("ESP8266硬件检测错误.\n"); } else { //非加密端口 USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode("CMCC-Cqvn","99pu58cb","121.36.42.100",1883,1)); } //2. MQTT协议初始化 MQTT_Init(); //3. 连接华为服务器 while(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord)) { USART1_Printf("服务器连接失败,正在重试...\n"); delay_ms(500); } USART1_Printf("服务器连接成功.\n"); //3. 订阅主题 if(MQTT_SubscribeTopic(SET_TOPIC,0,1)) { USART1_Printf("主题订阅失败.\n"); } else { USART1_Printf("主题订阅成功.\n"); } .................. .................. ................... } ```
-
https://support.huaweicloud.com/dpmg-kunpengcps/kunpengcps920_02_0005.html文档首页> 鲲鹏BoostKit ARM原生使能套件> 安卓模拟器方案> 安卓模拟器 编译指南> 鲲鹏编译环境准备和组件编译构建> 构建android-sdk-linux/tools目录下部件执行configure生成Makefile章节执行失败编译中断。gmake: *** [Makefile:177:xkbcommon.o] 错误 1xkbcommon disabled.XLib auto-detection... ()g++ -c -pipe -O2 -g -Wall -W -fPIC -I. -I../../../mkspecs/linux-g++ -o xlib.o xlib.cppxlib.cpp:34:10: 致命错误:X11/Xlib.h:No such file or directory #include <X11/Xlib.h> ^~~~~~~~~~~~编译中断。gmake: *** [Makefile:186:xlib.o] 错误 1XLib disabled.Xrender auto-detection... ()g++ -c -pipe -O2 -g -Wall -W -fPIC -I. -I../../../mkspecs/linux-g++ -o xrender.o xrender.cppxrender.cpp:34:10: 致命错误:X11/Xlib.h:No such file or directory #include <X11/Xlib.h> ^~~~~~~~~~~~编译中断。gmake: *** [Makefile:186:xrender.o] 错误 1Xrender disabled.XInput2 auto-detection... ()g++ -c -pipe -O2 -g -Wall -W -fPIC -I. -I../../../mkspecs/linux-g++ -o xinput2.o xinput2.cppxinput2.cpp:34:10: 致命错误:X11/Xlib.h:No such file or directory #include <X11/Xlib.h> ^~~~~~~~~~~~编译中断。gmake: *** [Makefile:186:xinput2.o] 错误 1XInput2 disabled.xcb auto-detection... ()g++ -c -pipe -O2 -g -Wall -W -fPIC -I. -I../../../mkspecs/linux-g++ -o xcb.o xcb.cppxcb.cpp:34:10: 致命错误:xcb/xcb.h:No such file or directory #include <xcb/xcb.h> ^~~~~~~~~~~编译中断。gmake: *** [Makefile:177:xcb.o] 错误 1xcb disabled.The test for linking against libxcb failed! You might need to install dependency packages for libxcb. See src/plugins/platforms/xcb/README.[root@localhost qt-everywhere-opensource-src-5.6.1]# make -j64 & make install[1] 27322make: *** 没有指明目标并且找不到 makefile。 停止。make: *** 没有规则可制作目标“install”。 停止。[1]+ 退出 2 make -j64[root@localhost qt-everywhere-opensource-src-5.6.1]#
-
本文分享自华为云社区《[物联网应用开发实践案例-智慧农业【玩转华为云】](https://bbs.huaweicloud.com/blogs/336348?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=iot&utm_content=content)》,作者: DS小龙哥。 # 1. 设计需求、硬件环境介绍 ## 1.1 项目背景 近几年,物联网、智能家居、AI人工智能技术发送非常迅速。在物联网技术的支撑下,如今农业逐渐走向现代化,自动化、现在智能化的农业生产成为了主流。告别“刀耕火种”的传统农业后,现代农业也正在向智慧型转变,当前智慧农业模式已经深入到农业生产的各个环节,灌溉、施肥、植保等细分领域都将与物联网、信息技术等先进科技相结合,效率、效果也将得到大大提高。 要知道,所谓的“智慧农业”就是充分应用现代信息技术成果,集成应用计算机技术与网络技术、物联网技术、无线通信技术以及专家智慧与知识等,实现农业可视化远程诊断、远程控制、灾变预警等智能管理。那么融入物联网的智慧农业的有以下几个优点: 1、低成本化 众所周知,目前想要购买一套全面的智慧农业设备的成本都较高,这是普通农户难以承受的,因此,想要实现全面智慧农业,那么低成本的智慧农业设备将成为智慧农业趋势之一。 2、操作简单化 智慧农业的根本是服务于农业、服务于农户,所以想要做到让农户更快地与智慧农业接轨就必须要把系统做得易操作、易学。要知道,当前我国农民普遍文化程度较低,只有将操作简单化才能够让每个农民都能熟练操作。 智慧农业也是一个大范围,比如: 智慧鱼塘、智慧大棚、智慧园林、城市绿化、智能果园等等都属于智慧农业的范围。 有了智能设备的加持:可以实现自动浇水灌溉、实时检测土壤养分、水分、环境温度、自动补光等一系列联动操作。 本篇文章就利用华为云IOT物联网平台实践搭建一个智慧农业智慧大脑,设备平台采用小熊开发板,搭载的CPU是意法半导体的STM32L431芯片,这是意法半导体推出的低功耗芯片;配合外部的一些专业传感器,能够获取空气中的温湿度数据,光照度数据等,根据种植区的空气温湿度数据,判断是否进行灌溉。 ## 1.2 实现功能 本项目是**利用意法半导体的STM32L431+ESP8266 WIFI ,配合华为云物联网平台服务器,组建一个智慧农业控制系统**,结合外部传感器采集的数据,并利用这些数据判断是否进行灌溉,补光等信息提示。 考虑到以学习、实践为目的,当前项目采用了ESP8266无线WIFI网卡作为联网设备,ESP8266价钱便宜,支持串口编程,有标准的一套AT资料,资料多,作为学习而言,非常适合。可以通过对ESP8266的编程实验,了解TCP、MQTT网络编程相关知识点。 **当前项目主要分为六个功能模块,分别是:基础系统模块、温度采集模块、湿度采集模块、光照采集模块、无线传感器网络模块、OLED显示屏模块。** (1)基础系统模块:进行各个数据的接收与转发,控制扫水作业是否进行,浇水作业是采用板载的电机模拟 (2)温度采集模块:采集监测区域的温度数据,传输到微控制器 (3)湿度采集模块:采集监测区域的湿度数据,传输到微控制器 (4)光照采集模块:采集监测区域的光照数据,传输到微控制器 (5)无线传感器网络模块:数据上传至云平台,数据下发交互等 (6)LCD显示屏模块:实时显示所监测到的各项数据 小熊开发板的扩展板上自带了光敏传感器、温湿度传感器、直流电机模块,可以很方便的实现上面的这些功能需求。 本项目设备的源代码里,连接华为云的MQTT协议是按照MQTT的官方中文手册编写的,不依赖任何外部SDK,不依赖ESP8266设备,只要能联网的设备都可以连接华为云IOT,非常适合移植到其他单片机平台;不管是采用51,STM32F1系列,都可以直接参考代码移植。 华为云物联网平台提供了API接口,可以通过API开发配套的上位机,方便实现数据查看,手动灌溉等操作。 提供的API除了可以查询设备属性信息之外,还可以创建产品、设备、对开发上位机来讲非常方便,可以开发出从底层设备到云端服务器、再到应用APP软件,完成3层数据交互。 **下面是开发的上位机APP运行效果。** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175051382617294.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175057100148220.png) **当前文章主要完成3个任务的实践:** (1)云端产品的创建、设备的创建 (2)设备上云,完成服务器登录、数据上传 (3)手机APP、电脑上位机软件的开发,可以通过云端API接口与设备、服务器之前通讯 ## 1.3 设备实物图 目前联网的设备采用的ESP8266(手上没有现成的NBIOT模块,暂时使用ESP8266代替,核心原理是一样的),正常项目里会使用NBIOT模块联网作为数据传输源。 小熊开发板的设备相关实物图如下: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175094797183715.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175110584719224.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175121080812352.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175129002270490.png) # 2. 创建IOT服务器端产品 需要先创建产品、在产品下再创建设备。产品是一个大框架,产品下的设备可以有很多,在应用层,可以通过华为云平台提供的API创建设备,删除设备,查询设备属性,在做产品时,软件端可以做一个设备注册的引导界面,完成产品下的设备注册,再将数据传递给设备端,这个过程叫“配网“,具体逻辑需要配合设备端完成。最终完成自动化设备创建,注册,上线等操作。 下面先介绍如何手动创建产品,创建设备,了解创建产品创建设备的过程中需要填充什么参数,理解之后,再使用API时才更加理解参数含义。 ## 2.1 创建产品 直接打开物联网产品页面: https://www.huaweicloud.com/product/iothub.html ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175166902205959.png) 打开产品页面,选择右上角创建产品。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175174719841777.png) 根据自己情况填写信息。就是填写自己产品的一些参数信息。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175185055432218.png) 创建成功后打开产品详情页面,拉到最下面,点击创建自定义模型文件。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175192063790846.png) 这里创建模型文件主要就是为了MQTT客户端能够正确的上传传感器数据上来,每个传感器设置一个属性,这个属性就是表示了传感器的数据值类型。 比如: 先添加一个电机,这个电机就是浇水电机,能上报开关状态,云端也能下发命令控制电机,所以需要添加属性和下发的命令。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175201722509470.png) 添加属性: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175208508485860.png) 添加命令: 因为电机需要云端远程控制。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175216237442899.png) **接下来就创建温度、湿度、光照度传感器的属性,这些传感器只是向云端上传数据,不需要下发指令控制,选择只读就可以了,电机要先实现远程浇灌控制,属性就选择读写。** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175230847157134.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175238792242118.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175246999734074.png) 创建完毕效果,一共有4个属性,电机、温度、湿度、光强度: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175257550959969.png) ## 2.2 创建设备 选择设备页面,注册设备。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175279762314044.png) 创建后保持设备密匙等信息,接下来登录服务器时,生成MQTT账号密匙需要用到这些参数。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175287659495656.png) **当前创建的设备信息如下:** { "device_id": "61cd1d97078a93029b84e7b6_1126626497", "secret": "1126626497" } ## 2.3 生成MQTT登录账号信息 官微提供的在线小工具: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/ 按照提示填入数据,生成,非常方便。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175318610138744.png) **当前生成的信息如下:** ClientId 61cd1d97078a93029b84e7b6_1126626497_0_0_2021123003 Username 61cd1d97078a93029b84e7b6_1126626497 Password b219f3a0099fa0284a2671a5c699b67a7cf6d5f7355d9ee8190011f3b64f71b5 # 3. 使用MQTT客户端模拟测试 为了验证服务器配置是否OK,先使用MQTT客户端软件进行连接测试。 ## 3.1 华为云IOT服务器地址与端口 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175364295746029.png) 端口: 1883 域名: a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com IP地址: 121.36.42.100 ## 3.2 订阅主题 在产品页面,可以看到主题管理页面,能看到当前设备可以订阅的主题有哪些。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175384618688260.png) 一般订阅下发的数据: 格式: $oc/devices/{device_id}/sys/messages/down //订阅主题: 平台下发消息给设备 $oc/devices/61cd1d97078a93029b84e7b6_1126626497/sys/messages/down ## 3.3 上报主题数据 官方文档介绍: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175422679295577.png) 服务ID,属性ID在产品页面查看,2.1小节创建产品里就讲了这个属性的作用。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175430717692585.png) 每次可以单个属性上报,也可以一起上报。 格式: $oc/devices/{device_id}/sys/properties/report //设备上报主题请求 $oc/devices/61cd1d97078a93029b84e7b6_1126626497/sys/properties/report //上报的数据格式如下 //电机开状态反馈 {"services": [{"service_id": "motor","properties":{"motor":1}}]} //电机关状态反馈 {"services": [{"service_id": "motor","properties":{"motor":0}}]} //温度上报 {"services": [{"service_id": "motor","properties":{"SHT30_H":14}}]} //湿度上报 {"services": [{"service_id": "motor","properties":{"SHT30_L":70}}]} //光照强度上报 {"services": [{"service_id": "motor","properties":{"BH1750":80}}]} //也可以一起上报 {"services": [{"service_id": "motor","properties":{"motor":1}},{"service_id": "motor","properties":{"SHT30_H":15}},{"service_id": "motor","properties":{"SHT30_L":70}},{"service_id": "motor","properties":{"BH1750":80}}]} ## 3.4 登录服务器 按照软件提示,填入相关数据即可。 如需要也需要使用和我一样的同款软件,打开百度搜索MQTT客户端_v2.4(协议3.1.1).exe 即可找到下载地址。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175463921320709.png) 发送数据后查看云端,已经登录成功,数据已经上传成功。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175471972120402.png) ## 3.5 下发命令 电机设备支持读写,支持下发命令,在设备页面测试。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175487044810251.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175494476974068.png) 点击确定之后,参看MQTT客户端软件,已经收到了下发的数据。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175507292326265.png) `len:174,Data:l$oc/devices/61cd1d97078a93029b84e7b6_1126626497/sys/commands/request_id=390ce15d-6e69-4021-b83a-5e953eea874c{"paras":{"motor":1},"service_id":"motor","command_name":"motor"}` # 4. 设备端上华为云IOT ## 4.1 安装keil软件 MCU采用的STM32芯片,设备端代码编写开发就采用的keil5。 keil5安装包下载地址: http://www.myir-tech.com/download.asp 安装keil时,软件要放在英文目录下,电脑的用户名必须是英文,否则会出现一些奇怪问题。 安装过程中,根据提示下一步下一步点击即可。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175543625309624.png) ## 4.2 编写代码 **工程代码:** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175560434530148.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175568195118852.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175578538624928.png) 工程代码较多,这里就贴出main.c全部代码: (main.c代码较多,详细代码请见原文章) # 5. 上位机软件开发 上位机与设备之间通信,需要通过服务器完成,服务器提供了对应的API接口,所以对于上位机而言通信主要是对HTTP请求进行处理,返回的数据进行解析等操作。 当前的软件采用是采用QT设计的,实现了产品注册、设备注册、获取在线设备,获取设备属性,远程指令发送等主要功能。 访问华为云的接口都需要填一个X-Auth-Token参数,这个参数获取需要IAM账号,下面第一步就先介绍,如何创建IAM账号,如何获取X-Auth-Token参数。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175812032365358.png) ## 5.1 创建IAM账户 创建一个IAM账户,方便接下来使用API接口访问华为云服务时,生成token登录密匙。 地址: https://console.huaweicloud.com/iam/?region=cn-north-4#/iam/users ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175827884760005.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175835504688316.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175846205737092.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175854479151766.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175863811998205.png) 账户创建好之后,代码里就可以编写一个获取Token的函数。 /* 功能: 获取token */ void Widget::GetToken() { //表示获取token function_select=3; QString requestUrl; QNetworkRequest request; //设置请求地址 QUrl url; //获取token请求地址 requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens") .arg(SERVER_ID); //自己创建的TCP服务器,测试用 //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.2 查询设备列表 帮助文档地址: https://support.huaweicloud.com/api-iothub/iot_06_v5_0048.html 官方提供了API接口,可以直接获取产品下面的所有设备详细信息返回。 关于请求参数,返回结果的字段含义,在帮助文档里有详细介绍。 URL格式: /v5/iot/{project_id}/devices 示例: https://iotda.cn-north-4.myhuaweicloud.com/v5/iot/0f2d61e43600f4e22f74c003616710bc/devices?product_id=6210e8acde9933029be8facf&is_cascade_query=false&limit=10&marker=ffffffffffffffffffffffff&offset=0 接口的在线调试地址:https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IoTDA&api=ListDevices ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175902102214133.png) 返回的结果: { "devices": [ { "app_id": "1af45e3938bb4482bc0be0a5cb3089e3", "app_name": "DefaultApp_620esbs1", "device_id": "6210e8acde9933029be8facf_dev2", "node_id": "dev2", "gateway_id": "6210e8acde9933029be8facf_dev2", "device_name": "dev2", "node_type": "GATEWAY", "description": null, "fw_version": null, "sw_version": null, "device_sdk_version": null, "product_id": "6210e8acde9933029be8facf", "product_name": "DHT11", "status": "INACTIVE", "tags": [] }, { "app_id": "1af45e3938bb4482bc0be0a5cb3089e3", "app_name": "DefaultApp_620esbs1", "device_id": "6210e8acde9933029be8facf_dev1", "node_id": "dev1", "gateway_id": "6210e8acde9933029be8facf_dev1", "device_name": "dev1", "node_type": "GATEWAY", "description": null, "fw_version": null, "sw_version": null, "device_sdk_version": null, "product_id": "6210e8acde9933029be8facf", "product_name": "DHT11", "status": "OFFLINE", "tags": [] } ], "page": { "count": 2, "marker": "6210efa980c60c11be19ead1" } } 上面的返回结果里通过JSON数组保存了设备信息,每一个设备就是一个独立的对象,上面的数据里返回了两个设备的信息,说明产品的目录下创建了两个设备。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175923116793833.png) 应用层编写代码完成设备列表获取: //查询所有设备 void Widget::Get_AllDevice() { //查询设备列表 function_select=1; QString requestUrl; QNetworkRequest request; //设置请求地址 QUrl url; //设备列表请求地址 requestUrl = QString("https://iotda.%1.myhuaweicloud.com/v5/iot/%2/devices?product_id=%3&is_cascade_query=false&limit=10&marker=ffffffffffffffffffffffff&offset=0") .arg(SERVER_ID) .arg(PROJECT_ID) .arg(Product_id); //设置数据提交格式 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json")); //设置token request.setRawHeader("X-Auth-Token",Token); //构造请求 url.setUrl(requestUrl); request.setUrl(url); //发送请求 manager->get(request); } 服务器返回的结果解析: //查询设备列表 if(function_select==1) { //清空原来的设备列表 ui->comboBox->clear(); device_id_lis.clear(); //解析数据 QJsonParseError json_error; QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error); if(json_error.error == QJsonParseError::NoError) { QJsonObject obj = document.object(); //判断是否是对象,然后开始解析数据 if(document.isObject()) { QJsonObject obj = document.object(); if(obj.contains("devices")) { QJsonArray array=obj.take("devices").toArray(); for(int i=0;i/得到设备ID if(obj1.contains("device_id")) { QString device_id=obj1.take("device_id").toString(); device_id_lis.append(device_id); ui->comboBox->addItem(device_id); qDebug()"device_id:"/support.huaweicloud.com/api-iothub/iot_06_v5_0034.html ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175972766929061.png) **(2)在线调试地址** 接口的在线调试地址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IoTDA&api=ListProperties **(3)设备端响应的数据格式** 帮助文档: https://support.huaweicloud.com/api-iothub/iot_06_v5_3011.html ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648175983338247896.png) **(4)使用总结** 上位机APP向设备端请求查询设备属性时,设备端会收到如下的消息: `$oc/devices/6210e8acde9933029be8facf_dev1/sys/properties/get/request_id=5f359b5c-542f-460e-9f51-85e82150ff4a{"service_id":"DHT11"}` 设备端需要解析这个字符串,得到里面的request_id=5f359b5c-542f-460e-9f51-85e82150ff4a 值。在向服务器回应时,要带上这个请求ID。 设备端响应的主题格式: $oc/devices/{device_id}/sys/properties/get/response/request_id={request_id} 示 例: $oc/devices/6210e8acde9933029be8facf_dev1/sys/properties/get/response/request_id=6c36c85e-68e1-4d01-a2a3-b89f09bd0427 设备端响应的数据格式: {"services": [{"service_id": "gps","properties":{"DHT11_t":12,"DHT11_h":33}}]} 应用端上位机收到设备端的响应数据: "{\"response\":{\"services\":[{\"service_id\":\"temp\",\"properties\":{\"DHT11_t\":13,\"DHT11_h\":33.345}}]}}" **(5)应用端获取设备属性** //查询设备属性 void Widget::Get_device_properties() { //表示获取token function_select=0; QString requestUrl; QNetworkRequest request; //设置请求地址 QUrl url; if(device_id_lis.size()=0) { //显示错误代码 QMessageBox::information(this,"提示","未选择设备,请先获取设备列表\n选择设备后重试.",QMessageBox::Ok,QMessageBox::Ok); return; } //获取token请求地址 requestUrl = QString("https://iotda.%1.myhuaweicloud.com/v5/iot/%2/devices/%3/properties?service_id=%4") .arg(SERVER_ID) .arg(PROJECT_ID) .arg(device_id_lis.at(ui->comboBox->currentIndex())) .arg(service_id); //自己创建的TCP服务器,测试用 //requestUrl="http://10.0.0.6:8080"; //设置数据提交格式 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json")); //设置token request.setRawHeader("X-Auth-Token",Token); //构造请求 url.setUrl(requestUrl); request.setUrl(url); //发送请求 manager->get(request); } **(6)应用端解析数据** //查询设备属性 if(function_select==0) { //解析数据 QJsonParseError json_error; QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error); if(json_error.error == QJsonParseError::NoError) { //判断是否是对象,然后开始解析数据 if(document.isObject()) { QJsonObject obj = document.object(); if(obj.contains("response")) { QJsonObject obj1=obj.take("response").toObject(); if(obj1.contains("services")) { QJsonArray array=obj1.take("services").toArray(); } } } } return; } ## 5.4 上位机开发环境搭建 上位机软件是采用QT开发的,Qt是一个1991年由QtCompany开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。QT在发布 Qt 4.6 的同时,作为 Qt 开发跨平台 IDE 的Qt Creator也发布了更新版本。Qt Creator是一个用于Qt开发的轻量级跨平台集成开发环境。Qt Creator可带来两大关键益处:提供首个专为支持跨平台开发而设计的集成开发环境 (IDE),并确保首次接触Qt框架的开发人员能迅速上手和操作。即使不开发Qt应用程序,Qt Creator也是一个简单易用且功能强大的IDE。 目前QT在嵌入式领域、桌面端都用的非常多,开发桌面,嵌入式的上位机还是非常方便。 嵌入式领域包括: 车机主机、嵌入式Linux设备等。 QT官网: https://resources.qt.io/cn ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/25/1648176069447773344.png) QT5.12.6安装包下载地址: https://download.qt.io/archive/qt/5.12/5.12.6/ QT学习专栏: https://blog.csdn.net/xiaolong1126626497/category_11400392.html QT环境搭建文章:https://xiaolong.blog.csdn.net/article/details/120654599 # 6. 总结 整个项目的实现主要分为两个大部分:1. 设备上云 2. 应用侧的软件开发 (1)设备上云: 目前通过STM32、ESP8266已经完了华为云物联网云平台的连接,ESP8266上云的过程主要是MQTT协议的理解,目前采用的ESP8266没有内置MQTT协议相关的AT指令,需要自己实现MQTT协议,这个过程稍微麻烦一点,需要安装官网的MQTT协议手册拼接结构完成协议构造。对于设备端而言,只要是通信采用标准的MQTT协议,不管连接哪一个物联网云平台,过程是没有多大区别的。 (2)应用层软件开发: 应用侧软件开发主要是方便远程管理设备,目前华为云物联网平台没有提供在线web设计功能、没有提供公版的APP;所以,在设备上云之后,想要方便的对设备的属性进行查看,管理,都需要自己开发上位机才行。
推荐直播
-
全面解析华为云EI-API服务:理论基础与实践应用指南
2024/11/29 周五 18:20-20:20
Alex 华为云学堂技术讲师
本期直播给大家带来的是理论与实践结合的华为云EI-API的服务介绍。从“主要功能,应用场景,实践案例,调用流程”四个维度来深入解析“语音交互API,文字识别API,自然语言处理API,图像识别API及图像搜索API”五大场景下API服务,同时结合实验,来加深开发者对API服务理解。
正在直播 -
企业员工、应届毕业生、在读研究生共探项目实践
2024/12/02 周一 19:00-21:00
姚圣伟 在职软件工程师 昇腾社区优秀开发者 华为云云享专家 HCDG天津地区发起人
大神带你一键了解和掌握LeakyReLU自定义算子在ONNX网络中应用和优化技巧,在线分享如何入门,以及在工作中如何结合实际项目进行学习
即将直播 -
昇腾云服务ModelArts深度解析:理论基础与实践应用指南
2024/12/03 周二 14:30-16:30
Alex 华为云学堂技术讲师
如何快速创建和部署模型,管理全周期AI工作流呢?本期直播聚焦华为昇腾云服务ModelArts一站式AI开发平台功能介绍,同时结合基于ModelArts 的实践性实验,帮助开发者从理论到实验更好地理解和使用ModelArts。
去报名
热门标签