Multi Camera Module freeze when switching between 2 cameras.

Hi. I have a Pi4 with a multi-camera module. Connected to it I have two 2.1 Cameras, one is a NoIR camera, and the other is a normal one.

The NoIR one takes a timelapse all night with raspistill, then in the morning it switches to the normal camera, and does its time lapse, and then after dusk it switches back to the NoIR.

Before a switch, the script kills raspistill with a sigterm. A python script switches cameras by running :

import RPi.GPIO as gp
import os

gp.setwarnings(False)
gp.setmode(gp.BOARD)

gp.setup(7, gp.OUT)
gp.setup(11, gp.OUT)
gp.setup(12, gp.OUT)

gp.setup(15, gp.OUT)
gp.setup(16, gp.OUT)
gp.setup(21, gp.OUT)
gp.setup(22, gp.OUT)

gp.output(11, True)
gp.output(12, True)
gp.output(15, True)
gp.output(16, True)
gp.output(21, True)
gp.output(22, True)

i2c = “i2cset -y 1 0x70 0x00 0x04”
os.system(i2c)
gp.output(7, False)
gp.output(11, False)
gp.output(12, True)

 

And the script to switch to the other camera is exactly the same except for this :

i2c = “i2cset -y 1 0x70 0x00 0x06”
os.system(i2c)
gp.output(7, False)
gp.output(11, True)
gp.output(12, False)

 

Every single time it tries to switch, raspistill just stalls. It creates a file with a ~ and seems to wait for sensor data. Typically I just have to kill raspistill, and run the script again which invokes the python switch command again, and then raspistill works fine.

The weirder thing is, that if a few minutes have not passed since the switch first happens, it freezes regardless. I have to wait for a while before trying to switch again and then it will work. I have no idea why. I have checked my cables, they are connected well, and at no other time in the 24 hours a day the cameras run do they cause any issues. It is just the switch. It needs a long break before invoking a second switch command, and trying again.

Can someone help me figure this out? I posted one of the switch scripts, and like i said the other is exactly the same, just different numbers to switch to port C instead of A.

Here is my bash script, you can see where I try to run a dummy raspistill to sacrifice itself to overcome the crash, but my wait time was only 45 seconds, I have increased it to 2 minutes to try again. It is very annoying.

