Corrupted image with SPI 5MP Camera at 2nd Loop

Hello,

I’ve made an Arducam OV5642 RevC work with an arduino. The picture is well displayed (actually, I directly send data through a sim800 chipcard to a ftp server, not with an SD card reader.)

But the problem comes after, at the second loop : the images are failed. I tried to fix with the ‘first dummy byte bug’, without success.

It is strange as everything works perfectly at the first loop… Did I miss a function that can reset properly my Arducam ?

For info :

At the end of the loop, a MOSFET transistor shut down the arducam. Then the arduino goes in sleepmode using watchdogs.

In order, I use these functions in the loop :

myCAM.write_reg(ARDUCHIP_TEST1, 0x55); temp = myCAM.read_reg(ARDUCHIP_TEST1);

myCAM.wrSensorReg16_8(0xff, 0x01);
myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);

myCAM.set_format(JPEG);
myCAM.InitCAM();

myCAM.OV5642_set_JPEG_size(OV5642_320x240);
myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);

myCAM.flush_fifo();
myCAM.clear_fifo_flag();
myCAM.start_capture();

myCAM.get_bit(ARDUCHIP_TRIG , CAP_DONE_MASK)

length = myCAM.read_fifo_length();

myCAM.CS_LOW();
myCAM.set_fifo_burst();

SPI.transfer(0x00)


Thank’s for the help !

Hi,

Please add

//Reset the CPLD
myCAM.write_reg(0x07, 0x80);
delay(100);
myCAM.write_reg(0x07, 0x00);

before myCAM.write_reg(ARDUCHIP_TEST1,0x55​​);

You are my hero !!

I’ll let it works during the night, I’ll keep you in touch if it works

Thank you so much

 

Great to hear you have solved your problems.

Well, it’s not perfectly working… The first one is working, then most of them are failed. Especially the following ones, it look like some of them are good after the 5th loop. But it’s erratic.

In order to clean the response, do I need to use something like

myCAM.read_reg(0x07)
after what you said to put in the code?

 

Hi,

Please let me know after

myCAM.CS_LOW();
myCAM.set_fifo_burst();

SPI.transfer(0x00)

what you do?

I just turn off the transistor, then put the arduino in Low Power mode using LowPower library

My code is here…

https://drive.google.com/drive/folders/1_GK3gGSc93zE6s3ayaUub3XfVn2-yzep?usp=sharing

I just turn off the transistor powering the arducam, then use the LowPower library to turn of the arduino…

My code is here if you ever want to have a look !

Thank you so much

I just turn off the transistor and entering the Arduino to low power mode using Low POwer library…

#include "LowPower.h" #include <SoftwareSerial.h> #include <ArduCAM.h> #include <Wire.h> #include <SPI.h> #include <Servo.h>

//---- DECLARE PIN, VARIABLES, OBJECTS -----

int transistor_cam=2;
int transistor_servo=3;
int transistor_sim=4;
int servo_pin=5;
int SPI_CS = 10;

unsigned long timeprevious = millis();
uint8_t vid = 0, pid = 0;
uint8_t temp = 0;
int reponse = 0;

SoftwareSerial sim800l(7,8);
ArduCAM myCAM(OV5642, SPI_CS);
Servo myservo;

void setup() {
pinMode(transistor_cam,OUTPUT);
pinMode(transistor_servo,OUTPUT);
pinMode(transistor_sim,OUTPUT);
pinMode(SPI_CS,OUTPUT);

digitalWrite(transistor_cam,LOW);
delay(10);
digitalWrite(transistor_sim,LOW);
delay(10);
digitalWrite(transistor_servo,LOW);
delay(10);

//-------- STARTING BUS CONNEXIONS --------

Serial.begin(57600);
sim800l.begin(57600);
Wire.begin(); //For OV5642
SPI.begin();
}

