热度 2
2019-10-21 11:05
3863 次阅读|
1 个评论
By Toradex 秦海 1). 简介 随着 Python 在互联网人工智能领域的流行,大家也慢慢感受到 Python 开发的便利,本文就基于嵌入式 ARM 平台,介绍使用 Python 配合 PyQT5 模块来开发图形化应用程序。 本文所演示的 ARM 平台来自于 Toradex 基于 NXP iMX6 ARM 处理器的 Apalis iMX6 ARM 嵌入式平台。 2. 准备 a). Apalis iMX6Q ARM 核心版配合 Apalis Evaluation Board 载板 ,连接调试串口 UART1 (载板 X29 )到开发主机方便调试。更多关于 Apalis iMX6 配合 Apalis Evaluation Board 载板的说明请参考 Datasheet 和 开发上手指南 。 b). Apalis iMX6Q 默认的 Linux BSP 是不包含 Python , QT 等支持的,需要重新编译。 ./ 基于 Toradex Linux BSP release V2.8 ./ 参考 这里 搭建 Openembedded 编译环境,然后适配下面 patch ,用于使本文测试需要的 libsoc 适配 Python3 。 https://github.com/simonqin09/libsoc-examples/blob/master/python/0005-libsoc-python3-support.patch ./ 修改 build/conf/local.conf 文件,增加需要的组件 -------------------------- #IMAGE_INSTALL_append = " python3 python3-pip python3-libsoc python3-pyqt5 rng-tools " -------------------------- ./ 适配下面 patch ,在标准 image bb 文件中增加 QT5 的支持 https://github.com/simonqin09/libsoc-examples/blob/master/python/0003-angstrom-qt5-lxde-image.patch ./ 重新编译 image -------------------------- $ bitbake -k angstrom-qt5-lxde-image -------------------------- ./ 新生成的 image 位于 deploy/images/apalis-imx6/ 目录,参考 这里 的说明更新到 Apalis iMX6 模块上面 3). Python GPIO 中断测试程序 a). 首先我们先不包含图形界面,单独通过 Python 来完成简单的 GPIO 中断测试程序,本程序通过调用 libsoc 来完成 GPIO 控制,关于 libsoc 的使用和说明请参考 这里 。 b). Apalis Evaluation Board 载板硬件连接配置如下, X4 GPIO05(MXM3_11) 对应系统中的 GPIO 号码是 170 ,作为按键输入使用; X4 GPIO06(MXM3_13) 对应系统中的 GPIO 号码是 169 ,作为输出驱动 LED 使用。 X4 GPIO05 X34 SW5 X4 GPIO06 X34 LED1 c). 源代码请参考如下,分别实现了阻塞模式和非阻塞模式中断相应,实现功能就是按键交替点亮和关闭 LED 灯。 ./ 阻塞模式 – https://github.com/simonqin09/libsoc-examples/blob/master/python/gpiotest_block.py // main 函数作为主函数,实现打开 GPIOs ,同时设定初始化状态为高电平输出; test_interrupt_handler 函数实现中断相应,采用 gpio_in.wait_for_interrupt 为阻塞式中断,捕获中断才会继续进行,捕获中断后做了简单的防误触处理。 ./ 非阻塞模式 – https://github.com/simonqin09/libsoc-examples/blob/master/python/gpiotest_nonblock.py // main 函数作为主函数,实现打开 GPIOs ,同时设定初始化状态为高电平输出;另外,在 main 函数里面采用 gpio_in.start_interrupt_handler 来使能中断相应,为非阻塞式;在 main 函数最后通过 while 来接收键盘输入实现退出应用; gpio_in.wait_for_interrupt 依然作为中断处理函数相应中断并驱动 LED 状态改变。 d). 将 Python 代码直接复制到 Apalis iMX6 上面测试运行结果如下: ./ 阻塞模式下,最后是通过 Ctrl-C 强制退出程序 ----------------------- root@apalis-imx6:~# ./gpiotest_block.py The LED initial status is ON The LED turns OFF interrupt times is 1 The LED turns ON interrupt times is 2 ^Clibsoc-gpio-debug: Interrupted system call Traceback (most recent call last): File "./gpiotest_block.py", line 54, in main(gpio_input_id, gpio_output_id) File "./gpiotest_block.py", line 45, in main test_interrupt_handler(gpio_in, gpio_out) File "./gpiotest_block.py", line 12, in test_interrupt_handler gpio_in.wait_for_interrupt(-1) File "/usr/lib/python3.5/site-packages/libsoc/gpio.py", line 118, in wait_for_interrupt if api.libsoc_gpio_wait_interrupt(self._gpio, timeout) != 0: KeyboardInterrupt ----------------------- ./ 非阻塞模式下 ----------------------- root@apalis-imx6:~# ./gpiotest_nonblock.py The LED initial status is ON please enter 'Q' to quit The LED turns OFF The LED turns ON The LED turns OFF Q Do you really want to quit? yes or no yes root@apalis-imx6:~# ----------------------- 4). 使用 PyQt5 实现图形化界面 GPIO 中断程序 a). 硬件配置和连接和上面的测试场景一致。 b). 为了方便开发 PyQt5 界面,首先通过 Qtcreator 创建如下 QWidget 项目 UI 界面 // LED Status 右边的 QFrame 方框以及 QLable 用于显示 LED 当前的状态 // ‘Turn ON’ 和 ’Turn OFF’ 两个 PushButton 用于通过界面控制 LED 状态, ’Exit’ PushButton 用于退出程序 ./ 最终的 UI 源代码参考如下,将对应的 mainwindow.ui 文件复制到 Apalis iMX6 Python 应用相同路径下 https://github.com/simonqin09/libsoc-examples/blob/master/python/mainwindow.ui c). 程序源代码参考如下: https://github.com/simonqin09/libsoc-examples/blob/master/python/gpiotest_pyqt5.py 说明如下: ./ class ApplicationWindow 用于实现 Qt5 界面以及相关按键操作: // 首先通过 loadUi 函数来加载之前制作好的 UI 文件 mainwindow.ui ,然后初始化界面显示,连接各个按键对应的处理程序 // 最后开启一个新的 Qthread 线程 self.thread ,用于处理外部 GPIO 按键中断相应,连接新线程反馈信号的处理程序,最后启动新线程 // LedStatusChange 函数为处理新线程反馈回来的 LED 状态变化信号而同步改变界面显示状态的函数 // Button_On_clicked 和 Button_Off_clicked 函数用于根据界面按键的点击来对应改变 LED GPIO 输出以及界面显示的函数 // Button_Exit_clicked 和 closeEvent 函数用于处理退出程序包括子线程的退出等相关的函数 ./ class gpioInterrupt 为用于处理 GPIO 中断同时对于改变 LED GPIO 输出以及将 LED 状态变化反馈给界面主程序 // 首先定义反馈信号,并初始化所需要使用的 GPIO 引脚 // run 函数部分基本就是上面第 3 章节的阻塞模式 Python 应用的代码,这里就不做赘述了 d). 测试运行结果如下: ----------------------- root@apalis-imx6:~# ./gpiotest_pyqt5.py The LED initial status is ON set LOW set HIGH The LED turns OFF button clicked for setting LOW The LED turns ON button clicked for setting HIGH root@apalis-imx6:~# ----------------------- 5). 总结 如上述示例,使用 Python 和 PyQt5 非常方便了创建一个嵌入式界面应用程序示例,相对于传统 C 语言开机要配置交叉编译环境,整个流程更加快捷方便,同时在实现比较简单的控制的时候其运行效率也是可以接受的,另外 Python 还可以集成大量的组件方便开发,就更加简化了比如设计机器视觉、人工智能等领域的嵌入式应用开发流程。