Limitations of MIPI software

Hello,

I would like to take consecutive RAW frames with long exposure times (e.g. 60 s) and high ISO (e.g. 3200) with the Raspberry Pi. Is this possible with the Arducam MIPI software?

Does this also work with official Raspberry PI cameras of version 1 or 2?

Is the NVIDIA Jetson Nano IMX219 camera without the Raspberry Pi crypto chip also compatible?

I guess there is limitation of the image sensor itself to do long exposure.

Our MIPI camera driver supports both V1 and V2 offical pi camera boards as well as our own cameras.

Jetson nano doesn’t require cryto chip, and you can use our IMX219 cameras.

I successfully used the camera V1 with your software for raw photos.

Your capture_raw.c automatically sets frame rate, gain and exposure? Is there a way I can disable all automatics and set frame rate, gain and exposure and then take several photos? I am perfectly happy with direct register access.

Regarding IMX219: Does the Jetson nano IMX219 work with the Raspberry Pi and Mipi software?

 

@Lactobacillus

From OV5647 datasheet you have to disable the auto exposure and auto gains first to do manual exposure and gain by yourself.

0x3503[0]: AEC manual = 1

0x3503[1]: AGC manual = 1

0x3500 EXPOSURE[19:16]

0x3501 EXPOSURE[15:8]

0x3502 EXPOSURE[7:0]

In our SDK you can direct access the sensor register with the I2C API calls, you can find the example from: https://github.com/ArduCAM/MIPI_Camera/blob/master/RPI/read_write_sensor_reg.c

The IMX219 camera module is also supported by our MIPI camera SDK on Raspberry Pi.

 

 

 

I hooked up a logic analyzer and realized that the register settings with arducam and raspiraw are completely different. Is there a way to put my own set of init registers without setting the default of the arducam software in the first place?

I looked a bit around on github but I could not find the initial register settings in the open sourcecode.

@Lactobacillus

The initialize settings for OV5647 is only used to bring up the camera, you can override the settings afterwards by yourself. We have API which allow user to access the I2C registers directly

Check the example code from: https://github.com/ArduCAM/MIPI_Camera/blob/master/RPI/read_write_sensor_reg.c

I frankensteined some code:

#include "arducam_mipicamera.h" #include <linux/v4l2-controls.h> #include <stdio.h> #include <string.h> #include <time.h> #include <unistd.h> #define LOG(fmt, args...) fprintf(stderr, fmt "\n", ##args)

void save_image(CAMERA_INSTANCE camera_instance, const char *name, int width, int height) {
IMAGE_FORMAT fmt = {IMAGE_ENCODING_RAW_BAYER, 0};
// The actual width and height of the IMAGE_ENCODING_RAW_BAYER format and the IMAGE_ENCODING_I420 format are aligned,
// width 32 bytes aligned, and height 16 byte aligned.
BUFFER *buffer = arducam_capture(camera_instance, &fmt, 6000);
if (!buffer) {
LOG(“capture timeout.”);
return;
}
if(0){
BUFFER *buffer2 = arducam_unpack_raw10_to_raw8(buffer->data, width, height);
arducam_release_buffer(buffer);
buffer = buffer2;
}
FILE *file = fopen(name, “wb”);
fwrite(buffer->data, buffer->length, 1, file);
fclose(file);
arducam_release_buffer(buffer);
}

