diff --git a/.gitignore b/.gitignore index 69e9da2dc473a8b5ee07fa705de6c112bccf5276..f488f24efa786fc0e98c8fed69fd8a29d2c5ad42 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ build lockzhiner_vision_module_sdk* opencv-mobile-4.10.0-lockzhiner-vision-module* -.vscode \ No newline at end of file +.vscode +Temp +.DS_Store diff --git a/README.md b/README.md index 733af2325cc34f43d0618eb789fbfaa08d23969f..4c39c5ee513cc71c63973c3c31b8c8eb78c5b540 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -

Lockzhiner Vision Module

+

凌智视觉模块(Lockzhiner Vision Module)

-Lockzhiner Vision Module 是福州市凌睿智捷电子有限公司倾力打造的一款高集成度人工智能视觉模块,专为边端人工智能和机器视觉应用而设计,其特色包括: +凌智视觉模块(Lockzhiner Vision Module) 是福州市凌睿智捷电子有限公司倾力打造的一款高集成度人工智能视觉模块,专为边端人工智能和机器视觉应用而设计,其特色包括: * 卓越的计算能力:Lockzhiner Vision Module 搭载单核 ARM Cortex-A7 处理器,并集成了 NEON 和 FPU,以更出色地处理 SIMD 和浮点计算。同时,该模块支持 Int8 量化,内置 0.5 TOPs 的 NPU,足以应对绝大多数的视觉应用场景。 * 广泛的开源适配:Lockzhiner Vision Module 与 PaddleClas、PaddleDetection、PaddleSeg、PaddleOCR 等基于 Paddle 框架的视觉场景库完美适配,并内置了一键启动脚本。配合 AIStudio,用户可以实现一键训练、一键部署,从而极大地减轻了部署负担。 @@ -12,16 +12,16 @@ Lockzhiner Vision Module 是福州市凌睿智捷电子有限公司倾力打造 这一部分教程旨在为你提供一个系统化的学习路径,帮助你快速上手 Lockzhiner Vision Module。通过一系列详细的教程,你将学会如何烧录镜像、连接设备、搭建开发环境和编写简单的程序。 -* [烧录镜像指南](./docs/introductory_tutorial/burn_image.md) -* [连接设备指南](./docs/introductory_tutorial/connect_device_using_ssh.md) +* [凌智视觉模块烧录镜像指南](./docs/introductory_tutorial/burn_image.md) +* [凌智视觉模块连接设备指南](./docs/introductory_tutorial/connect_device_using_ssh.md) 如果你需要开发 Python 程序,请参考以下教程搭建开发环境: -* [Python 开发环境搭建指南](./docs/introductory_tutorial/python_development_environment.md) +* [凌智视觉模块 Python 开发环境搭建指南](./docs/introductory_tutorial/python_development_environment.md) 如果你需要开发 C++ 程序,请参考以下教程搭建开发环境: -* [C++ 开发环境搭建指南](./docs/introductory_tutorial/cpp_development_environment.md) +* [凌智视觉模块 C++ 开发环境搭建指南](./docs/introductory_tutorial/cpp_development_environment.md) * [基于 C++ 编写 Hello World 程序](./example/hello_world/README.md) ## 🔌 外设控制教程 @@ -32,11 +32,11 @@ Lockzhiner Vision Module 拥有丰富的 IO 接口,其接口图片如下图所 为了帮助你快速上手教程,我们提供了一系列的外设控制例程,你可以点击链接快速学习 -* [串口使用指南](./example/periphery/usart/README.md) -* [ADC 使用指南](./example/periphery/adc/README.md) -* [PWM 使用指南](./example/periphery/pwm/README.md) -* [GPIO 使用指南](./example/periphery/gpio/README.md) -* [摄像头使用指南](./example/periphery/capture/README.md) +* [凌智视觉模块串口使用指南](./example/periphery/usart/README.md) +* [凌智视觉模块 ADC 使用指南](./example/periphery/adc/README.md) +* [凌智视觉模块 PWM 使用指南](./example/periphery/pwm/README.md) +* [凌智视觉模块 GPIO 使用指南](./example/periphery/gpio/README.md) +* [凌智视觉模块摄像头使用指南](./example/periphery/capture/README.md) ## 🧠 深度学习视觉部署教程 diff --git a/configs/LZ-MobileNetV2_x0_5.yaml b/configs/LZ-MobileNetV2_x0_5.yaml deleted file mode 100644 index 851af257274d299cefd2c826144af8fe8879273a..0000000000000000000000000000000000000000 --- a/configs/LZ-MobileNetV2_x0_5.yaml +++ /dev/null @@ -1,25 +0,0 @@ -config: - mean: - - 0.5 - - 0.5 - - 0.5 - std: - - 0.5 - - 0.5 - - 0.5 - -load_onnx: - inputs: - - x - input_size_list: - - - - 1 - - 3 - - 224 - - 224 - outputs: - - p2o.save_infer_model/scale_0.tmp_0.0 - -build: - do_quantization: false - dataset: \ No newline at end of file diff --git a/configs/LZ-MobileNetV2_x1_0.yaml b/configs/LZ-MobileNetV2_x1_0.yaml deleted file mode 100644 index 851af257274d299cefd2c826144af8fe8879273a..0000000000000000000000000000000000000000 --- a/configs/LZ-MobileNetV2_x1_0.yaml +++ /dev/null @@ -1,25 +0,0 @@ -config: - mean: - - 0.5 - - 0.5 - - 0.5 - std: - - 0.5 - - 0.5 - - 0.5 - -load_onnx: - inputs: - - x - input_size_list: - - - - 1 - - 3 - - 224 - - 224 - outputs: - - p2o.save_infer_model/scale_0.tmp_0.0 - -build: - do_quantization: false - dataset: \ No newline at end of file diff --git a/configs/LZ-MobileNetV2_x0_25.yaml b/configs/LZ-MobileNetV3_large_x1_0.yaml similarity index 84% rename from configs/LZ-MobileNetV2_x0_25.yaml rename to configs/LZ-MobileNetV3_large_x1_0.yaml index 851af257274d299cefd2c826144af8fe8879273a..12d2f243fc4a4df7b7a820beb85805c22be5ffc1 100644 --- a/configs/LZ-MobileNetV2_x0_25.yaml +++ b/configs/LZ-MobileNetV3_large_x1_0.yaml @@ -18,7 +18,7 @@ load_onnx: - 224 - 224 outputs: - - p2o.save_infer_model/scale_0.tmp_0.0 + - p2o.DequantizeLinear.881 build: do_quantization: false diff --git a/configs/LZ-MobileNetV3_small_x0_35.yaml b/configs/LZ-MobileNetV3_small_x0_35.yaml deleted file mode 100644 index 851af257274d299cefd2c826144af8fe8879273a..0000000000000000000000000000000000000000 --- a/configs/LZ-MobileNetV3_small_x0_35.yaml +++ /dev/null @@ -1,25 +0,0 @@ -config: - mean: - - 0.5 - - 0.5 - - 0.5 - std: - - 0.5 - - 0.5 - - 0.5 - -load_onnx: - inputs: - - x - input_size_list: - - - - 1 - - 3 - - 224 - - 224 - outputs: - - p2o.save_infer_model/scale_0.tmp_0.0 - -build: - do_quantization: false - dataset: \ No newline at end of file diff --git a/configs/LZ-MobileNetV3_small_x0_5.yaml b/configs/LZ-MobileNetV3_small_x0_5.yaml deleted file mode 100644 index 851af257274d299cefd2c826144af8fe8879273a..0000000000000000000000000000000000000000 --- a/configs/LZ-MobileNetV3_small_x0_5.yaml +++ /dev/null @@ -1,25 +0,0 @@ -config: - mean: - - 0.5 - - 0.5 - - 0.5 - std: - - 0.5 - - 0.5 - - 0.5 - -load_onnx: - inputs: - - x - input_size_list: - - - - 1 - - 3 - - 224 - - 224 - outputs: - - p2o.save_infer_model/scale_0.tmp_0.0 - -build: - do_quantization: false - dataset: \ No newline at end of file diff --git a/configs/LZ-MobileNetV3_small_x0_75.yaml b/configs/LZ-MobileNetV3_small_x0_75.yaml deleted file mode 100644 index 851af257274d299cefd2c826144af8fe8879273a..0000000000000000000000000000000000000000 --- a/configs/LZ-MobileNetV3_small_x0_75.yaml +++ /dev/null @@ -1,25 +0,0 @@ -config: - mean: - - 0.5 - - 0.5 - - 0.5 - std: - - 0.5 - - 0.5 - - 0.5 - -load_onnx: - inputs: - - x - input_size_list: - - - - 1 - - 3 - - 224 - - 224 - outputs: - - p2o.save_infer_model/scale_0.tmp_0.0 - -build: - do_quantization: false - dataset: \ No newline at end of file diff --git a/configs/LZ-MobileNetV3_small_x1_0.yaml b/configs/LZ-MobileNetV3_small_x1_0.yaml deleted file mode 100644 index 851af257274d299cefd2c826144af8fe8879273a..0000000000000000000000000000000000000000 --- a/configs/LZ-MobileNetV3_small_x1_0.yaml +++ /dev/null @@ -1,25 +0,0 @@ -config: - mean: - - 0.5 - - 0.5 - - 0.5 - std: - - 0.5 - - 0.5 - - 0.5 - -load_onnx: - inputs: - - x - input_size_list: - - - - 1 - - 3 - - 224 - - 224 - outputs: - - p2o.save_infer_model/scale_0.tmp_0.0 - -build: - do_quantization: false - dataset: \ No newline at end of file diff --git a/docs/introductory_tutorial/burn_image.md b/docs/introductory_tutorial/burn_image.md index 5b6602e55aa7ee36953096c6907bce8765d804c2..c2ae3c0619a19f1cbe5cc41c6ecd65d3120848af 100644 --- a/docs/introductory_tutorial/burn_image.md +++ b/docs/introductory_tutorial/burn_image.md @@ -1,4 +1,4 @@ -