void loop() {
delay(1000);

Serial.println(“Hello World !”);

// --------------- STARTING RELAYS & OPEN CAMERA COVER ------------------ */
Serial.println(“Open Camera Cover”);
/digitalWrite(transistor_servo,HIGH);
delay(10);
myservo.attach(servo_pin);
delay(100);
myservo.write(0);
delay(1000);
myservo.write(90);
delay(1000);
myservo.detach();
digitalWrite(transistor_servo,LOW);
delay(10);
/

delay(1000);
Serial.print(“Activating CAM & SIM transistors…”);
delay(10);
digitalWrite(transistor_cam,HIGH);
delay(10);
digitalWrite(transistor_sim,HIGH);
delay(10);
Serial.print(“Activation done.”);

//digitalWrite(relay,LOW);

// --------------- SETUP SIM800l ------------------
Serial.print(“Starting in 5sec “);
delay(5000);
timeprevious = millis();
while(sendATcommand(“AT”,“OK”,1000) != 1 && (millis() - timeprevious) < 10000){
Serial.print(”.”);
delay(1000); //For WakeUp
}
if (sendATcommand(“AT”,“OK”,1000) != 1) {
Serial.println(“Problem. Reboot…”);
return;
}
timeprevious = millis();
while(sendATcommand(“AT”,“OK”,1000) != 1 && (millis() - timeprevious) < 10000){
Serial.print(".");
delay(1000); //For WakeUp
}
Serial.println(sendATcommand(“AT+CSCLK=0”,“OK”,2000));

sendATcommand(“AT+SAPBR=0,1”,“OK”,1000);
updateSerial(“Flushing after Startup…”,5000);

Serial.println(“Sim800 setup for FTP…”);

int rep = 1;
int brk = 0;
String date = “”;

rep=0;
long timeprev = millis();
while (rep==0 && (millis() - timeprev) < 15000){
rep = sendATcommand(“AT+CPIN?”,“OK”,10000);
Serial.println(“retest”);
delay(1000);
}

delay(3000);
Serial.println(sendATcommand(“AT”, “OK”, 1000));
Serial.println(sendATcommand(“ATZ”, “OK”, 1000));
Serial.println(sendATcommand(“ATI”, “OK”, 1000));
Serial.println(sendATcommand(“AT+SAPBR=3,1,CONTYPE,GPRS”, “OK”, 1000));
Serial.println(sendATcommand(“AT+SAPBR=3,1,APN,free”, “OK”, 1000));
delay(1000);
Serial.println(sendATcommand(“AT+SAPBR=1,1”,“OK”, 5000));
delay(2000);
Serial.println(sendATcommand(“AT+CSQ”, “OK”, 1000));
Serial.println(sendATcommand(“AT+FTPCID=1”, “OK”, 1000));
Serial.println(sendATcommand(“AT+FTPSERV=ftp.agrotic.org”, “OK”, 1000));
Serial.println(sendATcommand(“AT+FTPPORT=21”, “OK”, 1000));
Serial.println(sendATcommand(“[email protected]”, “OK”, 1000));
Serial.println(sendATcommand(“AT+FTPPW=SA7an-m@-B!T3”, “OK”, 1000));
Serial.println(sendATcommand(“AT+FTPPUTPATH=/img/”, “OK”, 1000));

delay(2000);

timeprevious = millis();
while (date.indexOf(“2020”) == -1 && (millis() - timeprevious) < 10000){
date=getDate();
delay(1000);
}

if (rep == 1) {rep = sendATcommand(“AT+FTPPUTNAME= dev1_” + date + “.jpg”,“OK”,1000);}

Serial.println(“Sim800 setup finished.”);
updateSerial(“Flushing after Setup…”,5000);
delay(300);

// --------------- SETUP CAMERA ------------------
Serial.println(“Camera setup”);
delay(1000);

timeprevious = millis();
while((millis() - timeprevious) < 10000){
myCAM.write_reg(0x07, 0x80); //Reset the CPLD
delay(1000);
myCAM.write_reg(0x07, 0x00);
delay(1000);
Serial.println(myCAM.read_reg(0x07));
myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
temp = myCAM.read_reg(ARDUCHIP_TEST1);
if(temp != 0x55)
{
Serial.println(F(“SPI interface Error!”));
delay(1000);
continue;
}else{
Serial.println(F(“SPI interface OK.”));
break;
}
}
myCAM.wrSensorReg16_8(0xff, 0x01);
myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
if((vid != 0x56) || (pid != 0x42)){
Serial.println(F(“Can’t find OV5642 module!”));
delay(1000);
} else{
Serial.println(F(“OV5642 detected.”));
}
myCAM.set_format(JPEG);
myCAM.InitCAM();

myCAM.OV5642_set_JPEG_size(OV5642_320x240);
//myCAM.OV5642_set_JPEG_size(OV5642_640x480);
//myCAM.OV5642_set_JPEG_size(OV5642_1600x1200);
myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH

delay(1000);

// --------------- TAKE PICTURE ------------------
uint32_t length = 0;
int sim_buffer = 1350;
int i = 1;
int delai = 50;
int totalPackages=0;

myCAM.flush_fifo();
myCAM.clear_fifo_flag();
myCAM.start_capture();
Serial.println(F(“start Capture…”));
while(!myCAM.get_bit(ARDUCHIP_TRIG , CAP_DONE_MASK));
delay(1000);
Serial.println(F(“Capture Done!”));

// --------------- GET SIZE OF PICTURE ------------------
length = myCAM.read_fifo_length();
Serial.print(F(“The fifo length is :”));
Serial.println(length, DEC);
if (length >= MAX_FIFO_SIZE) {
Serial.println(F(“Over size.”));
}
if (length == 0 ) //0 kb
{
Serial.println(F(“Size is 0.”));
}

totalPackages = length / sim_buffer ;
//Serial.println("Size of file to send : " + length);

// --------------- SEND IMAGE ------------------
Serial.println("------ SEND IMAGE ------");
myCAM.CS_LOW();
myCAM.set_fifo_burst();
delay(1000);
Serial.println(String(SPI.transfer(0x00)));
Serial.println(String(SPI.transfer(0x00)));

while (sendATcommand(“AT+FTPPUT=1”,“OK”,2000)!=1){
delay(1000);
}
delay(1000);
updateSerial(“Waiting for FTP server…”,10000);

while (length > sim_buffer) {
Serial.println(“Sending " + String(i) + " / " + String(totalPackages) );
if(sendATcommand(“AT+FTPPUT=2,”+ String(sim_buffer),”+FTPPUT: 2",3000)){
delay(10);
for (int j=0; j<sim_buffer; j++){
sim800l.write(SPI.transfer(0x00));
}
length -= sim_buffer;
i++;
updateSerial(“fin : “,200);
Serial.println(”—”);
}
}
sendATcommand(“AT+FTPPUT=2,”+ String(length),"+FTPPUT: 2",5000);
delay(50);
for (int j=0; j<length; j++){
sim800l.write(SPI.transfer(0x00));
}

Serial.println(sendATcommand(“AT+FTPPUT=2,0”,“OK”,1000));
delay(2000);
Serial.println(“Upload finished.”);

Serial.println(sendATcommand(“AT+SAPBR=0,1”,“OK”,2000));
delay(2000);
Serial.println(sendATcommand(“AT+CFUN=0”,“OK”,2000));
Serial.println(sendATcommand(“AT+CSCLK=2”,“OK”,2000));

// --------------- CLOSE CAMERA COVER ------------------ */
delay(1000);

/*
Serial.println(“Close Camera Cover”);
digitalWrite(transistor_servo,HIGH);
delay(10);
myservo.attach(servo_pin);
delay(100);
myservo.write(0);
delay(1000);
digitalWrite(transistor_servo,LOW);
delay(10);*/

//-------- LOW POWER MODE --------
Serial.println(“Good night!”);
delay(10);
digitalWrite(transistor_cam,LOW);
delay(10);
digitalWrite(transistor_sim,LOW);
delay(10);

for (int i = 0; i <= 1; i++) {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}

} //Void loop


And the functions :

byte sendATcommand(String ATcommand, String answer1, unsigned int timeout){ byte reply = 0; String content = ""; char character; //Clean the modem input buffer while(sim800l.available()>0) sim800l.read();

//Send the atcommand to the modem
sim800l.println(ATcommand);
delay(20);
unsigned long timeprevious = millis();
while( reply ==0 && (millis() - timeprevious) < timeout ){
while(!sim800l.available() && (millis() - timeprevious) < timeout){
delay(20);
Serial.print(".");
}
while(sim800l.available() && (millis() - timeprevious) < timeout) {
character = sim800l.read();
//Serial.print(character);
content.concat(character);
}
//Stop reading conditions
if (content.indexOf(answer1) != -1){
reply = 1;
}
else{
Serial.println("Error for "+ATcommand);
return;
}
delay(50);
}
Serial.println("Command : " + content);
return reply;
}

String updateSerial(String text, unsigned int timeout) {
String content = “”;
unsigned long timeprevious = millis();
Serial.println(text);
while(content=="" && (millis() - timeprevious) < timeout){
if(sim800l.available()) {
content = sim800l.readString();
//delay(10);
}
}
return content;
}

String getDate() {
String content = “”;
String date="";
int ind = 0;
//Clean the modem input buffer
while(sim800l.available()>0) sim800l.read();

//Send the atcommand to the modem
sim800l.println(“AT+CIPGSMLOC=2,1”);
delay(2000);
unsigned long timeprevious = millis();
while( date == “” && ((millis() - timeprevious) < 15000)){
if(sim800l.available()) {
content = sim800l.readString();
for (int i = 0; i <= content.length(); i++) {
if (isDigit(content[i])){
date.concat(content[i]);
}
}
}
Serial.print(".");
delay(1000);
}
Serial.println("date is : "+date);
return date;
}

 

Hi,

I think that the method you send image data may have problems.You should send the data from 0xff 0xd8 to 0xff 0xd9.

You can refer to this operation process.

myCAM.CS_LOW();
myCAM.set_fifo_burst();
while ( length-- )
{
temp_last = temp;
temp = SPI.transfer(0x00);
//Read JPEG data from FIFO
if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
{
buf[i++] = temp; //save the last 0XD9
//Write the remain bytes in the buffer
myCAM.CS_HIGH();
outFile.write(buf, i);
//Close the file
outFile.close();
Serial.println(F(“Image save OK.”));
is_header = false;
i = 0;
}
if (is_header == true)
{
//Write image data to buffer if not full
if (i < 256)
buf[i++] = temp;
else
{
//Write 256 bytes image data to file
myCAM.CS_HIGH();
outFile.write(buf, 256);
i = 0;
buf[i++] = temp;
myCAM.CS_LOW();
myCAM.set_fifo_burst();
}
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;
buf[i++] = temp_last;
buf[i++] = temp;
}
}

Thank you !

As I don’t have much time, I decided to reset the Arduino after the sleep : like this, it’s “always” a first image.

It’s dirty but i’ll do it better when I’ll have time !

Thank you for the tips

OK, that is also a method.

We have understood your operation process in the above reply, please feel free to contact us if you have any further questions.

Hello, I tried to clean my code and make it in a proper way, like you said in the previous messages. It doesn’t work at all, I have some images like this :

In my code, I read SPI.transfer(0x00) while there is no succession of “FF & D8”, saying that the picture start.

If these octets are detected, I send through my SIM800 card the bytes FF, D8, then the bytes given by SPI.transfer.

I’ve seen that when the images directly start with FF & D8 (so my “while loop” is useless), the picture is good and the sending is OK .

But on most of pictures, my while loop has to run 3 times to “remove” some useless bytes, then it find the FF & D8. In this case, the picture is corrupted as shown above.

Any idea ?

 

My code is here :

byte temp2 = 0x00; byte temp_last; temp_last = temp; temp2 = SPI.transfer(0x00);
Removing useless bytes then Sending the first package from Arducam to SIM800l
while ( (temp2 != 0xD8) && (temp_last != 0xFF) && ( (millis() - timeprevious) < 5000) ){ Serial.println("not image yet"); temp_last = temp2; temp2 = SPI.transfer(0x00); Serial.println(temp2,HEX); }

if (sendATcommand(“AT+FTPPUT=2,”+ String(sim_buffer),"+FTPPUT: 2",4000)){
delay(50);
sim800l.write(0xFF);
sim800l.write(0xD8);
for (int j=0; j<sim_buffer-2; j++){
sim800l.write(SPI.transfer(0x00));
}
length -= sim_buffer;
i++;
updateSerial("fin : ",250);
}
else {return;}


Sending the following packages from Arducam to SIM800l

timeprevious = millis(); while (length > sim_buffer && (millis() - timeprevious) < 300000) { if (sendATcommand("AT+FTPPUT=2,"+ String(sim_buffer),"+FTPPUT: 2",4000)){ delay(50); for (int j=0; j<sim_buffer; j++){ sim800l.write(SPI.transfer(0x00)); } length -= sim_buffer; i++; updateSerial("fin : ",250); Serial.println("---"); } else {continue;} }
Sending the last package :
sendATcommand("AT+FTPPUT=2,"+ String(length),"+FTPPUT: 2",5000); delay(50); for (int j=0; j<length; j++){ sim800l.write(SPI.transfer(0x00)); }

Hi,

Data in FIFO does not always start with FF D8, and sometimes it is normal to lose a few.

I found that you only had a head test and no FF D9 test?

Another reason is that the SPI is too fast or has a bad signal.

Yes, it definitly start with something else than FF D8. And when it does, this is when i get corrupted images. I focused only at the header, not the end (FF D9) as it seemed to work without… But I’ll try to do it in a proper way.

Ok, for the SPI it can be explain by the fact that I use an arduino pro mini 5V. I’ll try to find something to slow it down.

I also have a mosfet transistor to power up my camera, and to be fair I didn’t know very well which mosfet to use… Do you have any recommandation ?

Thank’s,

Hi,

If you refer to our example of capture a picture, you’ll see that have to find both the head FF D8 and the tail FF D9 to be a complete picture.

For transistor controlled camera power, you can refer to the following figure.

I have a question. Can you help please?
i have arduino mega connected to ov5642 arducam and this arduino mega connected to another arduino mega via uart the second mega connected to spi sdcard module i want to capture the photo via the camera and send it via uart to the second arduino mega and store this photo in the sd card i made everything but when i put the sd card in the pc i found the jpg files created but empty have no data so how can i fix the code?
----------------------------------ov5642cameracode:
// ArduCAM Mini demo (C)2017 Lee
// Web: http://www.ArduCAM.com
// This program is a demo of how to use the enhanced functions
// This demo was made for ArduCAM_Mini_5MP_Plus.
// It can continue shooting and store it into the SD card in JPEG format
// The demo sketch will do the following tasks
// 1. Set the camera to JPEG output mode.
// 2. Capture a JPEG photo and buffer the image to FIFO
// 3.Write the picture data to the SD card
// 5.close the file
//You can change the FRAMES_NUM count to change the number of the picture.
//IF the FRAMES_NUM is 0X00, take one photos
//IF the FRAMES_NUM is 0X01, take two photos
//IF the FRAMES_NUM is 0X02, take three photos
//IF the FRAMES_NUM is 0X03, take four photos
//IF the FRAMES_NUM is 0X04, take five photos
//IF the FRAMES_NUM is 0X05, take six photos
//IF the FRAMES_NUM is 0X06, take seven photos
//IF the FRAMES_NUM is 0XFF, continue shooting until the FIFO is full
//You can see the picture in the SD card.
// This program requires the ArduCAM V4.0.0 (or later) library and ArduCAM_Mini_5MP_Plus
// and use Arduino IDE 1.6.8 compiler or above
#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))
#endif
#define FRAMES_NUM 0x06
// set pin 7 as the slave select for the digital pot:
const int CS = 7;
bool is_header = false;
int total_time = 0;
#if defined (OV5640_MINI_5MP_PLUS)
ArduCAM myCAM(OV5640, CS);
#else
ArduCAM myCAM(OV5642, CS);
#endif
uint8_t read_fifo_burst(ArduCAM myCAM);
void setup() {
// put your setup code here, to run once:
uint8_t vid, pid;
uint8_t temp;
#if defined(SAM3X8E)
Wire1.begin();
#else
Wire.begin();
#endif
Serial.begin(115200);
Serial1.begin(115200);
Serial.println(F(“ArduCAM Start!”));
// set the CS as an output:
pinMode(CS, OUTPUT);
digitalWrite(CS, HIGH);
// initialize SPI:
SPI.begin();
//Reset the CPLD
myCAM.write_reg(0x07, 0x80);
delay(100);
myCAM.write_reg(0x07, 0x00);
delay(100);
while(1){
//Check if the ArduCAM SPI bus is OK
myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
temp = myCAM.read_reg(ARDUCHIP_TEST1);
if(temp != 0x55)
{
Serial.println(F(“SPI interface Error!”));
delay(1000);continue;
}else{
Serial.println(F(“SPI interface OK.”));break;
}
}
#if defined (OV5640_MINI_5MP_PLUS)
while(1){
//Check if the camera module type is OV5640
myCAM.rdSensorReg16_8(OV5640_CHIPID_HIGH, &vid);
myCAM.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
myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
myCAM.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
myCAM.set_format(JPEG);
myCAM.InitCAM();
myCAM.set_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
myCAM.clear_fifo_flag();
myCAM.write_reg(ARDUCHIP_FRAMES, FRAMES_NUM);
}
void loop() {
// put your main code here, to run repeatedly:
myCAM.flush_fifo();
myCAM.clear_fifo_flag();
#if defined (OV5640_MINI_5MP_PLUS)
myCAM.OV5640_set_JPEG_size(OV5640_320x240);delay(1000);
#else
myCAM.OV5642_set_JPEG_size(OV5642_320x240);delay(1000);
#endif
//Start capture
myCAM.start_capture();
Serial.println(F(“start capture.”));
total_time = millis();
while ( !myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
Serial.println(F(“CAM Capture Done.”));
total_time = millis() - total_time;
Serial.print(F(“capture total_time used (in miliseconds):”));
Serial.println(total_time, DEC);
total_time = millis();
read_fifo_burst(myCAM);
total_time = millis() - total_time;
Serial.print(F(“save capture total_time used (in miliseconds):”));
Serial.println(total_time, DEC);
//Clear the capture done flag
myCAM.clear_fifo_flag();
delay(5000);
}
uint8_t read_fifo_burst(ArduCAM myCAM)
{
uint8_t temp = 0, temp_last = 0;
uint32_t length = 0;
static int i = 0;
static int k = 0;
char str[8];
byte buf[256];
length = myCAM.read_fifo_length();
Serial.print(F(“The fifo length is :”));
Serial.println(length, DEC);
if (length >= MAX_FIFO_SIZE) //8M
{
Serial.println(“Over size.”);
return 0;
}
if (length == 0 ) //0 kb
{
Serial.println(F(“Size is 0.”));
return 0;
}
myCAM.CS_LOW();
myCAM.set_fifo_burst();//Set fifo burst mode
i = 0;
while ( length-- )
{
temp_last = temp;
temp = SPI.transfer(0x00);
//Read JPEG data from FIFO
Serial1.write(temp);
}
}
-------------------------------------sdcardcode:
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include <SD.h>
#include “memorysaver.h”
#define SD_CS 9
bool is_header = false;
int total_time = 0;
void setup() {
// put your setup code here, to run once:
uint8_t vid, pid;
uint8_t temp;
Serial.begin(115200);
Serial1.begin(115200);
SPI.begin();
while(!SD.begin(SD_CS))
{
Serial.println(F(“SD Card Error!”));delay(1000);
}
Serial.println(F(“SD Card detected.”));
}
void loop(){
uint8_t temp = 0, temp_last = 0;
uint32_t length = 0;
static int i = 0;
static int k = 0;
char str[8];
File outFile;
byte buf[256];
while(Serial1.available()){
temp_last = temp;
temp = Serial1.read();
//Read JPEG data from FIFO
if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
{
buf[i++] = temp; //save the last 0XD9
//Write the remain bytes in the buffer
outFile.write(buf, i);
outFile.close();
Serial.println(F(“OK”));
i = 0;
}
if (is_header == true)
{
//Write image data to buffer if not full
if (i < 256)
buf[i++] = temp;
else
{
//Write 256 bytes image data to file
outFile.write(buf, 256);
i = 0;
buf[i++] = temp;
}
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;
k = k + 1;
itoa(k, str, 10);
strcat(str, “.jpg”);
//Open the new file
outFile = SD.open(str, O_WRITE | O_CREAT | O_TRUNC);
if (! outFile)
{
Serial.println(F(“File open failed”));
while (1);
}
buf[i++] = temp_last;
buf[i++] = temp;
}
}
}

Hi,

I have not seen the problem in your code for the time being, I suggest you to debug the problem step by step.
First of all, after the first mega takes a successful photo, the image data will be printed out through the serial port to confirm that the correct image data is successfully fetched.
Then, after sending the image data of the first mega to the second mega, the second mega prints the received data to the serial port to ensure that the correct data is received.
Then, separately test the process of creating files and writing data to the SD card to confirm that there is no problem with the process of saving the card.
Finally, debug the above functions together.