SOLVED ESP32控制SC132相机硬件触发,通过树莓派保存图片到SD卡的一些问题
-
系统搭建:ESP32接受到拍照信息,GPIO12~15管脚分别触发4个相机。每个相机由树莓派保存图片到SD卡中。需要实现4个相机同步拍照,存图。上图只搭建1个相机+1个树莓派+1块ESP32。最终系统为4个相机+4个树莓派+1块ESP32。存在的问题:单独运行如下.py文件,ESP32收到信息后发出一个脉冲,拍照一次,存图正常。但是将.py文件加入到树莓派启动项中,每次启动后,存下来的图都为空的。发现问题是,相机进程占用sudo lsof /dev/video0 ,需要手动关掉进程sudo kill 1903。偶然间,在树莓派启动的时候发送命令给ESP32,ESP32触发相机。即能正常工作,且存图正常。于是我在ESP32在Setup中加入45s,频率5Hz的方波。还是存在启动的时候由方波触发的RAW文件一张有图一张无图(要么奇数有图偶数无图,要么相反)。而且这么做具有很大的局限性,即需要树莓派和ESP32同时上电,且当使用4个树莓派时,启动时间不能保证一样,代码中的num(即四个相机同一场景下的照片名字错位)不能保证是一致的。
希望实现树莓派上电后自动运行代码,等待硬件触发,拍照存图。不知道贵公司有没有相关的开发案例或者函数接口供调用!!!
以下为树莓派中的代码.py文件。
import time
import subprocess
for num in range(0,20)://最后希望用while(1): 可以无限拍照,num来自本地文件
time.sleep(0.5)
print(num)
cmd = "v4l2-ctl --set-fmt-video=width=1024,height=1280,pixelformat=GREY --stream-mmap --stream-count=1 --stream-to=./pic-trigger/y8-pic-{}.raw".format(num)
subprocess.run(cmd,shell=True)已将相机触发改为硬件触发,普通模式
trigger_mode = 1
trigger_src = 1以下是ESP32初始化中的代码
#define WAVE_INTERVAL 45000 // 45s raspberry boot
void generateSquareWave() {
unsigned long startTime = millis();
while (millis() - startTime < WAVE_INTERVAL) {
// Toggle the state every 100ms
if ((millis() / 100) % 2 == 0) {
digitalWrite(12, HIGH);
digitalWrite(13, HIGH);
digitalWrite(14, HIGH);
digitalWrite(15, HIGH);
} else {
digitalWrite(12, LOW);
digitalWrite(13, LOW);
digitalWrite(14, LOW);
digitalWrite(15, LOW);
}
delay(100);
}
}
void setup(){
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
digitalWrite(14, LOW);
digitalWrite(15, LOW);
generateSquareWave();
} -
@mjyc said in ESP32控制SC132相机硬件触发,通过树莓派保存图片到SD卡的一些问题:
import time
import subprocess
for num in range(0,20)://最后希望用while(1): 可以无限拍照,num来自本地文件
time.sleep(0.5)
print(num)
cmd = "v4l2-ctl --set-fmt-video=width=1024,height=1280,pixelformat=GREY --stream-mmap --stream-count=1 --stream-to=./pic-trigger/y8-pic-{}.raw".format(num)
subprocess.run(cmd,shell=True)- 首先你应该去掉time.sleep(0.5)。
两个系统是异步的,树莓派端要随时最好收取图片的准备。本身v4l2-ctl 这个命令就会等待。 - stream-count=1设置成-1怎么样?让这个进程一直等着,别退出了。有退出,就有可能丢帧。
- 首先你应该去掉time.sleep(0.5)。
-
stream-count=-1,进程一直运行,我如何保存不同名字的图片。
-
@veye_xumm
您好,目前按照您所说的连续捕获的stream-count=-1的方式,没有办法捕获一次,保存一张不同名字的图片。
我将我目前的情况详细的叙述一下:
我将gpio-trigger.py 编写好,在Terimal中运行python nano gpio-trigger.py 能够正常的实现触发,存图
于是,我将这个python文件作为开机启动程序
但是每次重启后,都是没进行硬件触发,就在文件夹下产生了20张(指所有),且所有照片都是空的。于是我猜想是启动的太早了,于是我在gpio-trigger.py进入循环前,进行了60s的延迟。但是仍然没有解决,还是会出现延迟结束,没有硬件触发,直接生成20张空图片
-
@mjyc 你现在摄像头的工作模式,是断电保存的,还是树莓派启动后配置的?
-
@veye_xumm said in ESP32控制SC132相机硬件触发,通过树莓派保存图片到SD卡的一些问题:
摄像头的工作模式
摄像头的工作模式,是我paramsave保存的,每次上电v4l2-ctrl -L看到的都是一样的。
-
@mjyc 你试试别让他上电后自动执行,你手动执行你的这个python脚本?
-
@veye_xumm said in ESP32控制SC132相机硬件触发,通过树莓派保存图片到SD卡的一些问题:
手动执行你的这个python脚本
手动执行这个python脚本,必须要拍满20张图片再次运行,才能继续拍摄。但是我如果用while(1):这种写法,运行一次,不ctrl c退出,也是不能继续拍摄的。
报错为:VIDIOC_S_FMT:failed:Device or resource busy
VIDIOC_REQBUFS returned -1(Device or resource busy)当然自启动问题更多,根本不会等待硬件触发,直接拍完20张。有一次,我试了一下while(1):这种写法,一直存零kb的空图。
-
@veye_xumm 可以可以提供一下解决方案,实现自启动,4个相机硬件触发同步拍摄。真的很急,我的微信号YMJXIAOBAI
-
@veye_xumm
我下午有空的,可否帮忙解决一下这个困扰我两周的问题吗 -
我觉得如果代码中,最开始能清楚所有占用设备的进程,然后开始拍照,这样不管是断电还是提前结束,都不影响下次代码运行。(我运行代码的时候,发现没有结束进程(比如没拍够,或者断电了)下次再拍,会报failed:Device or resource busy。
-
-
@veye_xumm
好的好的,感谢您的建议