烧录镜像指南

+

凌智视觉模块烧录镜像指南

发布版本:V0.0.1 diff --git a/docs/introductory_tutorial/connect_device_using_ssh.md b/docs/introductory_tutorial/connect_device_using_ssh.md index 3ded352831d9af84f41c89b61b1b12a0f5099938..1980d6d7fa3d3fc7a87574e566c686e57f087dc5 100644 --- a/docs/introductory_tutorial/connect_device_using_ssh.md +++ b/docs/introductory_tutorial/connect_device_using_ssh.md @@ -1,4 +1,4 @@ -

连接设备指南

+

凌智视觉模块连接设备指南

发布版本:V0.0.1 diff --git a/docs/introductory_tutorial/cpp_development_environment.md b/docs/introductory_tutorial/cpp_development_environment.md index 5a93ae30c2497c65dbf23f1a7204de35966deee4..d17471b7c59ebf66820b1580573d1b923ae69709 100644 --- a/docs/introductory_tutorial/cpp_development_environment.md +++ b/docs/introductory_tutorial/cpp_development_environment.md @@ -1,4 +1,4 @@ -

C++ 开发环境搭建指南

+

凌智视觉模块 C++ 开发环境搭建指南

发布版本:V0.0.2 @@ -220,6 +220,7 @@ unzip -qo opencv-mobile-4.10.0-lockzhiner-vision-module.zip -d third_party ```bash cd /LockzhinerVisionModuleWorkSpace/LockzhinerVisionModule +rm -rf third_party/lockzhiner_vision_module_sdk rm -rf lockzhiner_vision_module_sdk.zip wget https://gitee.com/LockzhinerAI/LockzhinerVisionModule/releases/download/v0.0.0/lockzhiner_vision_module_sdk.zip unzip -qo lockzhiner_vision_module_sdk.zip -d third_party diff --git a/docs/introductory_tutorial/python_development_environment.md b/docs/introductory_tutorial/python_development_environment.md index 1399a45b723945daea41728ec641bb49566956b1..6ecd298fd90aae5aa85513e157bf04ced4df076f 100644 --- a/docs/introductory_tutorial/python_development_environment.md +++ b/docs/introductory_tutorial/python_development_environment.md @@ -1,4 +1,4 @@ -

Python 开发环境搭建指南

+

凌智视觉模块 Python 开发环境搭建指南

发布版本:V0.0.0 diff --git a/example/periphery/adc/README.md b/example/periphery/adc/README.md index 48b15138adcf319e96d0c061047c4b8027aacef9..59a429183522fa8d251db2ebcfed42227966f887 100644 --- a/example/periphery/adc/README.md +++ b/example/periphery/adc/README.md @@ -1,8 +1,8 @@ -

ADC 使用指南

+

凌智视觉模块 ADC 使用指南

发布版本:V0.0.0 -日期:2024-08-30 +日期:2024-09-11 文件密级:□绝密 □秘密 □内部资料 ■公开 @@ -25,139 +25,14 @@ | **日期** | **版本** | **作者** | **修改说明** | | :--------- | -------- | -------- | ------------ | -| 2024/08/30 | 0.0.0 | 郑必城 | 初始版本 | +| 2024/09/11 | 0.0.0 | 郑必城 | 初始版本 | ## 1 简介 -作为连接模拟世界与数字世界的桥梁,ADC能够将连续的模拟信号(如温度、压力、声音等)转换为离散的数字信号,使得主控芯片能够处理和分析这些信号。本章节中,我们将教会你如何使用 Lockzhiner Vision Module 读取 ADC 数据。 - -## 2 前期准备 - -在开始这个章节前,请确保你已经按照 [开发环境搭建指南](../../../docs/introductory_tutorial/development_environment.md) 正确配置了开发环境。 - -## 3 API 文档 - -```c++ -/** - * @class ADC - * @brief 这是一个模数转换器(ADC)的抽象类,用于从模拟源读取数据。 - * - * 该类提供基本的ADC操作接口,包括打开ADC设备以及从ADC读取数据。 - * 注意:该ADC不得接入超过1.8V的电压,否则可能会损坏设备。 - */ -class ADC { - public: - /** - * @brief 默认构造函数。 - * - * 初始化ADC类的实例。 - */ - ADC() = default; - - /** - * @brief 默认析构函数。 - * - * 清理ADC类实例使用的资源。 - */ - ~ADC() = default; - - /** - * @brief 打开ADC设备。 - * - * 初始化ADC硬件并准备进行读取操作。 - * @return bool 如果设备成功打开则返回true,否则返回false。 - */ - bool Open(); - - /** - * @brief 从ADC读取数据。 - * - * 从ADC读取当前的模拟值(mV),并将其转换为浮点数形式。 - * 注意:确保ADC未接入超过1.8V的电压。 - * @param[out] adc_data 存储读取到的ADC数据的变量(以浮点数形式)。 - * @return bool 如果成功读取数据则返回true,否则返回false。 - */ - bool Read(float& adc_data); - - private: - float scale_ = 0.0; -}; -``` - -## 4 项目介绍 - -为了方便大家入手,我们做了一个简易的 ADC 例程。该例程可以输出当前的 ADC 数值。 - -```cmake -# CMake最低版本要求 -cmake_minimum_required(VERSION 3.10) - -project(test_adc) - -# 定义项目根目录路径 -set(PROJECT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../..") -# 定义 LockzhinerVisionModule SDK 路径 -set(LockzhinerVisionModule_ROOT_PATH "${PROJECT_ROOT_PATH}/third_party/lockzhiner_vision_module_sdk") -set(LockzhinerVisionModule_DIR "${LockzhinerVisionModule_ROOT_PATH}/lib/cmake/lockzhiner_vision_module") -find_package(LockzhinerVisionModule REQUIRED) - -# 配置 ADC 读取例程 -add_executable(Test-ADC test_adc.cc) -target_include_directories(Test-ADC PRIVATE ${LOCKZHINER_VISION_MODULE_INCLUDE_DIRS}) -target_link_libraries(Test-ADC PRIVATE ${LOCKZHINER_VISION_MODULE_LIBRARIES}) -``` - -读取 ADC 数据的核心代码如下: - -```cpp -#include - -#include - -int main() { - lockzhiner_vision_module::periphery::ADC adc; - if (!adc.Open()) { - std::cout << "Failed to open adc." << std::endl; - return 1; - } - - float adc_data; - if (!adc.Read(adc_data)) { - std::cout << "Failed to read adc data." << std::endl; - return 1; - } - std::cout << "adc_data is " << adc_data << "mv" << std::endl; - return 0; -} -``` - -## 5 编译项目 - -使用 Docker Destop 打开 LockzhinerVisionModule 容器并执行以下命令来编译项目 - -```bash -# 进入 Demo 目录 -cd /LockzhinerVisionModuleWorkSpace/LockzhinerVisionModule/example/periphery/adc - -# 创建编译目录 -rm -rf build && mkdir build && cd build - -# 配置交叉编译工具链 -export TOOLCHAIN_ROOT_PATH=${PWD}/../../../../../arm-rockchip830-linux-uclibcgnueabihf - -# 使用 cmake 配置项目 -cmake -DCMAKE_TOOLCHAIN_FILE=../../../../toolchains/arm-rockchip830-linux-uclibcgnueabihf.toolchain.cmake \ - -DCMAKE_BUILD_TYPE=Release \ - .. - -# 执行编译 -make -j8 -``` - -![](images/build_example.png) - -## 6 正确连接设备 +作为连接模拟世界与数字世界的桥梁,ADC 能够将连续的模拟信号(如温度、压力、声音等)转换为离散的数字信号,使得主控芯片能够处理和分析这些信号。本章节中,我们将教会你如何使用凌智视觉模块读取 ADC 数据。 + +## 2 正确连接设备 > 注意: Lockzhiner Vision Module ADC 引脚最大可承载电压是 1.8V 切忌不要输入超过 1.8V 的电压,否则可能烧板子!!!! @@ -174,23 +49,9 @@ make -j8 ![](images/100mV.png) -## 7 执行 ADC 测试程序 - -参考 [连接设备指南](../../../docs/introductory_tutorial/connect_device_using_ssh.md) 正确连接 Lockzhiner Vision Module 设备。 - -![](../../../docs/introductory_tutorial/images/connect_device_using_ssh/ssh_success.png) - -使用 SFTP 功能将软件上传到 Lockzhiner Vision Module - -![](images/sftp.png) - -在 Lockzhiner Vision Module 上运行以下代码来执行 ADC 测试程序 - -```bash -chmod +x ./Test-ADC -./Test-ADC -``` +## 3 在凌智视觉模块上部署 ADC 例程 -![](images/result.png) +请参考以下教程使用 C++ 或 Python 在凌智视觉模块上部署 ADC 例程: -可以看到有一定的误差,误差一般在10mv以内 \ No newline at end of file +* [凌智视觉模块 ADC C++ 部署指南](./cpp/README.md) +* [凌智视觉模块 ADC Python 部署指南](./python/README.md) \ No newline at end of file diff --git a/example/periphery/adc/CMakeLists.txt b/example/periphery/adc/cpp/CMakeLists.txt similarity index 90% rename from example/periphery/adc/CMakeLists.txt rename to example/periphery/adc/cpp/CMakeLists.txt index e20fae0c956ae5efc1686b9b5a22bc61368eb904..2fe36b8a6bf05519217068eff3e85cede5af7ae1 100644 --- a/example/periphery/adc/CMakeLists.txt +++ b/example/periphery/adc/cpp/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.10) project(test_adc) # 定义项目根目录路径 -set(PROJECT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../..") +set(PROJECT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../..") # 定义 LockzhinerVisionModule SDK 路径 set(LockzhinerVisionModule_ROOT_PATH "${PROJECT_ROOT_PATH}/third_party/lockzhiner_vision_module_sdk") set(LockzhinerVisionModule_DIR "${LockzhinerVisionModule_ROOT_PATH}/lib/cmake/lockzhiner_vision_module") diff --git a/example/periphery/adc/cpp/README.md b/example/periphery/adc/cpp/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6472cf6c2c006aabb5257f8f48c02bea08751922 --- /dev/null +++ b/example/periphery/adc/cpp/README.md @@ -0,0 +1,169 @@ +

