Hallo,
ich arbeite derzeit an einem Projekt, bei dem ich versuche mit einem Arduino Nano Every zwei ArduCAM Mini 5MP OV5642 anzusteuern, welche jeweils nacheinander ein Bild aufnehmen und anschließend über ein Adafruit MicroSD-Kartenmodul als JPEG auf eine MicroSD speichern.
Die einzelnen Komponenten sind über SPI mit dem Microkontroller verbunden und werden von diesem mit Strom versorgt.
Da ich wenig Erfahrung mit Arduino und der Ansteuerung von SD-Kartenmodulen habe, besteht das verwendete Skript größtenteils aus Teilen der ArduCAM Mini Bibliotheken für die OV5642.
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include <SD.h>
#include "memorysaver.h"
//This demo can only work on OV5640_MINI_5MP_PLUS or OV5642_MINI_5MP_PLUS platform.
#if !(defined (OV5640_MINI_5MP_PLUS)||defined (OV5642_MINI_5MP_PLUS))
#error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
#endif
#define SD_CS 14
// set CS-Ports of the cameras
const int CS1 = 10;
const int CS2 = 9;
bool CAM1_EXIST = false;
bool CAM2_EXIST = false;
// set resoultion of the image
uint8_t resolution = OV5642_1280x960;
uint32_t line, column;
#if defined (OV5640_MINI_5MP_PLUS)
ArduCAM myCAM1(OV5640, CS1);
ArduCAM myCAM2(OV5640, CS2);
#else
ArduCAM myCAM1(OV5642, CS1);
ArduCAM myCAM2(OV5642, CS2);
#endif
//function for initializing both cameras
void initializeCAM() {
uint8_t vid, pid;
uint8_t temp;
Wire.begin();
Serial.begin(115200);
Serial.println(F("ArduCAM Start!"));
// set the CS output:
pinMode(CS1, OUTPUT);
digitalWrite(CS1, HIGH);
pinMode(CS2, OUTPUT);
digitalWrite(CS2, HIGH);
//initialize SPI:
SPI.begin();
//Reset the CPLD
myCAM1.write_reg(0x07, 0x80);
delay(100);
myCAM1.write_reg(0x07, 0x00);
delay(100);
myCAM2.write_reg(0x07, 0x80);
delay(100);
myCAM2.write_reg(0x07, 0x00);
delay(100);
//Check if the 2 ArduCAM Mini 5MP PLus Cameras' SPI bus is OK
while(1){
myCAM1.write_reg(ARDUCHIP_TEST1, 0x55);
temp = myCAM1.read_reg(ARDUCHIP_TEST1);
if(temp != 0x55)
{
Serial.println(F("SPI1 interface Error!"));
}else{
CAM1_EXIST = true;
Serial.println(F("SPI1 interface OK."));
}
myCAM2.write_reg(ARDUCHIP_TEST1, 0x55);
temp = myCAM2.read_reg(ARDUCHIP_TEST1);
if(temp != 0x55)
{
Serial.println(F("SPI2 interface Error!"));
}else{
CAM2_EXIST = true;
Serial.println(F("SPI2 interface OK."));
}
if(!(CAM1_EXIST||CAM2_EXIST)){
delay(1000);continue;
}else
break;
}
//Initialize SD Card
while(!SD.begin(SD_CS)){
Serial.println(F("SD Card Error"));delay(1000);
}
Serial.println(F("SD Card detected."));
#if defined (OV5640_MINI_5MP_PLUS)
while(1){
//Check if the camera module type is OV5640
myCAM1.rdSensorReg16_8(OV5640_CHIPID_HIGH, &vid);
myCAM1.rdSensorReg16_8(OV5640_CHIPID_LOW, &pid);
if ((vid != 0x56) || (pid != 0x40)){
Serial.println(F("Can't find OV5640 module!"));
delay(1000);continue;
}else{
Serial.println(F("OV5640 detected."));break;
}
}
#else
while(1){
//Check if the camera module type is OV5642
myCAM1.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
myCAM1.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
if ((vid != 0x56) || (pid != 0x42)){
Serial.println(F("Can't find OV5642 module!"));
delay(1000);continue;
}else{
Serial.println(F("OV5642 detected."));break;
}
}
#endif
//Change to JPEG capture mode and initialize the OV5640 module
myCAM1.set_format(JPEG);
myCAM1.InitCAM();
myCAM1.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH
myCAM2.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH
}
void captureImage(ArduCAM myCAM) {
myCAM.flush_fifo();
myCAM.clear_fifo_flag();
myCAM.OV5642_set_JPEG_size(resolution);delay(1000);
//Start capture
myCAM.start_capture();
Serial.println(F("Start capture."));
float capture_start_time = millis()/1000.0;
Serial.println("Mission Time: ");Serial.println(capture_start_time);
while ( !myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
Serial.println(F("CAM Capture Done."));
float capture_done_time = millis()/1000.0;
float capture_consumed_time = capture_done_time - capture_start_time;
Serial.println("Time needed for capturing image: ");Serial.println(capture_consumed_time);
}
void saveImageToSD(ArduCAM myCAM) {
File outFile;
char VL;
char str[8];
byte buf[256];
static int k = 0,m = 0;
int i,j = 0;
Serial.println("Saving the image,please waitting...");
float saving_start_time = millis()/1000.0;
Serial.println("Mission Time: ");Serial.println(saving_start_time);
itoa(saving_start_time, str, 10);
strcat(str,".jpg"); //Generate file name
outFile = SD.open(str,O_WRITE | O_CREAT | O_TRUNC);
if (! outFile)
{
Serial.println(F("File open error"));
return;
}
if(resolution == OV5642_640x480 ){
line = 640;column = 480;
}else if( resolution == OV5642_1280x960 ){
line = 1280;column = 960;
}else if( resolution == OV5642_1920x1080 ){
line = 1920;column = 1080;
}else if( resolution == OV5642_2592x1944 ){
line = 2592;column = 1944;
}
//Save as JPEG format
for(i = 0; i < line; i++)
for(j = 0; j < column; j++)
{
VL = myCAM.read_fifo();
buf[m++] = VL;
if(m >= 256)
{
//Write 256 bytes image data to file from buffer
outFile.write(buf,256);
m = 0;
}
}
if(m > 0 )//Write the left image data to file from buffer
outFile.write( buf, m );m = 0;
//Close the file
outFile.close();
Serial.println("Image save OK.");
float saving_done_time = millis()/1000.0;
float saving_consumed_time = saving_done_time - saving_start_time;
Serial.println("Time needed for saving file: ");Serial.println(saving_consumed_time);
//Clear the capture done flag
myCAM.clear_fifo_flag();
delay(10);
}
void setup() {
initializeCAM();
}
void loop() {
if(CAM1_EXIST){
captureImage(myCAM1);
saveImageToSD(myCAM1);
}
if(CAM2_EXIST){
captureImage(myCAM2);
saveImageToSD(myCAM2);
}
}
Die Ansteuerung der Kameras klappt soweit, allerdings stoße ich beim durchlaufen des Programms auf das Problem, dass das schreiben der Bilder auf die MicroSD für meine Verwendung viel zu lange dauert ( bei einer Auflösung von 1280x960 Pixeln 27 Sekunden, bei 2592x1944 107 Sekunden und selbst bei minimaler Auflösung von 640x480 noch 6 Sekunden). Wenn ich das Format auf RAW statt JPEG setze, komme ich auf fast identische Zeiten.
Könnte man das Skript optimieren, sodass die speicherzeiten deutlich kürzer sind oder liegt es an der Hardware?
Schonmal vielen Dank für die Hilfe und freundliche Grüße