#!/bin/bash
date &>> ~/log/daylapse.log;
killall raspistill;
sleep 5;
killall -9 raspistill;
sleep 2;
python ~/bin/camnorm.py;
sleep 2;
raspistill -th none -n -w 1920 -h 1080 -ISO 100 -awb off -ss 100000 -o ~/WeatherLapse/throwaway.jpg &>> ~/log/daylapse.log &
sleep 120;
killall raspistill;
sleep 2;
killall -9 raspistill;
sleep 2;
python ~/bin/camnorm.py;
sleep 2;
rm ~/WeatherLapse/throwaway.jpg;
rm ~/WeatherLapse/.jpg~;
raspistill -th none -n -ae 48,0x00,0x8080FF -a 12 -w 1920 -h 1080 -tl 15000 -awb off -t 90000000 -sh 30 -co 20 -sa 10 -awb cloud -mm matrix -o ~/WeatherLapse/day%05d.jpg &>> ~/log/daylapse.log &
ffmpeg -loglevel error -nostdin -r 30 -i ~/WeatherLapse/night%05d.jpg -c:v libx264 “/mnt/Share/Capture/WeatherLapse/Complete/$(date +”%y-%m-%d")-1-Night.mp4" &>> ~/log/nightvideo.log;
mkdir /mnt/Share/Capture/WeatherLapse/$(date +"%y-%m-%d");
mv ~/WeatherLapse/night
.jpg /mnt/Share/Capture/WeatherLapse/$(date +"%y-%m-%d")/ &>> ~/log/daylapse.log &

Hello,

Thanks for your detail description. I think it is due to the i2c bus exists conflict. Please try to add

dtparam=i2c_vc=on to the /boot/config.txt and reboot. Then change the i2cset -y 1 to i2cset -y 0

Thank you for getting back to me, I was losing hope. I already had dtparam=i2c_vc=on in there, but I will try to use i2cset -y 0 to switch and see if it helps. I will get back to you on that. The cameras run doing 24 hour time lapses, it is currently running and will try to switch in 7 hours. I will let you know if it helped or not. Thanks again.

Ok it did not work, it gives a write failed error. It switches sometimes, when it wants to with i2cset -y 0 it is just doesn’t work consistently, it fails more than it works.

I don’t understand how people can switch fast enough low low quality video. It takes me more than 5 minutes of trying till it finally switches.

It is obviously not switching properly, maybe someone can understand what is happening. So this morning at the end of the night timelapse, the script killed raspistill, then switched camera, then it takes a dummy shot because the first shot always fails after I try to switch.

The dummy shut hung, and when it was finally killed, another switch command was given by the script and the real rasp still with my timelapse settings run. This also freezes if there was not a long enough wait it seems. I keep increasing the timer. Last timer was set to 240 seconds. raspistill also froze. I guess I did not wait enough, but upon killing and manually running the script, again, to switch and take my timelapse, the first shot was green. That was the throwaway shot because i use -awb off it comes green. The image was stuck in some buffer the whole time. This time raspistill worked and is taking pictures from the right camera but the first shot was the shot stuck when it froze.

What is going on here? it looks like the camera takes a picture and is not sending it to the pi through the module. Something is jamming it. The image was obviously taken, and then delivered the next switch and raspistill command. Why? Is my multi camera module defective? What could cause this? Some bad connection somewhere between the pi and the module? I have reseated the cables and everything several times.

 

Last, does anyone have a different way I can do this? I need a pi with 2 camera modules that I can use one for night and one for day. This multi camera module sucks for this. It looks like it should work but it doesn’t for me. Either my module is defective or something in my script is wrong when it comes to switching. I can’t figure it out.

 

No help?

Hello,

Very sorry for my late reply. Would you like to attach your whole code for me? I want to help you test it. What’s more, have you tested our demo? Getting it here https://github.com/ArduCAM/RaspberryPi/tree/master/Multi_Camera_Adapter

If possible, please attach me your demo and I will help you check it in detail and reply you as soon as possible.

 

I cannot use the demo because this machine has no monitor. It is a camera sitting in the attic of the house. I control it with wifi.

It seems that when i2cset is run from a script it doesn’t work. I can switch cameras as I please from commandline with i2cset, or running my python script myself. But it seems when it runs from cron, it fails to do anything. That is why it keeps failing till I try myself and it works. It is strange.

Here are the 2 scripts I run that call for camera switch, they run in a cron job, and I also posted the scripts that supposed to switch :


[email protected]:~/WeatherLapse $ more ~/bin/daylapse
#!/bin/bash
date &>> ~/log/daylapse.log;
killall raspistill &>> ~/log/daylapse.log;
killall -9 raspistill &>> ~/log/daylapse.log;
~/bin/nightvideo &>> ~/log/daylapse.log &
sleep 30 &>> ~/log/daylapse.log;
python ~/bin/camnorm.py &>> ~/log/daylapse.log;
i2cset -y 1 0x70 0x00 0x04 &>> ~/log/daylapse.log;
&>> ~/log/daylapse.log &
date &>> ~/log/daylapse.log;
raspistill -th none -n -ae 48,0x00,0x8080FF -a 12 -w 1920 -h 1080 -tl 15000 -t 90000000 -sh 30 -co 20 -sa 5 -awb cloud -mm matrix -o ~/WeatherLapse/day%05d.jpg &>> ~/log/daylapse.log &


[email protected]:~/WeatherLapse $ more ~/bin/nightlapse
#!/bin/bash
date &>> ~/log/nightlapse.log;
killall raspistill &>> ~/log/nightlapse.log;
killall -9 raspistill &>> ~/log/nightlapse.log;
~/bin/dayvideo &>> ~/log/nightlapse.log &
sleep 30 &>> ~/log/nightlapse.log;
python ~/bin/camnoir.py &>> ~/log/nightlapse.log;
i2cset -y 1 0x70 0x00 0x06 &>> ~/log/nightlapse.log;
&>> ~/log/nightlapse.log &
date &>> ~/log/nightlapse.log;
raspistill -th none -n -ae 48,0xff,0x808000 -a 12 -w 1920 -h 1080 -awb greyworld -ISO 800 -ss 10000000 -t 90000000 -tl 0 -sh 30 -co 20 -sa 5 -mm matrix -o ~/WeatherLapse/night%05d.jpg &>> ~/log/nightlapse.log &


[email protected]:~/WeatherLapse $ more ~/bin/camnorm.py
#!/usr/bin/python
import RPi.GPIO as gp
import os

gp.setwarnings(False)
gp.setmode(gp.BOARD)

gp.setup(7, gp.OUT)
gp.setup(11, gp.OUT)
gp.setup(12, gp.OUT)

gp.setup(15, gp.OUT)
gp.setup(16, gp.OUT)
gp.setup(21, gp.OUT)
gp.setup(22, gp.OUT)

gp.output(11, True)
gp.output(12, True)
gp.output(15, True)
gp.output(16, True)
gp.output(21, True)
gp.output(22, True)

i2c = "i2cset -y 1 0x70 0x00 0x04"
os.system(i2c)
gp.output(7, False)
gp.output(11, False)
gp.output(12, True)


[email protected]:~/WeatherLapse $ more ~/bin/camnoir.py
#!/usr/bin/python
import RPi.GPIO as gp
import os

gp.setwarnings(False)
gp.setmode(gp.BOARD)

gp.setup(7, gp.OUT)
gp.setup(11, gp.OUT)
gp.setup(12, gp.OUT)

gp.setup(15, gp.OUT)
gp.setup(16, gp.OUT)
gp.setup(21, gp.OUT)
gp.setup(22, gp.OUT)

gp.output(11, True)
gp.output(12, True)
gp.output(15, True)
gp.output(16, True)
gp.output(21, True)
gp.output(22, True)

i2c = "i2cset -y 1 0x70 0x00 0x06"
os.system(i2c)
gp.output(7, False)
gp.output(11, True)
gp.output(12, False)

Have you using this demo to test the hardware?

https://github.com/ArduCAM/RaspberryPi/blob/master/Multi_Camera_Adapter/Multi_Adapter_Board_4Channel/Multi_Camera_Adapter_V2.2_C%2B%2B/AdapterTestDemo.py

 

Yes I did, and that is where I borrowed the code to switch, and the demo test works when I run it manually. My script also works when I run it manualy…

If I login through SSH and run “daylapse” or “night lapse” script above, it works, it killls raspistill, switches cameras, and starts taking my time lapse.

The problem is when it is run from crontab, without me personally running it, it seems it does not switch.

All I have to do is login, and run the script myself, it works…

I can sit here and switch and take pictures all day, it works, but when it is automated, it doesn’t. It has something to do with i2cset or the GPIO running from a script instead of a shell.

Oh, It seems the hardware is normal, the issue should move on the start script. Do you want to start the script automatically? I don’t know about the crontab you said. Can you tell me more about that?

It is linux’s scheduler, the default one the pi uses. It just runs whatever command you tell it, at the time you tell it to run.

I would guess it is a permission thing, or maybe the environment variables are missing? I don’t know much about programming unfortunately.

Today I tried to modify the script so it runs as root when it gives those commands. I will update with the results.

OK, it does seems the permission’s issue. Waiting for your latest news.

 

Ok! It is switching properly now!! I am not sure what fixed it 100% but I think it is running as root.
I also stopped using shortcuts like ~/log and I switched almost everything to the full path that may be effected by crond. It seems cron doesn’t run things in a normal environment.

That drove me insane and I have never came across something that had a problem running in cron. What made me think of it aside from running as root, is some of my binaries in /usr/local/bin would not run without full path. Encapsulating commands in the crontab with bash -c ‘/usr/bin/blah.sh’ for example will make it run in a bash environment. I have not tried this yet but I mentioned it for someone in the future struggling like I did that may stumble over this post.

Anyway great to hear it can work normally.

 

Does anyone have experience using up to 3 Arducam 8MP autofocus cameras on a Raspberry Pi with Android OS?

Any help would be appreciated. CODE EXAMPLES?

 

Hi,

I don’t know if this link is helpful for you

https://www.electronicsforu.com/electronics-projects/surveillance-camera-using-raspicam-android-app

 

Hi distortionist I was wondering if you can give me more details on how you solved your issues?I have a similar python script and what I do is that I have a button that do a simple taking image. Click on that button and it will switch to camera A and take an image and save to a folder, then it will move to camera B and perform the same process and save to a folder. However it seem that, this button doesnt work consistently. sometime it works fine. Sometime it takes picture on camera A then stall indefinitely, sometime it takes picture on camera A then switch to camera B then stall indefinitel. Sometime it crashes my whole program. If you have any solution i would love to hear it. Thanks.

Here is my code:

i2c1 = “i2cset -y 1 0x70 0x00 0x01”
i2c2 = “i2cset -y 1 0x70 0x00 0x02”

NumA = 0
NumB = 0

GPIO.setup(7,GPIO.OUT)
GPIO.setup(11,GPIO.OUT)

def folder_counter():

global NumA
global NumB

ParentA = '/home/pi/camera/CameraA/'
ParentB = '/home/pi/camera/CameraB/'

Number_of_fileA = os.listdir(ParentA)
Number_of_fileB = os.listdir(ParentB)

NumA = len(Number_of_fileA) + 1
NumB = len(Number_of_fileB) + 1

return NumA,NumB

def shutter_button():
folder_counter()
time.sleep(0.3)

os.system(i2c1) #0x01 bus
GPIO.output(7,False)
GPIO.output(11,False)

filename = "/home/pi/camera/CameraA/image" + str(NumA) + ".jpg"
camera.capture(filename)

time.sleep(0.3)
os.system(i2c2) #0x02 bus
GPIO.output(7,True)
filename = "/home/pi/camera/CameraB/image" + str(NumB) + ".jpg"
camera.capture(filename)