凌智视觉模块 ADC C++ 部署指南

+ +发布版本:V0.0.0 + +日期:2024-09-14 + +文件密级:□绝密 □秘密 □内部资料 ■公开 + +--- + +**免责声明** + +本文档按**现状**提供,福州凌睿智捷电子有限公司(以下简称**本公司**)不对本文档中的任何陈述、信息和内容的准确性、可靠性、完整性、适销性、适用性及非侵权性提供任何明示或暗示的声明或保证。本文档仅作为使用指导的参考。 + +由于产品版本升级或其他原因,本文档可能在未经任何通知的情况下不定期更新或修改。 + +**读者对象** + +本教程适用于以下工程师: + +- 技术支持工程师 +- 软件开发工程师 + +**修订记录** + +| **日期** | **版本** | **作者** | **修改说明** | +| :--------- | -------- | -------- | ------------ | +| 2024/09/14 | 0.0.0 | 郑必城 | 初始版本 | + +## 1 简介 + +接下来让我们基于 C++ 来部署 ADC 例程。在开始本章节前: + +- 请确保你已经按照 [开发环境搭建指南](../../../../docs/introductory_tutorial/cpp_development_environment.md) 正确配置了开发环境。 +- 请确保你已经按照 [凌智视觉模块 ADC 使用指南](../README.md) 正确将信号连接到开发板。 + +## 2 API 文档 + +```c++ +/// \class ADCBase +/// \brief ADCBase +/// 类是一个模板类,用于处理特定设备和引脚的模拟数字转换器(ADC)的基础操作。 +/// +/// \template +/// \param device_index ADC 设备编号。 +/// \param in_voltage_index ADC 引脚编号。 +template +class ADCBase { + public: + /// \brief 构造函数,初始化 ADC 设备。 + ADCBase(); + + /// \brief 析构函数,默认实现。 + ~ADCBase() = default; + + /// \brief 从 ADC 读取数据,并将结果存储在提供的引用中。 + /// + /// \param[out] adc_data 存储读取数据的浮点数引用。 + /// \return 读取成功返回 true,否则返回 false。 + bool Read(float& adc_data); + + /// \brief 从 ADC 读取数据,并返回结果。 + /// + /// \return 读取到的 ADC 数据值(mV),如果读取失败则返回 0。 + float Read(); + + private: + // clang-format off + inline const static std::string scale_file_path_ = fmt::format("/sys/bus/iio/devices/iio:device{}/in_voltage_scale", device_index); + inline static float scale_ = 0.0; + inline const static std::string raw_file_path_ = fmt::format("/sys/bus/iio/devices/iio:device{}/in_voltage{}_raw", device_index, in_voltage_index); + // clang-format on +}; + +/// \brief 定义 ADCIN1 别名。 +using ADCIN1 = ADCBase<0, 1>; +``` + +## 3 项目介绍 + +为了方便大家入手,我们做了一个简易的 ADC 例程。该例程可以输出当前的 ADC 数值。 + +```cmake +# CMake最低版本要求 +cmake_minimum_required(VERSION 3.10) + +project(test_adc) + +# 定义项目根目录路径 +set(PROJECT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../..") +# 定义 LockzhinerVisionModule SDK 路径 +set(LockzhinerVisionModule_ROOT_PATH "${PROJECT_ROOT_PATH}/third_party/lockzhiner_vision_module_sdk") +set(LockzhinerVisionModule_DIR "${LockzhinerVisionModule_ROOT_PATH}/lib/cmake/lockzhiner_vision_module") +find_package(LockzhinerVisionModule REQUIRED) + +# 配置 ADC 读取例程 +add_executable(Test-ADC test_adc.cc) +target_include_directories(Test-ADC PRIVATE ${LOCKZHINER_VISION_MODULE_INCLUDE_DIRS}) +target_link_libraries(Test-ADC PRIVATE ${LOCKZHINER_VISION_MODULE_LIBRARIES}) +``` + +读取 ADC 数据的核心代码如下: + +```cpp +#include + +#include + +int main() { + lockzhiner_vision_module::periphery::ADCIN1 adc; + float adc_data; + if (!adc.Read(adc_data)) { + std::cout << "Failed to read adc data." << std::endl; + return 1; + } + std::cout << "adc_data is " << adc_data << "mV" << std::endl; + return 0; +} +``` + +## 4 编译项目 + +使用 Docker Destop 打开 LockzhinerVisionModule 容器并执行以下命令来编译项目 + +```bash +# 进入 Demo 目录 +cd /LockzhinerVisionModuleWorkSpace/LockzhinerVisionModule/example/periphery/adc/cpp + +# 创建编译目录 +rm -rf build && mkdir build && cd build + +# 配置交叉编译工具链 +export TOOLCHAIN_ROOT_PATH=${PWD}/../../../../../../arm-rockchip830-linux-uclibcgnueabihf + +# 使用 cmake 配置项目 +cmake -DCMAKE_TOOLCHAIN_FILE=../../../../../toolchains/arm-rockchip830-linux-uclibcgnueabihf.toolchain.cmake \ + -DCMAKE_BUILD_TYPE=Release \ + .. + +# 执行编译 +make -j8 +``` + +![](images/build_example.png) + +## 5 执行 ADC 测试程序 + +参考 [连接设备指南](../../../../docs/introductory_tutorial/connect_device_using_ssh.md) 正确连接 Lockzhiner Vision Module 设备。 + +![](../../../../docs/introductory_tutorial/images/connect_device_using_ssh/ssh_success.png) + +使用 SFTP 功能将软件上传到 Lockzhiner Vision Module + +![](images/sftp.png) + +在 Lockzhiner Vision Module 上运行以下代码来执行 ADC 测试程序 + +```bash +chmod +x ./Test-ADC +./Test-ADC +``` + +![](images/result.png) + +可以看到有一定的误差,误差一般在10mv以内 + +## 6 其他 + +如果你需要使用 Python 来部署 ADC 例程请参考[凌智视觉模块 ADC Python 部署指南](../python/README.md)。 diff --git a/example/periphery/adc/images/build_example.png b/example/periphery/adc/cpp/images/build_example.png similarity index 100% rename from example/periphery/adc/images/build_example.png rename to example/periphery/adc/cpp/images/build_example.png diff --git a/example/periphery/adc/images/result.png b/example/periphery/adc/cpp/images/result.png similarity index 100% rename from example/periphery/adc/images/result.png rename to example/periphery/adc/cpp/images/result.png diff --git a/example/periphery/adc/images/sftp.png b/example/periphery/adc/cpp/images/sftp.png similarity index 100% rename from example/periphery/adc/images/sftp.png rename to example/periphery/adc/cpp/images/sftp.png diff --git a/example/periphery/adc/test_adc.cc b/example/periphery/adc/cpp/test_adc.cc similarity index 67% rename from example/periphery/adc/test_adc.cc rename to example/periphery/adc/cpp/test_adc.cc index 733d873193b63b8cfd2f3e0b9bcdfa12251a86ae..363e22d1879ec0b01889d5fae2d6a362547e7c23 100644 --- a/example/periphery/adc/test_adc.cc +++ b/example/periphery/adc/cpp/test_adc.cc @@ -3,12 +3,7 @@ #include int main() { - lockzhiner_vision_module::periphery::ADC adc; - if (!adc.Open()) { - std::cout << "Failed to open adc." << std::endl; - return 1; - } - + lockzhiner_vision_module::periphery::ADCIN1 adc; float adc_data; if (!adc.Read(adc_data)) { std::cout << "Failed to read adc data." << std::endl; diff --git a/example/periphery/adc/python/README.md b/example/periphery/adc/python/README.md new file mode 100644 index 0000000000000000000000000000000000000000..40a1f3d10cb9b6c6914c03b1fa352c8940e3c4a1 --- /dev/null +++ b/example/periphery/adc/python/README.md @@ -0,0 +1,112 @@ +

凌智视觉模块 ADC Python 部署指南

