一、前言
GC032A 是常见的 30 万像素摄像头,在 EC600M 上通过 camera 模块的 `camPreview`、`camCapture`、`camScandecode` 使用。用起来简单,但坑不少。这篇记录我踩过的四个。
二、坑 1:cam.start() 用子目录路径会失败
现象:把照片保存到 `/usr/photos/xxx` 这样的子目录,`cam.start()` 返回错误码 -1,拍照失败。
原因:驱动对保存路径有要求。直接存根目录就正常。
```
失败:/usr/photos/001
成功:/usr/001
```
另外注意:在 QuecPython 里 USB 盘符路径(如 `U:/`)需要先归一化成 `/usr/…`,否则文件操作会报 `ENODEV`。
三、坑 2:拍照前必须先关预览
现象:预览开着的时候直接拍照,报"camera occupied",错误码 -2 或 -1。
原因:预览和拍照占用同一个摄像头对象,不能同时进行。
正确流程:
```python
cam.close_preview() # 先释放摄像头
time.sleep_ms(300) # 等它完全释放,这步别省
ok, name = cam.capture_photo(320, 240)
# … 用完再恢复预览
```
`time.sleep_ms(300)` 这个延迟不能省,不等它释放完就拍,照样失败。
四、坑 3:闪光灯常亮,竟然是功放使能脚搞的鬼
现象:程序一跑起来,摄像头闪光灯就一直亮着,关不掉。
排查过程:翻遍 camera 模块,没有任何闪光灯或手电筒相关的 API。一度以为是硬件问题,结论是"软件关不了、得改硬件"。
后来发现真相:闪光灯和功放使能共用同一个 GPIO。功放一开,灯就亮;功放一关,灯就灭。
所以解法是按需开关功放,而不是去控灯:
```python
from audio import Audio
# 空闲时关功放,灯灭
Audio.setSpeakerpaSwitch(0)
# 播放前开功放,灯亮(播放期间无法避免)
Audio.setSpeakerpaSwitch(1)
```
注意两点:
- 这个 API 必须在 `set_pa()` 之后调用;
- 只能主线程调(子线程碰音频设备会 dump)。
结论:硬件共脚导致的问题,软件只能"错开时间",无法同时满足两个需求。
五、坑 4:30 万像素识别不了高密度二维码
现象:扫码功能对普通打印二维码识别正常,但对手机屏幕上的微信好友码死活识别不出来。
原因:GC032A 只有 30 万像素,对高密度二维码存在硬件识别边界,像素不够,解码解不出来。它只能稳定识别低密度的打印码。
这不是代码问题,是物理限制。做产品选型时要提前考虑扫码密度需求。
六、小结
| 坑 | 现象 | 解法 |
|—|—|—|
| 子目录保存失败 | cam.start() 返回 -1 | 照片存根目录 |
| 预览占摄像头 | 拍照报 -2/-1 | 先 `close_preview()` 加 300ms 延迟 |
| 闪光灯常亮 | 灯无法关闭 | 与功放共脚,用 `setSpeakerpaSwitch` 按需开关 |
| 二维码识别失败 | 高密度码解不出 | 硬件边界,只支持低密度打印码 |
一句话总结:摄像头的问题,一半在驱动,一半在硬件;搞清楚"是谁的限制",才不会白改代码。