# 第一个硬件项目 ***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.*** --- 本教程将带您使用Quectel Pi H1开发套件完成两个入门级硬件实践:使用IMX219摄像头拍照和读取板载按键事件。 # 用IMX219摄像头拍第一张照片 如果未配备IMX219摄像头,可跳过本章。 ## 安装摄像头 1. 关闭Quectel Pi H1智能主控板电源。 2. 找到板上标注为 **CAMERA1** 或 **CAMERA2** 的MIPI CSI排线接口。 3. 将IMX219摄像头的排线金手指朝下,插入接口并扣紧卡扣。 4. 重新上电并启动Quectel Pi H1智能主控板。 ```{note} 请勿反向插入排线,金手指应朝向电路板(向下)。安装和拆卸排线时务必先断电。 ``` ```{image} images/image_Nr7ObVImeojwbXxl8BNcmiCrnGe.webp :width: 910px :height: 508px :align: center ``` ## 控制摄像头拍照 ### 环境配置 运行拍照命令前,请先设置插件路径(每次打开新的终端窗口后均需重新设置): ```bash export GST_PLUGIN_PATH=/usr/lib/gstreamer-1.0:$GST_PLUGIN_PATH ``` ### 拍照 执行以下命令采集图像并保存为JPEG文件: *max-files* 同时决定拍摄张数和本地保存的文件数。当前设置为 *max-files=1*,因此拍摄1张照片,并在 */home/pi* 目录中保存1个JPEG文件;设置为 *max-files=n* 时,拍摄 *n* 张照片,并在本地保存 *n* 个文件。 ```bash sudo -E gst-launch-1.0 -e \ qtiqmmfsrc name=camsrc ! \ 'video/x-raw,format=NV12,width=1280,height=720,framerate=30/1' ! \ tee name=t ! \ queue ! videoconvert ! jpegenc ! \ multifilesink location=/home/pi/shot-%05d.jpg max-files=1 ``` 管道状态显示为 *PLAYING* 时,表示摄像头正在采集图像。按“Ctrl+C”可停止管道。 ```{note} 如需拍摄 *n* 张照片并在本地保存 *n* 个文件,请将参数设置为 *max-files=n*。 ``` ## 进阶:用Python+OpenCV拍照 安装OpenCV: ```bash sudo apt update sudo apt install -y python3-opencv ``` 创建文件 *~/capture.py*: ```python import cv2 # MIPI摄像头需通过GStreamer管道访问 gst_pipeline = ( "qtiqmmfsrc name=camsrc ! " "video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! " "videoconvert ! video/x-raw,format=BGR ! appsink" ) cap = cv2.VideoCapture(gst_pipeline, cv2.CAP_GSTREAMER) if not cap.isOpened(): print("错误:无法打开摄像头") exit(1) # 跳过前几帧(摄像头需要时间完成自动曝光和白平衡) for i in range(30): cap.read() ret, frame = cap.read() if ret: cv2.imwrite("/home/pi/opencv_photo.jpg", frame) print("拍照成功!已保存到 /home/pi/opencv_photo.jpg") else: print("错误:无法读取图像帧") cap.release() ``` ```{note} 脚本会将照片保存到 */home/pi/opencv_photo.jpg*。如需更改位置,请修改脚本中的保存路径。 ``` 运行(需要 *sudo* 权限): ```bash sudo -E python3 ~/capture.py ``` ```{note} IMX219是MIPI CSI摄像头,不支持标准V4L2接口,因此OpenCV需要借助GStreamer管道来访问。运行前确保已设置 *export GST_PLUGIN_PATH=/usr/lib/gstreamer-1.0:$GST_PLUGIN_PATH*。 ``` # 探索GPIO ## 查看GPIO引脚状态 安装GPIO命令行工具: ```bash sudo apt install -y gpiod ``` 查看系统中所有GPIO控制器: ```bash sudo gpiodetect ``` 查看指定控制器上所有引脚的状态: ```bash sudo gpioinfo --chip gpiochip4 ``` 输出中的每一行代表一个GPIO引脚;标有 *consumer=xxx* 的引脚已被内核驱动占用。 ```{note} 板载 **KEY1** 和 **KEY2** 由内核中的 *gpio-keys* 和 *pmic_resin* 驱动管理,在用户空间中呈现为标准Linux输入设备。因此,应使用 *evtest* 或 *evdev* 读取按键事件,而不是直接操作GPIO引脚。 ``` ## 使用evtest验证按键 Quectel Pi H1智能主控板提供 **KEY1** 和 **KEY2** 两个用户按键,可通过Linux输入子系统读取。设备节点可能随系统版本变化,请先运行 *sudo evtest* 确认 *gpio-keys* 和 *pmic_resin* 对应的 *event* 编号;下表为本示例环境的映射。 | **按键** | **输入设备** | **映射键码** | | --- | --- | --- | | KEY1 | */dev/input/event3* | KEY_VOLUMEDOWN (114) | | KEY2 | */dev/input/event1* | KEY_VOLUMEUP (115) | 安装 *evtest* 工具: ```bash sudo apt install -y evtest ``` 使用以下命令监听 **KEY1**: ```bash sudo evtest /dev/input/event3 ``` 按下KEY1,终端将实时输出按键事件: ```plaintext Event: time ..., type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 1 ← 按下 Event: time ..., type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 0 ← 松开 ``` 按“Ctrl+C”退出。同样,可使用 *sudo evtest /dev/input/event1* 监听KEY2。 ```{image} images/image_IDcRbTc4YoR3XVx7Qkuc8MQ7nFe.webp :width: 703px :height: 367px :align: center ``` ## 使用Python监听按键事件 安装 *evdev* 库: ```bash pip install evdev ``` 创建文件 *~/button_monitor.py*: ```python from evdev import InputDevice, ecodes import selectors dev_key1 = InputDevice("/dev/input/event3") dev_key2 = InputDevice("/dev/input/event1") print(f"监听 KEY1: {dev_key1.name}") print(f"监听 KEY2: {dev_key2.name}") print("按 Ctrl+C 退出") sel = selectors.DefaultSelector() sel.register(dev_key1, selectors.EVENT_READ) sel.register(dev_key2, selectors.EVENT_READ) try: while True: for key, _ in sel.select(): device = key.fileobj for event in device.read(): if event.type == ecodes.EV_KEY and event.value == 1: if event.code == ecodes.KEY_VOLUMEDOWN: print("KEY1 被按下!") elif event.code == ecodes.KEY_VOLUMEUP: print("KEY2 被按下!") except KeyboardInterrupt: print("\n退出监听") ``` 运行: ```bash sudo -E python3 ~/button_monitor.py ``` 按下KEY1或KEY2,终端将输出相应提示。按“Ctrl+C”退出。 ```{note} 访问Linux输入设备需要 *root* 权限,因此应使用 *sudo* 运行脚本。 ``` ```{image} images/image_I5DfbulPaoB1JMxEWRScTJsHn5f.webp :width: 434px :height: 196px :align: center ``` # 常见问题 **Q:拍照命令报错“no element qtiqmmfsrc”** 请先设置插件路径: ```bash export GST_PLUGIN_PATH=/usr/lib/gstreamer-1.0:$GST_PLUGIN_PATH ``` 然后执行拍照命令。 **Q:拍照命令报错“Failed to connect to bus”** 请确保命令带有 ***sudo -E*** 前缀,因为摄像头插件需要 ***root*** 权限。 **Q:*evtest*****没有显示按键事件** 设备编号可能与文中示例不同。运行 ***sudo evtest***(不带参数)可列出所有输入设备,从中找到 *gpio-keys* 和 *pmic_resin* 对应的 *event* 编号即可。 **Q:Python脚本报权限错误** Linux输入设备和摄像头都需要 *root* 权限: - 按键脚本:*sudo -E python3 ~/button_monitor.py* - 拍照脚本:*sudo -E python3 ~/capture.py*