+ +发布版本:V0.0.0 + +日期:2024-09-14 + +文件密级:□绝密 □秘密 □内部资料 ■公开 + +--- + +**免责声明** + +本文档按**现状**提供,福州凌睿智捷电子有限公司(以下简称**本公司**)不对本文档中的任何陈述、信息和内容的准确性、可靠性、完整性、适销性、适用性及非侵权性提供任何明示或暗示的声明或保证。本文档仅作为使用指导的参考。 + +由于产品版本升级或其他原因,本文档可能在未经任何通知的情况下不定期更新或修改。 + +**读者对象** + +本教程适用于以下工程师: + +- 技术支持工程师 +- 软件开发工程师 + +**修订记录** + +| **日期** | **版本** | **作者** | **修改说明** | +| :--------- | -------- | -------- | ------------ | +| 2024/09/14 | 0.0.0 | 郑必城 | 初始版本 | + +## 1 简介 + +接下来让我们基于 Python 来部署 ADC 例程。在开始本章节前: + +- 请确保你已经按照 [开发环境搭建指南](../../../../docs/introductory_tutorial/python_development_environment.md) 正确配置了开发环境。 +- 请确保你已经按照 [凌智视觉模块 ADC 使用指南](../README.md) 正确将信号连接到开发板。 + +## 2 API 文档 + +```python +class ADCBase: + """ + @brief ADC 基类,用于初始化和管理 ADC 对象 + + 该类提供了一个基础接口来读取 ADC 的数据。通过传入具体的 ADC 类, + 该类能够实例化并调用具体 ADC 类的读取方法,从而实现对不同ADC设备的统一访问。 + + @param adc_class: 具体的 ADC 类,该类必须包含一个 read 方法用于读取ADC数据 + """ + + def __init__(self, adc_class): + """ + @brief 构造函数,用于初始化 ADC 对象 + + 在实例化 ADCBase 对象时,会调用此构造函数来创建具体的 ADC 类实例,并将其保存在成员变量 self.adc 中。 + + @param adc_class: 具体的 ADC 类,用于创建 ADC 实例 + """ + self.adc = adc_class() + + def read(self): + """ + @brief 读取ADC数据 + + 该方法调用具体的 ADC 实例的 read 方法,返回读取到的 ADC 数据。 + + @return 读取到的 ADC 数据 + """ + return self.adc.read() + + +class ADCIN1(ADCBase): + def __init__(self): + super().__init__(periphery.ADCIN1) +``` + +## 3 项目介绍 + +为了方便大家入手,我们做了一个简易的 ADC 例程。该例程可以输出当前的 ADC 数值。 + +```python +from lockzhiner_vision_module.periphery import ADCIN1 + + +if __name__ == "__main__": + adc = ADCIN1() + print(f"adc_data is {adc.read()} mV") +``` + +## 4 执行 ADC 测试程序 + +参考 [连接设备指南](../../../../docs/introductory_tutorial/connect_device_using_ssh.md) 正确连接 Lockzhiner Vision Module 设备。 + +![](../../../../docs/introductory_tutorial/images/connect_device_using_ssh/ssh_success.png) + +使用 SFTP 功能将 Python 代码上传到 Lockzhiner Vision Module + +![](images/sftp.png) + +在 Lockzhiner Vision Module 上运行以下代码来执行 ADC 测试程序 + +```bash +chmod +x ./Test-ADC +./Test-ADC +``` + +![](images/result.png) + +可以看到有一定的误差,误差一般在10mv以内 + +## 5 其他 + +如果你需要使用 C++ 来部署 ADC 例程请参考[凌智视觉模块 ADC C++ 部署指南](../cpp/README.md)。 \ No newline at end of file diff --git a/example/periphery/adc/python/images/result.png b/example/periphery/adc/python/images/result.png new file mode 100644 index 0000000000000000000000000000000000000000..a804622dff7ce8f72c1beed375ef1146eab2a835 Binary files /dev/null and b/example/periphery/adc/python/images/result.png differ diff --git a/example/periphery/adc/python/images/sftp.png b/example/periphery/adc/python/images/sftp.png new file mode 100644 index 0000000000000000000000000000000000000000..48b84e586b1c78e8fdc4294157431cf2473b191e Binary files /dev/null and b/example/periphery/adc/python/images/sftp.png differ diff --git a/example/periphery/adc/python/test_adc.py b/example/periphery/adc/python/test_adc.py new file mode 100644 index 0000000000000000000000000000000000000000..7a2d3f2fb509d2b34f195cab35e2be1beae7e3f6 --- /dev/null +++ b/example/periphery/adc/python/test_adc.py @@ -0,0 +1,6 @@ +from lockzhiner_vision_module.periphery import ADCIN1 + + +if __name__ == "__main__": + adc = ADCIN1() + print(f"adc_data is {adc.read()} mV") \ No newline at end of file diff --git a/example/periphery/gpio/README.md b/example/periphery/gpio/README.md index 3d7b28765de3adbe9c9f25033faf49519a8d9419..c0d31b1c92b57343b6000a5d0f387b69c24275ad 100644 --- a/example/periphery/gpio/README.md +++ b/example/periphery/gpio/README.md @@ -1,8 +1,8 @@ -

GPIO 使用指南

+

凌智视觉模块 GPIO 使用指南