int main(int argc, char **argv) {
CAMERA_INSTANCE camera_instance;
int width = 2592, height = 1944;
char file_name[100];

LOG(“Open camera…”);
int res = arducam_init_camera(&camera_instance);
if (res) {
LOG(“init camera status = %d”, res);
return -1;
}

//width =2592;//2336;//4672;//1920;
//height =1944;//1748;//3496;//1080;
LOG(“Setting the resolution…”);
// res = arducam_set_resolution(camera_instance, &width, &height);
res = arducam_set_mode(camera_instance, 0);
if (res) {
LOG(“set resolution status = %d”, res);
return -1;
} else {
// LOG(“Current resolution is %dx%d”, width, height);
LOG(“Notice:You can use the list_format sample program to see the resolution and control supported by the camera.”);
}

arducam_set_control(camera_instance, 0x0103,0x01);
sleep(1);

arducam_set_control(camera_instance, 0x3827,0xEC);
arducam_set_control(camera_instance, 0x370C,0x03);
arducam_set_control(camera_instance, 0x3612,0x5B);
arducam_set_control(camera_instance, 0x3618,0x04);
arducam_set_control(camera_instance, 0x5000,0x06);
arducam_set_control(camera_instance, 0x5002,0x40);
arducam_set_control(camera_instance, 0x5003,0x08);
arducam_set_control(camera_instance, 0x5A00,0x08);
arducam_set_control(camera_instance, 0x3000,0x00);
arducam_set_control(camera_instance, 0x3001,0x00);
arducam_set_control(camera_instance, 0x3002,0x00);
arducam_set_control(camera_instance, 0x3016,0x08);
arducam_set_control(camera_instance, 0x3017,0xE0);
arducam_set_control(camera_instance, 0x3018,0x44);
arducam_set_control(camera_instance, 0x301C,0xF8);
arducam_set_control(camera_instance, 0x301D,0xF0);
arducam_set_control(camera_instance, 0x3A18,0x00);
arducam_set_control(camera_instance, 0x3A19,0xF8);
arducam_set_control(camera_instance, 0x3C01,0x80);
arducam_set_control(camera_instance, 0x3B07,0x0C);
arducam_set_control(camera_instance, 0x380C,0x1F);
arducam_set_control(camera_instance, 0x380D,0x1B);
arducam_set_control(camera_instance, 0x3814,0x11);
arducam_set_control(camera_instance, 0x3815,0x11);
arducam_set_control(camera_instance, 0x3708,0x64);
arducam_set_control(camera_instance, 0x3709,0x12);
arducam_set_control(camera_instance, 0x3808,0x0A);
arducam_set_control(camera_instance, 0x3809,0x20);
arducam_set_control(camera_instance, 0x380A,0x07);
arducam_set_control(camera_instance, 0x380B,0x98);
arducam_set_control(camera_instance, 0x3800,0x00);
arducam_set_control(camera_instance, 0x3801,0x00);
arducam_set_control(camera_instance, 0x3802,0x00);
arducam_set_control(camera_instance, 0x3803,0x00);
arducam_set_control(camera_instance, 0x3804,0x0A);
arducam_set_control(camera_instance, 0x3805,0x3F);
arducam_set_control(camera_instance, 0x3806,0x07);
arducam_set_control(camera_instance, 0x3807,0xA3);
arducam_set_control(camera_instance, 0x3811,0x10);
arducam_set_control(camera_instance, 0x3813,0x06);
arducam_set_control(camera_instance, 0x3630,0x2E);
arducam_set_control(camera_instance, 0x3632,0xE2);
arducam_set_control(camera_instance, 0x3633,0x23);
arducam_set_control(camera_instance, 0x3634,0x44);
arducam_set_control(camera_instance, 0x3636,0x06);
arducam_set_control(camera_instance, 0x3620,0x64);
arducam_set_control(camera_instance, 0x3621,0xE0);
arducam_set_control(camera_instance, 0x3600,0x37);
arducam_set_control(camera_instance, 0x3704,0xA0);
arducam_set_control(camera_instance, 0x3703,0x5A);
arducam_set_control(camera_instance, 0x3715,0x78);
arducam_set_control(camera_instance, 0x3717,0x01);
arducam_set_control(camera_instance, 0x3731,0x02);
arducam_set_control(camera_instance, 0x370B,0x60);
arducam_set_control(camera_instance, 0x3705,0x1A);
arducam_set_control(camera_instance, 0x3F05,0x02);
arducam_set_control(camera_instance, 0x3F06,0x10);
arducam_set_control(camera_instance, 0x3F01,0x0A);
arducam_set_control(camera_instance, 0x3A08,0x01);
arducam_set_control(camera_instance, 0x3A09,0x28);
arducam_set_control(camera_instance, 0x3A0A,0x00);
arducam_set_control(camera_instance, 0x3A0B,0xF6);
arducam_set_control(camera_instance, 0x3A0D,0x08);
arducam_set_control(camera_instance, 0x3A0E,0x06);
arducam_set_control(camera_instance, 0x3A0F,0x58);
arducam_set_control(camera_instance, 0x3A10,0x50);
arducam_set_control(camera_instance, 0x3A1B,0x58);
arducam_set_control(camera_instance, 0x3A1E,0x50);
arducam_set_control(camera_instance, 0x3A11,0x60);
arducam_set_control(camera_instance, 0x3A1F,0x28);
arducam_set_control(camera_instance, 0x4001,0x02);
arducam_set_control(camera_instance, 0x4004,0x04);
arducam_set_control(camera_instance, 0x4000,0x09);
arducam_set_control(camera_instance, 0x4837,0x16);
arducam_set_control(camera_instance, 0x4800,0x24);
arducam_set_control(camera_instance, 0x3503,0x03);
arducam_set_control(camera_instance, 0x3820,0x00);
arducam_set_control(camera_instance, 0x3821,0x02);
arducam_set_control(camera_instance, 0x380E,0x7F);
arducam_set_control(camera_instance, 0x380F,0xFF);
arducam_set_control(camera_instance, 0x350A,0x02);
arducam_set_control(camera_instance, 0x350B,0x00);
arducam_set_control(camera_instance, 0x3500,0x07);
arducam_set_control(camera_instance, 0x3501,0xFF);
arducam_set_control(camera_instance, 0x3502,0xF0);
arducam_set_control(camera_instance, 0x3212,0xA0);
arducam_set_control(camera_instance, 0x0100,0x01);

unsigned int counter = 0;
time_t seconds;

for (counter = 0; counter < 25; counter++){
seconds = time(NULL);
sprintf(file_name, “%ld.raw”, seconds);
LOG(“Capture image %s…”, file_name);
save_image(camera_instance, file_name, width, height);
}

LOG(“Close camera…”);
res = arducam_close_camera(camera_instance);
if (res) {
LOG(“close camera status = %d”, res);
}
return 0;
}


 

