BMP mode problems

I’m using an OV5642 have been able to get JPEG mode to work with the given examples. I can save the files to an SD card and view them on a PC. However, if I attempt BMP mode, it malfunctions.

The capture completes, but the code appeared to hang. If I print out read_fifo_length, it gives 8388606. I printed out MAX_FIFO_SIZE and it gives 8388607…so basically its returning the max length and processing loop was chewing away forever. I printed out the values from the FIFO and its a series of 16 and 130. It seems like these values are close to the RGB565 format with just the MSB set for each color…but that would be 16 and 132.

The only changes I’ve made are to use SPI1 and alternate SPI1 pins. SPI communication appears to be working fine, so I’m not sure what’s going on. Please give me diagnostic steps.

Also, I can’t find documentation, but I’m assuming BMP mode is only supported at 320x240 mode. Please confirm.

I tried more simplified code and read_fifo_length returned 8 and all 8 bytes were zero. I’m not sure what the difference in the code is.

I put the above code in a loop, and it now alternates between returning a fifo length of 8 and 8388606. Code and output below. Again, the only modifications are to SPI…which seems to be working. I slimmed down the code a much as I could.

Output:

ArduCAM Start!
SPI interface OK.
SD Card detected.
OV5642 detected.
Grab
Start Capture
Capture Done!
8
End Grab
Start Capture
Capture Done!
8388606
Start Capture
Capture Done!
8
Start Capture
Capture Done!
8388606
Start Capture
Capture Done!

 

Code:

 

#include <SD.h>
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
//#include <UTFT_SPI.h>
#include “memorysaver.h”

#define SD_CS BUILTIN_SDCARD
const int SPI_CS = 34;

#define BMPIMAGEOFFSET 66
const int bmp_header[BMPIMAGEOFFSET] PROGMEM =
{
0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x28, 0x00,
0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00,
0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00,
0x00, 0x00
};

ArduCAM myCAM(OV5642, SPI_CS);

void setup()
{
uint8_t vid = 0, pid = 0;
uint8_t temp = 0;

Wire.begin();

Serial.begin(115200);
Serial.println(F(“ArduCAM Start!”));
// set the SPI_CS as an output:
pinMode(SPI_CS, OUTPUT);
// initialize SPI:
SPI1.begin();
SPI1.setMISO(39);
SPI1.setMOSI(26);

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;
}
}
//Initialize SD Card
while(!SD.begin(SD_CS)){
Serial.println(F(“SD Card Error!”));delay(1000);
}
Serial.println(F(“SD Card detected.”));

while(1){
//Check if the camera module type is OV5642
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);continue;
} else{
Serial.println(F(“OV5642 detected.”)); break;
}
}
myCAM.InitCAM();
char str[8];
itoa(97, str, 10);
strcat(str, “.bmp”); //Generate file name
Serial.println(“Grab”);
GrabImage(str);
Serial.println(“End Grab”);
}
void loop()
{
char str[8];
unsigned long previous_time = 0;
static int k = 0;
// myCAM.set_mode(MCU2LCD_MODE); //Switch to CAM
while (1)
{
previous_time = millis();

if ((millis() - previous_time) < 1500)
{
k = k + 1;
itoa(k, str, 10);
strcat(str, “.bmp”); //Generate file name
GrabImage(str);
}
}
}

void GrabImage(char* str)
{
File outFile;
char VH = 0, VL = 0;
byte buf[256];
static int k = 0;
int i, j = 0;
outFile = SD.open(str, O_WRITE | O_CREAT | O_TRUNC);
if (! outFile)
{
Serial.println(F(“Open File Error”));
return;
}
//Flush the FIFO
myCAM.flush_fifo();
//Start capture
myCAM.set_mode(BMP);
myCAM.start_capture();
Serial.println(F(“Start Capture”));
//Polling the capture done flag
while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
Serial.println(F(“Capture Done!”));
k = 0;
//Write the BMP header
for ( i = 0; i < BMPIMAGEOFFSET; i++)
{
char ch = pgm_read_byte(&bmp_header[i]);
buf[k++] = ch;
}
outFile.write(buf, k);
Serial.println(myCAM.read_fifo_length());
//Read the first dummy byte
myCAM.read_fifo();
k = 0;
//Read 320x240x2 byte from FIFO
//Save as RGB565 bmp format
for (i = 0; i < 240; i++)
for (j = 0; j < 320; j++)
{
VH = myCAM.read_fifo();
VL = myCAM.read_fifo();
//Serial.println(VL,DEC);
buf[k++] = VL;
buf[k++] = VH;

//Write image data to bufer if not full
if (k >= 256)
{
//Write 256 bytes image data to file from buffer
outFile.write(buf, 256);
k = 0;
}
}
//Close the file
outFile.close();
//Clear the capture done flag
myCAM.clear_fifo_flag();

return;
}

 

It appears settings are getting stuck somehow. I attempted to compare the code fragments that behaved differently and observed their behavior change.

All I want to do is examine each pixel in RGB565 mode without saving to SD or exporting in any way. Can you forward a minimal code fragment?

I’m using different example files and it seems this might be the line that causes differing behavior:

This makes the fifo length be 8:

CAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH

This one makes the fifo length 8388606

CAM.clear_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);

Hi,

Your question seems a little messy. Can you first explain which example you used? Have you verified the function with our example before modifying the code?

The library had to be modified to support alternate spi in order to run at all. Again, JPEG mode works just fine, so spi is fine. SPI is the only modification. I’m not suspecting the modifications are the issue, since everything else seems to work just fine.

I’ve attempted all the examples that utilize RGB, but they all malfunction. My observation is that fifo length returns either 8 or 8388606. The closest I’ve come to figuring out why behavior differs is the below line:

This makes the fifo length be 8:

CAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH

This one makes the fifo length 8388606

CAM.clear_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);

 

Hi,

First, explain to you why bmp can only save 320*240. If you need to save pictures of other resolutions, you need to change the information of the bmp header, including the resolution and size of the image.
Secondly, I will explain to you the code you used. According to my observation, the example you used is an example for LCD display. If you only want to verify the functions you need, I suggest you refer to this example: https:// github.com/ArduCAM/Arduino/tree/master/ArduCAM/examples/mini/ArduCAM_Mini_5MP_OV5642_Plus_Functions

The code you suggested is the same code I’ve been using. Can you please verify the read_fifo_length output for a BMP capture?

Also, I neglected to state that I am not using the Arducam shield. Does this make a difference?

You also mentioned that I can adjust the BMP resolution by adjusting the header. Can you tell me how to do this?

 

I retried the code again and got the same results. My process is to modify the case statement used to take external input. I execute a command to switch to BMP mode and then I execute a command to take a picture in mode 3. Is this the correct sequence?

Using this process, I can see the BMP header get printed, then the sequence

ox 61
ox 8
ox 61
0x 8

…then this sequence is repeated until the end of the fifo.
0x 82
ox 10

I still need assistance and debug steps.

Hi,

In this example:https://github.com/ArduCAM/Arduino/tree/767848764ce70b7bb8432ad1f069e6c999e19679/ArduCAM/examples/mini/ArduCAM_Mini_5MP_Plus_Video_Streaming, you can set the bmp image output through commands, but you need to add additional save to card functions.
For information about bmp headers, please refer to the official information of bmp.