发布版本:V0.0.0 -日期:2024-09-03 +日期:2024-09-14 文件密级:□绝密 □秘密 □内部资料 ■公开 @@ -25,273 +25,42 @@ | **日期** | **版本** | **作者** | **修改说明** | | :--------- | -------- | -------- | ------------ | -| 2024/09/03 | 0.0.0 | 郑必城 | 初始版本 | - +| 2024/09/14 | 0.0.0 | 郑必城 | 初始版本 | ## 1 简介 GPIO(General Purpose Input/Output,通用输入/输出)是一种在嵌入式系统和微控制器上常用的接口,用于实现基本的输入输出操作。这些引脚可以被配置为输入模式,用于读取外部信号(如按钮按下、传感器数据等),或者配置为输出模式,用于控制外部设备(如LED灯、电机等)。本章节中,我们将教会你如何使用 Lockzhiner Vision Module 上的 GPIO 输出和读取电平。 -## 2 前期准备 - -在开始这个章节前,请确保你已经按照 [开发环境搭建指南](../../../docs/introductory_tutorial/development_environment.md) 正确配置了开发环境。 - -## 3 API 文档 - -```c++ -/// @enum GPIOMode -/// @brief GPIO引脚的工作模式枚举。 -enum class GPIOMode { - /// @brief 输入模式。 - IN, - /// @brief 输出模式。 - OUT, -}; - -/// @enum GPIOState -/// @brief GPIO引脚的状态枚举。 -enum class GPIOState { - /// @brief 高电平状态。 - HIGH = 1, - /// @brief 低电平状态。 - LOW = 0, -}; - -/// @template GPIO_Base -/// @brief GPIO基类模板,用于表示和操作GPIO引脚。 -/// @param bank GPIO引脚所属的银行(或组)。 -/// @param port_char GPIO引脚所在的端口字符('A' - 'Z')。 -/// @param pin GPIO引脚号。 -template -class GPIO_Base { - public: - GPIO_Base(); - ~GPIO_Base(); - - /// @brief 配置GPIO引脚的工作模式。 - /// @param mode 要设置的工作模式(输入或输出)。 - /// @return 配置是否成功。 - bool Config(GPIOMode mode); - - /// @brief 写入GPIO引脚的状态。 - /// @param state 要写入的状态(高电平或低电平)。 - /// @return 写入是否成功。 - bool Write(GPIOState state); - - /// @brief 读取GPIO引脚的状态。 - /// @param[out] state 读取到的状态(高电平或低电平)。 - /// @return 读取是否成功。 - bool Read(GPIOState& state); - - private: - // clang-format off - inline constexpr static uint32_t gpio_index_ = (32 * bank + 8 * (port_char - 'A') + pin); - inline const static std::string direction_file_path_ = fmt::format("/sys/class/gpio/gpio{}/direction", gpio_index_); - inline const static std::string value_file_path_ = fmt::format("/sys/class/gpio/gpio{}/value", gpio_index_); - // clang-format on -}; - -/******************** GPIO_0XX ********************/ -template -using GPIO_0_Base = GPIO_Base<0, port_char, pin>; -template -using GPIO_0A_Base = GPIO_0_Base<'A', pin>; -using GPIO_0A0 = GPIO_0A_Base<0>; -/******************** GPIO_0XX ********************/ - -/******************** GPIO_1XX ********************/ -template -using GPIO_1_Base = GPIO_Base<1, port_char, pin>; -template -using GPIO_1C_Base = GPIO_0_Base<'C', pin>; -using GPIO_1C7 = GPIO_1C_Base<7>; -/******************** GPIO_1XX ********************/ -``` - -## 3 项目介绍 - -为了方便大家入手,我们将项目拆分为 GPIO 输出电平和 GPIO 输入电平两个部分,他们共用一个 CMake 文件。 - -```cmake -# CMake最低版本要求 -cmake_minimum_required(VERSION 3.10) - -project(test_gpio) - -# 定义项目根目录路径 -set(PROJECT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../..") -# 定义 LockzhinerVisionModule SDK 路径 -set(LockzhinerVisionModule_ROOT_PATH "${PROJECT_ROOT_PATH}/third_party/lockzhiner_vision_module_sdk") -set(LockzhinerVisionModule_DIR "${LockzhinerVisionModule_ROOT_PATH}/lib/cmake/lockzhiner_vision_module") -find_package(LockzhinerVisionModule REQUIRED) - -# 配置 GPIO 输出 Demo -add_executable(Test-GPIO-Write test_gpio_write.cc) -target_include_directories(Test-GPIO-Write PRIVATE ${LOCKZHINER_VISION_MODULE_INCLUDE_DIRS}) -target_link_libraries(Test-GPIO-Write PRIVATE ${LOCKZHINER_VISION_MODULE_LIBRARIES}) - -# 配置 GPIO 读取 Demo -add_executable(Test-GPIO-Read test_gpio_read.cc) -target_include_directories(Test-GPIO-Read PRIVATE ${LOCKZHINER_VISION_MODULE_INCLUDE_DIRS}) -target_link_libraries(Test-GPIO-Read PRIVATE ${LOCKZHINER_VISION_MODULE_LIBRARIES}) -``` - -GPIO 输入电平的核心代码如下: - -```cpp -#include - -#include -#include - -int main() { - lockzhiner_vision_module::periphery::GPIO_0A0 gpio_0A0; - - if (!gpio_0A0.Config(lockzhiner_vision_module::periphery::GPIOMode::IN)) { - std::cout << "Failed to config gpio mode" << std::endl; - return 1; - } - - lockzhiner_vision_module::periphery::GPIOState state; - if (!gpio_0A0.Read(state)) { - std::cout << "Failed to read gpio mode" << std::endl; - return 1; - } - - std::cout << "state is " << static_cast(state) << std::endl; - return 0; -} -``` - -GPIO 输出电平的核心代码如下: - -```cpp -#include - -#include -#include - -int main() { - lockzhiner_vision_module::periphery::GPIO_0A0 gpio_0A0; - - if (!gpio_0A0.Config(lockzhiner_vision_module::periphery::GPIOMode::OUT)) { - std::cout << "Failed to config gpio mode" << std::endl; - return 1; - } - - if (!gpio_0A0.Write(lockzhiner_vision_module::periphery::GPIOState::HIGH)) { - std::cout << "Failed to config gpio mode" << std::endl; - return 1; - } - - for (int i = 0; i < 10; i++) { - std::cout << "Wait: " << i << "/" << 10 << std::endl; - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - - if (!gpio_0A0.Write(lockzhiner_vision_module::periphery::GPIOState::LOW)) { - std::cout << "Failed to config gpio mode" << std::endl; - return 1; - } - - return 0; -} -``` - -## 4 编译项目 - -使用 Docker Destop 打开 LockzhinerVisionModule 容器并执行以下命令来编译项目 - -```bash -# 进入 Demo 目录 -cd /LockzhinerVisionModuleWorkSpace/LockzhinerVisionModule/example/periphery/gpio - -# 创建编译目录 -rm -rf build && mkdir build && cd build - -# 配置交叉编译工具链 -export TOOLCHAIN_ROOT_PATH=${PWD}/../../../../../arm-rockchip830-linux-uclibcgnueabihf - -# 使用 cmake 配置项目 -cmake -DCMAKE_TOOLCHAIN_FILE=../../../../toolchains/arm-rockchip830-linux-uclibcgnueabihf.toolchain.cmake \ - -DCMAKE_BUILD_TYPE=Release \ - .. - -# 执行编译 -make -j8 -``` - -![](images/build_example.png) - -## 5 上传测试例程 - -参考 [连接设备指南](../../../docs/introductory_tutorial/connect_device_using_ssh.md) 正确连接 Lockzhiner Vision Module 设备。 - -![](../../../docs/introductory_tutorial/images/connect_device_using_ssh/ssh_success.png) - -使用 SFTP 功能将软件上传到 Lockzhiner Vision Module - -![](images/sftp.png) - -## 6 执行 GPIO 测试程序 - -### 6.1 测试 GPIO 输出电平 - -为了方便调试,我们这里使用 **示波器** 进行调试,请正确的将 Lockzhiner Vision Module 的引脚按照以下方式连接 - -* LockzhinerVisionModule GPIO_0A0 <-> Input IO -* LockzhinerVisionModule GND <-> Input GND +## 2 正确连接设备 板子上的引脚丝印较小,如果看不清引脚信息,可以参考下图 ![](../../../images/periphery.png) -在 Lockzhiner Vision Module 上运行以下代码来执行 GPIO 输出电平程序 - -```bash -chmod +x ./Test-GPIO-Write -./Test-GPIO-Write -``` +### 2.1 测试 GPIO 输出模式 -查看示波器可以看到,GPIO_0A0 输出了 3.4V 左右的电压 +测试 GPIO 输出模式时,我们使用 **示波器** 进行调试,请正确的将 Lockzhiner Vision Module 的引脚按照以下方式连接 -![](images/show_0.png) +- LockzhinerVisionModule GPIO_0A0 <-> Input IO +- LockzhinerVisionModule GND <-> Input GND -电压持续 10S 后恢复了正常 - -![](images/show_1.png) - -### 6.2 测试 GPIO 输入高电平程序 +### 2.2 测试 GPIO 输入模式(输入高电平) 为了方便调试,我们这里使用 **3V3 引脚** 进行调试,请正确的将 Lockzhiner Vision Module 的引脚按照以下方式连接 -* LockzhinerVisionModule GPIO_0A0 <-> LockzhinerVisionModule 3V3 - -在 Lockzhiner Vision Module 上运行以下代码来执行 GPIO 接收程序 - -```bash -chmod +x ./Test-GPIO-Read -./Test-GPIO-Read -``` - -可以看到,在接高电平引脚的情况下,引脚的状态信息为 1 - -![](images/show_2.png) +- LockzhinerVisionModule GPIO_0A0 <-> LockzhinerVisionModule 3V3 -### 6.3 测试 GPIO 输入低电平程序 +### 2.3 测试 GPIO 输入模式(输入低电平) 为了方便调试,我们这里使用 **GND 引脚** 进行调试,请正确的将 Lockzhiner Vision Module 的引脚按照以下方式连接 -* LockzhinerVisionModule GPIO_0A0 <-> LockzhinerVisionModule GND +- LockzhinerVisionModule GPIO_0A0 <-> LockzhinerVisionModule GND 在 Lockzhiner Vision Module 上运行以下代码来执行 GPIO 接收程序 -```bash -export LD_LIBRARY_PATH=${PWD}:$LD_LIBRARY_PATH -chmod +x ./Test-GPIO-Read -./Test-GPIO-Read -``` +## 3 在凌智视觉模块上部署 ADC 例程 -可以看到,在低电平引脚的情况下,引脚的状态信息为 0 +请参考以下教程使用 C++ 或 Python 在凌智视觉模块上部署 GPIO 例程: -![](images/show_3.png) \ No newline at end of file +- [凌智视觉模块 GPIO C++ 部署指南](./cpp/README.md) +- [凌智视觉模块 GPIO Python 部署指南](./python/README.md) diff --git a/example/periphery/gpio/CMakeLists.txt b/example/periphery/gpio/cpp/CMakeLists.txt similarity index 93% rename from example/periphery/gpio/CMakeLists.txt rename to example/periphery/gpio/cpp/CMakeLists.txt index e188f69bf11ebf5106f6337120f52ce4f22ca5ee..070fc27344fe946b138e40a1ff7b073b4a908849 100644 --- a/example/periphery/gpio/CMakeLists.txt +++ b/example/periphery/gpio/cpp/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.10) project(test_gpio) # 定义项目根目录路径 -set(PROJECT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../..") +set(PROJECT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../..") # 定义 LockzhinerVisionModule SDK 路径 set(LockzhinerVisionModule_ROOT_PATH "${PROJECT_ROOT_PATH}/third_party/lockzhiner_vision_module_sdk") set(LockzhinerVisionModule_DIR "${LockzhinerVisionModule_ROOT_PATH}/lib/cmake/lockzhiner_vision_module") diff --git a/example/periphery/gpio/cpp/README.md b/example/periphery/gpio/cpp/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3c544e36a8f0cd242f3795b153e9dec5f8aaa816 --- /dev/null +++ b/example/periphery/gpio/cpp/README.md @@ -0,0 +1,298 @@ +

凌智视觉模块 GPIO C++ 部署指南