I compiled the code and rebooted the Pi.

Unfurtunattely it seems my register settings do not get written when I start the program (apart from the arducam settings). Any Ideas?

Hi,

You should use arducam_write_sensor_reg() instead of arducam_set_control().

Please try it again.

 

Thanks,

using this function I war able to write.

Unfortunatelly it tells me “capture timeout.”. Suggestions?

Code with ~0.5 s exposure:

#include "arducam_mipicamera.h" #include <linux/v4l2-controls.h> #include <stdio.h> #include <string.h> #include <time.h> #include <unistd.h> #define LOG(fmt, args...) fprintf(stderr, fmt "\n", ##args)

void save_image(CAMERA_INSTANCE camera_instance, const char *name, int width, int height) {
IMAGE_FORMAT fmt = {IMAGE_ENCODING_RAW_BAYER, 0};
// The actual width and height of the IMAGE_ENCODING_RAW_BAYER format and the IMAGE_ENCODING_I420 format are aligned,
// width 32 bytes aligned, and height 16 byte aligned.
BUFFER *buffer = arducam_capture(camera_instance, &fmt, 6000);
if (!buffer) {
LOG(“capture timeout.”);
return;
}
if(0){
BUFFER *buffer2 = arducam_unpack_raw10_to_raw8(buffer->data, width, height);
arducam_release_buffer(buffer);
buffer = buffer2;
}
FILE *file = fopen(name, “wb”);
fwrite(buffer->data, buffer->length, 1, file);
fclose(file);
arducam_release_buffer(buffer);
}