+ +发布版本:V0.0.0 + +日期:2024-09-14 + +文件密级:□绝密 □秘密 □内部资料 ■公开 + +--- + +**免责声明** + +本文档按**现状**提供,福州凌睿智捷电子有限公司(以下简称**本公司**)不对本文档中的任何陈述、信息和内容的准确性、可靠性、完整性、适销性、适用性及非侵权性提供任何明示或暗示的声明或保证。本文档仅作为使用指导的参考。 + +由于产品版本升级或其他原因,本文档可能在未经任何通知的情况下不定期更新或修改。 + +**读者对象** + +本教程适用于以下工程师: + +- 技术支持工程师 +- 软件开发工程师 + +**修订记录** + +| **日期** | **版本** | **作者** | **修改说明** | +| :--------- | -------- | -------- | ------------ | +| 2024/09/14 | 0.0.0 | 郑必城 | 初始版本 | + +## 1 简介 + +接下来让我们基于 C++ 来部署 GPIO 例程。在开始本章节前: + +- 请确保你已经按照 [开发环境搭建指南](../../../../docs/introductory_tutorial/cpp_development_environment.md) 正确配置了开发环境。 +- 请确保你已经按照 [凌智视觉模块 GPIO 使用指南](../README.md) 正确将信号连接到开发板。 + +## 2 API 文档 + +```c++ +/// \enum GPIOMode +/// \brief GPIO 模式枚举类 +/// +/// 定义 GPIO 的模式,包括输入(IN)和输出(OUT)。 +enum class GPIOMode { + IN, ///< 输入模式 + OUT, ///< 输出模式 +}; + +/// \enum GPIOState +/// \brief GPIO 状态枚举类 +/// +/// 定义 GPIO 的状态,包括错误(ERROR)、高电平(HIGH)和低电平(LOW)。 +enum class GPIOState { + ERROR = 2, ///< 错误状态 + HIGH = 1, ///< 高电平状态 + LOW = 0, ///< 低电平状态 +}; + +/// \class GPIOBase +/// \brief GPIO 基础类模板 +/// +/// \tparam bank GPIO 端口集合(0-31) +/// \tparam port_char 端口字符('A'-'D') +/// \tparam pin GPIO 引脚(0-7) +/// +/// 该模板类提供了对 GPIO 引脚的基本操作,包括配置模式、写入状态、读取状态等。 +template +class GPIOBase { + public: + /// \brief 构造函数,初始化 GPIO 并导出 GPIO 引脚。 + GPIOBase(); + + /// \brief 析构函数,取消导出 GPIO 引脚。 + ~GPIOBase(); + + /// \brief 配置 GPIO 模式 + /// + /// \param mode 要设置的 GPIO 模式 + /// \return 操作成功返回 true,否则返回 false。 + bool Config(GPIOMode mode); + + /// \brief 写入 GPIO 状态 + /// + /// \param state 要设置的 GPIO 状态 + /// \return 操作成功返回 true,否则返回 false。 + bool Write(GPIOState state); + + /// \brief 读取 GPIO 状态 + /// + /// \param state 用于存储读取到的 GPIO 状态 + /// \return 读取成功返回 true,否则返回 false。 + bool Read(GPIOState& state); + + /// \brief 读取 GPIO 状态 + /// + /// \return 返回读取到的 GPIO 状态。 + GPIOState Read(); + + private: + // clang-format off + inline constexpr static uint32_t gpio_index_ = (32 * bank + 8 * (port_char - 'A') + pin); + inline const static std::string direction_file_path_ = fmt::format("/sys/class/gpio/gpio{}/direction", gpio_index_); + inline const static std::string value_file_path_ = fmt::format("/sys/class/gpio/gpio{}/value", gpio_index_); + // clang-format on +}; + +/******************** GPIO0XX ********************/ +using GPIO0A0 = GPIOBase<0, 'A', 0>; +/******************** GPIO0XX ********************/ + +/******************** GPIO1XX ********************/ +using GPIO1C7 = GPIOBase<1, 'C', 7>; +/******************** GPIO1XX ********************/ + +/******************** GPIO2XX ********************/ +using GPIO2A0 = GPIOBase<2, 'A', 0>; +using GPIO2A1 = GPIOBase<2, 'A', 1>; +using GPIO2A2 = GPIOBase<2, 'A', 2>; +using GPIO2A3 = GPIOBase<2, 'A', 3>; +using GPIO2A4 = GPIOBase<2, 'A', 4>; +using GPIO2A5 = GPIOBase<2, 'A', 5>; +/******************** GPIO2XX ********************/ +``` + +## 3 项目介绍 + +为了方便大家入手,我们将项目拆分为**测试 GPIO 输出模式**和**测试 GPIO 输入模式**两个例程,他们共用一个 CMake 文件。 + +```cmake +# CMake最低版本要求 +cmake_minimum_required(VERSION 3.10) + +project(test_gpio) + +# 定义项目根目录路径 +set(PROJECT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../..") +# 定义 LockzhinerVisionModule SDK 路径 +set(LockzhinerVisionModule_ROOT_PATH "${PROJECT_ROOT_PATH}/third_party/lockzhiner_vision_module_sdk") +set(LockzhinerVisionModule_DIR "${LockzhinerVisionModule_ROOT_PATH}/lib/cmake/lockzhiner_vision_module") +find_package(LockzhinerVisionModule REQUIRED) + +# 配置 GPIO 输出 Demo +add_executable(Test-GPIO-Write test_gpio_write.cc) +target_include_directories(Test-GPIO-Write PRIVATE ${LOCKZHINER_VISION_MODULE_INCLUDE_DIRS}) +target_link_libraries(Test-GPIO-Write PRIVATE ${LOCKZHINER_VISION_MODULE_LIBRARIES}) + +# 配置 GPIO 读取 Demo +add_executable(Test-GPIO-Read test_gpio_read.cc) +target_include_directories(Test-GPIO-Read PRIVATE ${LOCKZHINER_VISION_MODULE_INCLUDE_DIRS}) +target_link_libraries(Test-GPIO-Read PRIVATE ${LOCKZHINER_VISION_MODULE_LIBRARIES}) +``` + +测试 GPIO 输入模式的核心代码如下: + +```cpp +#include + +#include +#include + +int main() { + lockzhiner_vision_module::periphery::GPIO0A0 gpio; + + if (!gpio.Config(lockzhiner_vision_module::periphery::GPIOMode::IN)) { + std::cout << "Failed to config gpio mode" << std::endl; + return 1; + } + + lockzhiner_vision_module::periphery::GPIOState state; + if (!gpio.Read(state)) { + std::cout << "Failed to read gpio mode" << std::endl; + return 1; + } + + std::cout << "state is " << static_cast(state) << std::endl; + return 0; +} +``` + +测试 GPIO 输出模式的核心代码如下: + +```cpp +#include + +#include +#include + +int main() { + lockzhiner_vision_module::periphery::GPIO0A0 gpio; + + if (!gpio.Config(lockzhiner_vision_module::periphery::GPIOMode::OUT)) { + std::cout << "Failed to config gpio mode" << std::endl; + return 1; + } + + if (!gpio.Write(lockzhiner_vision_module::periphery::GPIOState::HIGH)) { + std::cout << "Failed to config gpio mode" << std::endl; + return 1; + } + + for (int i = 0; i < 10; i++) { + std::cout << "Wait: " << i << "/" << 10 << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + if (!gpio.Write(lockzhiner_vision_module::periphery::GPIOState::LOW)) { + std::cout << "Failed to config gpio mode" << std::endl; + return 1; + } + + return 0; +} +``` + +## 4 编译项目 + +使用 Docker Destop 打开 LockzhinerVisionModule 容器并执行以下命令来编译项目 + +```bash +# 进入 Demo 目录 +cd /LockzhinerVisionModuleWorkSpace/LockzhinerVisionModule/example/periphery/gpio + +# 创建编译目录 +rm -rf build && mkdir build && cd build + +# 配置交叉编译工具链 +export TOOLCHAIN_ROOT_PATH=${PWD}/../../../../../../arm-rockchip830-linux-uclibcgnueabihf + +# 使用 cmake 配置项目 +cmake -DCMAKE_TOOLCHAIN_FILE=../../../../../toolchains/arm-rockchip830-linux-uclibcgnueabihf.toolchain.cmake \ + -DCMAKE_BUILD_TYPE=Release \ + .. + +# 执行编译 +make -j8 +``` + +![](images/build_example.png) + +## 5 上传测试例程 + +参考 [连接设备指南](../../../../docs/introductory_tutorial/connect_device_using_ssh.md) 正确连接 Lockzhiner Vision Module 设备。 + +![](../../../../docs/introductory_tutorial/images/connect_device_using_ssh/ssh_success.png) + +使用 SFTP 功能将软件上传到 Lockzhiner Vision Module + +![](images/sftp.png) + +## 6 执行 GPIO 测试程序 + +### 6.1 测试 GPIO 输出模式 + +在 Lockzhiner Vision Module 上运行以下代码来执行 GPIO 输出电平程序 + +```bash +chmod +x ./Test-GPIO-Write +./Test-GPIO-Write +``` + +查看示波器可以看到,GPIO_0A0 输出了 3.4V 左右的电压 + +![](images/show_0.png) + +电压持续 10S 后恢复了正常 + +![](images/show_1.png) + +### 6.2 测试 GPIO 输入模式(输入高电平) + +在 Lockzhiner Vision Module 上运行以下代码来执行 GPIO 接收程序 + +```bash +chmod +x ./Test-GPIO-Read +./Test-GPIO-Read +``` + +可以看到,在接高电平引脚的情况下,引脚的状态信息为 1 + +![](images/show_2.png) + +### 6.3 测试 GPIO 输入模式(输入低电平) + +在 Lockzhiner Vision Module 上运行以下代码来执行 GPIO 接收程序 + +```bash +export LD_LIBRARY_PATH=${PWD}:$LD_LIBRARY_PATH +chmod +x ./Test-GPIO-Read +./Test-GPIO-Read +``` + +可以看到,在低电平引脚的情况下,引脚的状态信息为 0 + +![](images/show_3.png) + +## 7 其他 + +如果你需要使用 Python 来部署 ADC 例程请参考[凌智视觉模块 ADC Python 部署指南](../python/README.md)。 diff --git a/example/periphery/gpio/images/build_example.png b/example/periphery/gpio/cpp/images/build_example.png similarity index 100% rename from example/periphery/gpio/images/build_example.png rename to example/periphery/gpio/cpp/images/build_example.png diff --git a/example/periphery/gpio/images/sftp.png b/example/periphery/gpio/cpp/images/sftp.png similarity index 100% rename from example/periphery/gpio/images/sftp.png rename to example/periphery/gpio/cpp/images/sftp.png diff --git a/example/periphery/gpio/images/show_0.png b/example/periphery/gpio/cpp/images/show_0.png similarity index 100% rename from example/periphery/gpio/images/show_0.png rename to example/periphery/gpio/cpp/images/show_0.png diff --git a/example/periphery/gpio/images/show_1.png b/example/periphery/gpio/cpp/images/show_1.png similarity index 100% rename from example/periphery/gpio/images/show_1.png rename to example/periphery/gpio/cpp/images/show_1.png diff --git a/example/periphery/gpio/images/show_2.png b/example/periphery/gpio/cpp/images/show_2.png similarity index 100% rename from example/periphery/gpio/images/show_2.png rename to example/periphery/gpio/cpp/images/show_2.png diff --git a/example/periphery/gpio/images/show_3.png b/example/periphery/gpio/cpp/images/show_3.png similarity index 100% rename from example/periphery/gpio/images/show_3.png rename to example/periphery/gpio/cpp/images/show_3.png diff --git a/example/periphery/gpio/test_gpio_read.cc b/example/periphery/gpio/cpp/test_gpio_read.cc similarity index 71% rename from example/periphery/gpio/test_gpio_read.cc rename to example/periphery/gpio/cpp/test_gpio_read.cc index 485ab49907b2c4ded4f8ba70436c24a1ee3c5736..3cb8a473295d10c7caccd139e4b17832f6105ba5 100644 --- a/example/periphery/gpio/test_gpio_read.cc +++ b/example/periphery/gpio/cpp/test_gpio_read.cc @@ -4,15 +4,15 @@ #include int main() { - lockzhiner_vision_module::periphery::GPIO_0A0 gpio_0A0; + lockzhiner_vision_module::periphery::GPIO0A0 gpio; - if (!gpio_0A0.Config(lockzhiner_vision_module::periphery::GPIOMode::IN)) { + if (!gpio.Config(lockzhiner_vision_module::periphery::GPIOMode::IN)) { std::cout << "Failed to config gpio mode" << std::endl; return 1; } lockzhiner_vision_module::periphery::GPIOState state; - if (!gpio_0A0.Read(state)) { + if (!gpio.Read(state)) { std::cout << "Failed to read gpio mode" << std::endl; return 1; } diff --git a/example/periphery/gpio/test_gpio_write.cc b/example/periphery/gpio/cpp/test_gpio_write.cc similarity index 63% rename from example/periphery/gpio/test_gpio_write.cc rename to example/periphery/gpio/cpp/test_gpio_write.cc index afc2d1874072e90a511830868eb470cd4a7438d0..91af6880adc0d7f92eb6d7b124556f836f24c105 100644 --- a/example/periphery/gpio/test_gpio_write.cc +++ b/example/periphery/gpio/cpp/test_gpio_write.cc @@ -4,14 +4,14 @@ #include int main() { - lockzhiner_vision_module::periphery::GPIO_0A0 gpio_0A0; + lockzhiner_vision_module::periphery::GPIO0A0 gpio; - if (!gpio_0A0.Config(lockzhiner_vision_module::periphery::GPIOMode::OUT)) { + if (!gpio.Config(lockzhiner_vision_module::periphery::GPIOMode::OUT)) { std::cout << "Failed to config gpio mode" << std::endl; return 1; } - if (!gpio_0A0.Write(lockzhiner_vision_module::periphery::GPIOState::HIGH)) { + if (!gpio.Write(lockzhiner_vision_module::periphery::GPIOState::HIGH)) { std::cout << "Failed to config gpio mode" << std::endl; return 1; } @@ -21,7 +21,7 @@ int main() { std::this_thread::sleep_for(std::chrono::seconds(1)); } - if (!gpio_0A0.Write(lockzhiner_vision_module::periphery::GPIOState::LOW)) { + if (!gpio.Write(lockzhiner_vision_module::periphery::GPIOState::LOW)) { std::cout << "Failed to config gpio mode" << std::endl; return 1; } diff --git a/example/periphery/gpio/python/README.md b/example/periphery/gpio/python/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ec03d92476687c02eb23c248ed49f3cb4e5d1b4f --- /dev/null +++ b/example/periphery/gpio/python/README.md @@ -0,0 +1,171 @@ +