int main(int argc, char **argv) {
CAMERA_INSTANCE camera_instance;
int width = 2592, height = 1944;
char file_name[100];

LOG(“Open camera…”);
int res = arducam_init_camera(&camera_instance);
if (res) {
LOG(“init camera status = %d”, res);
return -1;
}

//width =2592;//2336;//4672;//1920;
//height =1944;//1748;//3496;//1080;
LOG(“Setting the resolution…”);
// res = arducam_set_resolution(camera_instance, &width, &height);
res = arducam_set_mode(camera_instance, 0);
if (res) {
LOG(“set resolution status = %d”, res);
return -1;
} else {
// LOG(“Current resolution is %dx%d”, width, height);
LOG(“Notice:You can use the list_format sample program to see the resolution and control supported by the camera.”);
}

arducam_write_sensor_reg(camera_instance, 0x0103,0x01);
sleep(1);

arducam_write_sensor_reg(camera_instance, 0x3827,0xEC);
arducam_write_sensor_reg(camera_instance, 0x370C,0x03);
arducam_write_sensor_reg(camera_instance, 0x3612,0x5B);
arducam_write_sensor_reg(camera_instance, 0x3618,0x04);
arducam_write_sensor_reg(camera_instance, 0x5000,0x06);
arducam_write_sensor_reg(camera_instance, 0x5002,0x40);
arducam_write_sensor_reg(camera_instance, 0x5003,0x08);
arducam_write_sensor_reg(camera_instance, 0x5A00,0x08);
arducam_write_sensor_reg(camera_instance, 0x3000,0x00);
arducam_write_sensor_reg(camera_instance, 0x3001,0x00);
arducam_write_sensor_reg(camera_instance, 0x3002,0x00);
arducam_write_sensor_reg(camera_instance, 0x3016,0x08);
arducam_write_sensor_reg(camera_instance, 0x3017,0xE0);
arducam_write_sensor_reg(camera_instance, 0x3018,0x44);
arducam_write_sensor_reg(camera_instance, 0x301C,0xF8);
arducam_write_sensor_reg(camera_instance, 0x301D,0xF0);
arducam_write_sensor_reg(camera_instance, 0x3A18,0x00);
arducam_write_sensor_reg(camera_instance, 0x3A19,0xF8);
arducam_write_sensor_reg(camera_instance, 0x3C01,0x80);
arducam_write_sensor_reg(camera_instance, 0x3B07,0x0C);
arducam_write_sensor_reg(camera_instance, 0x380C,0x1F);
arducam_write_sensor_reg(camera_instance, 0x380D,0x1B);
arducam_write_sensor_reg(camera_instance, 0x3814,0x11);
arducam_write_sensor_reg(camera_instance, 0x3815,0x11);
arducam_write_sensor_reg(camera_instance, 0x3708,0x64);
arducam_write_sensor_reg(camera_instance, 0x3709,0x12);
arducam_write_sensor_reg(camera_instance, 0x3808,0x0A);
arducam_write_sensor_reg(camera_instance, 0x3809,0x20);
arducam_write_sensor_reg(camera_instance, 0x380A,0x07);
arducam_write_sensor_reg(camera_instance, 0x380B,0x98);
arducam_write_sensor_reg(camera_instance, 0x3800,0x00);
arducam_write_sensor_reg(camera_instance, 0x3801,0x00);
arducam_write_sensor_reg(camera_instance, 0x3802,0x00);
arducam_write_sensor_reg(camera_instance, 0x3803,0x00);
arducam_write_sensor_reg(camera_instance, 0x3804,0x0A);
arducam_write_sensor_reg(camera_instance, 0x3805,0x3F);
arducam_write_sensor_reg(camera_instance, 0x3806,0x07);
arducam_write_sensor_reg(camera_instance, 0x3807,0xA3);
arducam_write_sensor_reg(camera_instance, 0x3811,0x10);
arducam_write_sensor_reg(camera_instance, 0x3813,0x06);
arducam_write_sensor_reg(camera_instance, 0x3630,0x2E);
arducam_write_sensor_reg(camera_instance, 0x3632,0xE2);
arducam_write_sensor_reg(camera_instance, 0x3633,0x23);
arducam_write_sensor_reg(camera_instance, 0x3634,0x44);
arducam_write_sensor_reg(camera_instance, 0x3636,0x06);
arducam_write_sensor_reg(camera_instance, 0x3620,0x64);
arducam_write_sensor_reg(camera_instance, 0x3621,0xE0);
arducam_write_sensor_reg(camera_instance, 0x3600,0x37);
arducam_write_sensor_reg(camera_instance, 0x3704,0xA0);
arducam_write_sensor_reg(camera_instance, 0x3703,0x5A);
arducam_write_sensor_reg(camera_instance, 0x3715,0x78);
arducam_write_sensor_reg(camera_instance, 0x3717,0x01);
arducam_write_sensor_reg(camera_instance, 0x3731,0x02);
arducam_write_sensor_reg(camera_instance, 0x370B,0x60);
arducam_write_sensor_reg(camera_instance, 0x3705,0x1A);
arducam_write_sensor_reg(camera_instance, 0x3F05,0x02);
arducam_write_sensor_reg(camera_instance, 0x3F06,0x10);
arducam_write_sensor_reg(camera_instance, 0x3F01,0x0A);
arducam_write_sensor_reg(camera_instance, 0x3A08,0x01);
arducam_write_sensor_reg(camera_instance, 0x3A09,0x28);
arducam_write_sensor_reg(camera_instance, 0x3A0A,0x00);
arducam_write_sensor_reg(camera_instance, 0x3A0B,0xF6);
arducam_write_sensor_reg(camera_instance, 0x3A0D,0x08);
arducam_write_sensor_reg(camera_instance, 0x3A0E,0x06);
arducam_write_sensor_reg(camera_instance, 0x3A0F,0x58);
arducam_write_sensor_reg(camera_instance, 0x3A10,0x50);
arducam_write_sensor_reg(camera_instance, 0x3A1B,0x58);
arducam_write_sensor_reg(camera_instance, 0x3A1E,0x50);
arducam_write_sensor_reg(camera_instance, 0x3A11,0x60);
arducam_write_sensor_reg(camera_instance, 0x3A1F,0x28);
arducam_write_sensor_reg(camera_instance, 0x4001,0x02);
arducam_write_sensor_reg(camera_instance, 0x4004,0x04);
arducam_write_sensor_reg(camera_instance, 0x4000,0x09);
arducam_write_sensor_reg(camera_instance, 0x4837,0x16);
arducam_write_sensor_reg(camera_instance, 0x4800,0x24);
arducam_write_sensor_reg(camera_instance, 0x3503,0x03);
arducam_write_sensor_reg(camera_instance, 0x3820,0x00);
arducam_write_sensor_reg(camera_instance, 0x3821,0x02);
//arducam_write_sensor_reg(camera_instance, 0x380E,0x7F);
//arducam_write_sensor_reg(camera_instance, 0x380F,0xFF);
arducam_write_sensor_reg(camera_instance, 0x380E,0x0A);
arducam_write_sensor_reg(camera_instance, 0x380F,0xA0);
arducam_write_sensor_reg(camera_instance, 0x350A,0x02);
arducam_write_sensor_reg(camera_instance, 0x350B,0x00);
arducam_write_sensor_reg(camera_instance, 0x3500,0x07);
arducam_write_sensor_reg(camera_instance, 0x3501,0xFF);
arducam_write_sensor_reg(camera_instance, 0x3502,0xF0);
arducam_write_sensor_reg(camera_instance, 0x3212,0xA0);
arducam_write_sensor_reg(camera_instance, 0x0100,0x01);

unsigned int counter = 0;
time_t seconds;

for (counter = 0; counter < 25; counter++){
seconds = time(NULL);
sprintf(file_name, “%ld.raw”, seconds);
LOG(“Capture image %s…”, file_name);
save_image(camera_instance, file_name, width, height);
}

LOG(“Close camera…”);
res = arducam_close_camera(camera_instance);
if (res) {
LOG(“close camera status = %d”, res);
}
return 0;
}

Hi,

Many factors will cause it, I think is due to your error sensor configurations. In our SDK, when you choose one mode, such as 640x480, we will config the raspberry pi CSI to receive 640x480 resolution and it does not receive other resolution. What’s more, other factors such as bayer format and number lans .etc.