凌智视觉模块 GPIO Python 部署指南

+ +发布版本:V0.0.0 + +日期:2024-09-14 + +文件密级:□绝密 □秘密 □内部资料 ■公开 + +--- + +**免责声明** + +本文档按**现状**提供,福州凌睿智捷电子有限公司(以下简称**本公司**)不对本文档中的任何陈述、信息和内容的准确性、可靠性、完整性、适销性、适用性及非侵权性提供任何明示或暗示的声明或保证。本文档仅作为使用指导的参考。 + +由于产品版本升级或其他原因,本文档可能在未经任何通知的情况下不定期更新或修改。 + +**读者对象** + +本教程适用于以下工程师: + +- 技术支持工程师 +- 软件开发工程师 + +**修订记录** + +| **日期** | **版本** | **作者** | **修改说明** | +| :--------- | -------- | -------- | ------------ | +| 2024/09/14 | 0.0.0 | 郑必城 | 初始版本 | + +## 1 简介 + +接下来让我们基于 Python 来部署 GPIO 例程。在开始本章节前: + +- 请确保你已经按照 [开发环境搭建指南](../../../../docs/introductory_tutorial/python_development_environment.md) 正确配置了开发环境。 +- 请确保你已经按照 [凌智视觉模块 GPIO 使用指南](../README.md) 正确将信号连接到开发板。 + +## 2 API 文档 + +```python +from ..lockzhiner_vision_module_wapper import periphery + +from enum import Enum + + +class GPIOMode(Enum): + """ + @class GPIOMode + @brief GPIO 模式枚举类 + + 该类定义了GPIO 的输入(IN)和输出(OUT)两种模式,基于 periphery 库。 + + """ + + IN = periphery.GPIOMode.IN + OUT = periphery.GPIOMode.OUT + + +class GPIOState(Enum): + """ + @class GPIOState + @brief GPIO 状态枚举类 + + 该类定义了 GPIO 的高电平(HIGH)、低电平(LOW)和错误(ERROR)三种状态,基于 periphery 库。 + """ + + HIGH = periphery.GPIOState.HIGH + LOW = periphery.GPIOState.LOW + ERROR = periphery.GPIOState.ERROR + + +class GPIOBase: + """ + @class GPIOBase + @brief GPIO 基础类 + + 该类提供了 GPIO 的基本操作,包括配置模式、读取状态和写入状态。 + 它依赖于一个外部的 gpio_class 来实现具体的功能。 + """ + + def __init__(self, gpio_class): + """ + @fn __init__ + @brief 构造函数 + + @param gpio_class: 一个实现了 GPIO 操作的类 + """ + self.gpio = gpio_class() + + def config(self, gpio_mode): + """ + @fn config + @brief 配置 GPIO 模式 + @param gpio_mode: 要配置的 GPIO 模式,使用 GPIOMode 枚举类指定 + + @return 配置操作的结果 + """ + return self.gpio.config(gpio_mode) + + def read(self): + """ + @fn read + @brief 读取 GPIO 状态 + + @return GPIO 的当前状态,使用 GPIOState 枚举类表示 + """ + return self.gpio.read() + + def write(self, gpio_state): + """ + @fn write + @brief 写入GPIO状态 + @param gpio_state: 要写入的 GPIO 状态,使用 GPIOState 枚举类指定 + + @return 写入操作的结果 + """ + return self.gpio.write(gpio_state) + + +class GPIO0A0(GPIOBase): + def __init__(self): + super().__init__(periphery.GPIO0A0) + + +class GPIO1C7(GPIOBase): + def __init__(self): + super().__init__(periphery.GPIO1C7) + + +class GPIO2A0(GPIOBase): + def __init__(self): + super().__init__(periphery.GPIO2A0) + + +class GPIO2A1(GPIOBase): + def __init__(self): + super().__init__(periphery.GPIO2A1) + + +class GPIO2A2(GPIOBase): + def __init__(self): + super().__init__(periphery.GPIO2A2) + + +class GPIO2A3(GPIOBase): + def __init__(self): + super().__init__(periphery.GPIO2A3) + + +class GPIO2A4(GPIOBase): + def __init__(self): + super().__init__(periphery.GPIO2A4) + + +class GPIO2A5(GPIOBase): + def __init__(self): + super().__init__(periphery.GPIO2A5) +``` + +## 3 项目介绍 + +为了方便大家入手,我们将项目拆分为**测试 GPIO 输出模式**和**测试 GPIO 输入模式**两个例程。 + +测试 GPIO 输入模式的核心代码如下: + +```python +``` + +测试 GPIO 输出模式的核心代码如下: + +```python +``` \ No newline at end of file diff --git a/example/periphery/gpio/python/test_gpio_read.py b/example/periphery/gpio/python/test_gpio_read.py new file mode 100644 index 0000000000000000000000000000000000000000..7160507ee6f345c7f41f238908124a0282b57fe1 --- /dev/null +++ b/example/periphery/gpio/python/test_gpio_read.py @@ -0,0 +1,17 @@ +from lockzhiner_vision_module.periphery import GPIO0A0 +from lockzhiner_vision_module.periphery import GPIOMode +from lockzhiner_vision_module.periphery import GPIOState + +if __name__ == "__main__": + gpio = GPIO0A0() + + if gpio.config(GPIOMode.IN) is False: + print("Failed to config gpio mode") + exit(1) + + state = gpio.read() + if state == GPIOState.ERROR: + print("Failed to read gpio mode") + exit(1) + + print(f"state is {state}") \ No newline at end of file diff --git a/example/periphery/gpio/python/test_gpio_write.py b/example/periphery/gpio/python/test_gpio_write.py new file mode 100644 index 0000000000000000000000000000000000000000..3faf1912da3280c724d311a9626e9f5dba33cd4c --- /dev/null +++ b/example/periphery/gpio/python/test_gpio_write.py @@ -0,0 +1,27 @@ +from lockzhiner_vision_module.periphery import GPIO0A0 +from lockzhiner_vision_module.periphery import GPIOMode +from lockzhiner_vision_module.periphery import GPIOState + +import time + +if __name__ == "__main__": + gpio = GPIO0A0() + + if gpio.config(GPIOMode.OUT) is False: + print("Failed to config gpio mode") + exit(1) + + if gpio.write(GPIOState.HIGH) is False: + print("Failed to write gpio state") + exit(1) + + time_index = 0 + total_time = 10 + while time_index < total_time: + print(f"Wait: {time_index}/{total_time}") + time_index += 1 + time.sleep(1) + + if gpio.write(GPIOState.LOW) is False: + print("Failed to write gpio state") + exit(1) \ No newline at end of file diff --git a/example/vision/classification/README.md b/example/vision/classification/README.md index 6a26cc6e2855e2eb4f59fec610a4faded93fc6f9..2959a30d91ded555c79cac05535f38d442b2c570 100644 --- a/example/vision/classification/README.md +++ b/example/vision/classification/README.md @@ -1,8 +1,35 @@

凌智视觉模块分类模型部署指南

+发布版本:V0.0.0 + +日期:2024-09-11 + +文件密级:□绝密 □秘密 □内部资料 ■公开 + +--- + +**免责声明** + +本文档按**现状**提供,福州凌睿智捷电子有限公司(以下简称**本公司**)不对本文档中的任何陈述、信息和内容的准确性、可靠性、完整性、适销性、适用性及非侵权性提供任何明示或暗示的声明或保证。本文档仅作为使用指导的参考。 + +由于产品版本升级或其他原因,本文档可能在未经任何通知的情况下不定期更新或修改。 + +**读者对象** + +本教程适用于以下工程师: + +- 技术支持工程师 +- 软件开发工程师 + +**修订记录** + +| **日期** | **版本** | **作者** | **修改说明** | +| :--------- | -------- | -------- | ------------ | +| 2024/09/11 | 0.0.0 | 郑必城 | 初始版本 | + ## 1 简介 -在深度学习中,分类模型是一类用于将输入数据分配到预定义类别或标签的模型。这类模型的主要目标是通过分析输入特征,将数据正确地归类到一个或多个类别中。在本章节中,我们将教你如何使用 PaddleX 和 PaddleSlim 训练一个分类模型并在 LockzhinerVisionModule 上部署。 +在深度学习中,分类模型是一类用于将输入数据分配到预定义类别或标签的模型。这类模型的主要目标是通过分析输入特征,将数据正确地归类到一个或多个类别中。在本章节中,我们将教你如何使用 PaddleX 和 PaddleSlim 训练一个分类模型并在凌智视觉模块上部署。 ## 2 图像数据标注 @@ -182,7 +209,7 @@ AI Studio 是基于百度深度学习开源平台飞桨的人工智能学习与 ## 4 在凌智视觉模块上部署模型 -训练完模型后,请参考以下教程使用 C++ 或 Python 在凌智视觉模块上部署模型: +训练完模型后,请参考以下教程使用 C++ 或 Python 在凌智视觉模块上部署分类模型例程: * [凌智视觉模块分类模型 C++ 部署指南](./cpp/README.md) * [凌智视觉模块分类模型 Python 部署指南](./python/README.md) diff --git a/example/vision/classification/cpp/README.md b/example/vision/classification/cpp/README.md index d4edf571e6279cfb1c5100b12147e6eb3e4e6de7..fdbfdbb79e51658f26fe2d47684d8e65cd5f0e5f 100644 --- a/example/vision/classification/cpp/README.md +++ b/example/vision/classification/cpp/README.md @@ -1,8 +1,38 @@

凌智视觉模块分类模型 C++ 部署指南

+发布版本:V0.0.0 + +日期:2024-09-11 + +文件密级:□绝密 □秘密 □内部资料 ■公开 + +--- + +**免责声明** + +本文档按**现状**提供,福州凌睿智捷电子有限公司(以下简称**本公司**)不对本文档中的任何陈述、信息和内容的准确性、可靠性、完整性、适销性、适用性及非侵权性提供任何明示或暗示的声明或保证。本文档仅作为使用指导的参考。 + +由于产品版本升级或其他原因,本文档可能在未经任何通知的情况下不定期更新或修改。 + +**读者对象** + +本教程适用于以下工程师: + +- 技术支持工程师 +- 软件开发工程师 + +**修订记录** + +| **日期** | **版本** | **作者** | **修改说明** | +| :--------- | -------- | -------- | ------------ | +| 2024/09/11 | 0.0.0 | 郑必城 | 初始版本 | + ## 1 简介 -接下来让我们基于 C++ 来部署 PaddleClas 分类模型。在开始本章节前,请确保你已经参考 [凌智视觉模块分类模型部署指南](../README.md) 对模型进行了充分训练。如果你需要使用 Python 来部署 PaddleClas 请参考 [凌智视觉模块分类模型 Python 部署指南](../python/README.md)。 +接下来让我们基于 C++ 来部署 PaddleClas 分类模型。在开始本章节前: + +- 请确保你已经参考 [凌智视觉模块分类模型部署指南](../README.md) 对模型进行了充分训练。 +- 请确保你已经按照 [开发环境搭建指南](../../../../docs/introductory_tutorial/cpp_development_environment.md) 正确配置了开发环境。 ## 2 C++ API 文档 @@ -226,12 +256,6 @@ int main(int argc, char *argv[]) { ## 4 部署模型 -### 4.1 配置开发环境 - -在开始这个章节前,请确保你已经按照 [开发环境搭建指南](../../../../docs/introductory_tutorial/cpp_development_environment.md) 正确配置了开发环境。 - -### 4.2 编译项目 - 使用 Docker Destop 打开 LockzhinerVisionModule 容器并执行以下命令来编译项目 ```bash @@ -276,3 +300,7 @@ chmod +x ./Test-PaddleClas 程序将读取摄像头数据,使用神经网络检测后输出置信度和类别: ![](images/result_0.png) + +## 5 其他 + +如果你需要使用 Python 来部署 PaddleClas 请参考[凌智视觉模块分类模型 Python 部署指南](../python/README.md)。 diff --git a/example/vision/classification/python/README.md b/example/vision/classification/python/README.md index 75869211418b8888c64a733aa0c8b232eb91b5c6..eb83aa3b8a3917ce95a8cc261ed7b080f23029e8 100644 --- a/example/vision/classification/python/README.md +++ b/example/vision/classification/python/README.md @@ -1,6 +1,5 @@

凌智视觉模块分类模型 Python 部署指南

- 发布版本:V0.0.0 日期:2024-09-11 @@ -28,15 +27,15 @@ | :--------- | -------- | -------- | ------------ | | 2024/09/11 | 0.0.0 | 郑必城 | 初始版本 | - ## 1 简介 -接下来让我们基于 Python 来部署 PaddleClas 分类模型。在开始本章节前,请确保你已经参考 [凌智视觉模块分类模型部署指南](../README.md) 对模型进行了充分训练。如果你需要使用 C++ 来部署 PaddleClas 请参考 [凌智视觉模块分类模型 C++ 部署指南](../cpp/README.md)。 +接下来让我们基于 Python 来部署 PaddleClas 分类模型。在开始本章节前: +- 请确保你已经参考 [凌智视觉模块分类模型部署指南](../README.md) 对模型进行了充分训练。 +- 请确保你已经按照 [开发环境搭建指南](../../../../docs/introductory_tutorial/python_development_environment.md) 正确配置了开发环境。 ## 2 Python API 文档 - ```python class ClassificationResult: """ @@ -154,20 +153,14 @@ if __name__ == "__main__": ## 4 上传并测试 Python 程序 -### 4.1 准备工作 - -在开始这个章节前,请确保你已经按照 [开发环境搭建指南](../../../../docs/introductory_tutorial/python_development_environment.md) 正确配置了开发环境。 - -### 4.2 连接设备并测试模型 - 参考 [连接设备指南](../../../../docs/introductory_tutorial/connect_device_using_ssh.md) 正确连接 Lockzhiner Vision Module 设备。 ![](../../../../docs/introductory_tutorial/images/connect_device_using_ssh/ssh_success.png) 请使用 Electerm Sftp 依次上传以下两个文件: -* 进入存放 **test_paddleclas.py** 脚本文件的目录,将 **test_paddleclas.py** 上传到 Lockzhiner Vision Module -* 进入存放 **LZ-MobileNetV2_x0_25.rknn(也可能是其他模型)** 模型存放的目录(模型存放在训练模型后下载的 output 文件夹内),将 **LZ-MobileNetV2_x0_25.rknn** 上传到 Lockzhiner Vision Module +- 进入存放 **test_paddleclas.py** 脚本文件的目录,将 **test_paddleclas.py** 上传到 Lockzhiner Vision Module +- 进入存放 **LZ-MobileNetV2_x0_25.rknn(也可能是其他模型)** 模型存放的目录(模型存放在训练模型后下载的 output 文件夹内),将 **LZ-MobileNetV2_x0_25.rknn** 上传到 Lockzhiner Vision Module ![](images/stfp_0.png) @@ -181,4 +174,8 @@ python test_paddleclas.py 运行程序后,屏幕上开始打印标签索引,分类置信度,并在一段时间后输出 FPS 值 -![alt text](result_0.png) \ No newline at end of file +![alt text](result_0.png) + +## 5 其他 + +如果你需要使用 C++ 来部署 PaddleClas 请参考[凌智视觉模块分类模型 C++ 部署指南](../cpp/README.md)。