Hey Guys,
This issue was found utilizing the OV2640 Mini module, as well as an Arduino Zero clone using copied and pasted example code. There is a flash storage chip as well as a SX127X LoRa radio utilizing the same bus. When this issue occurs, the Arduino will crash while executing an SPI transfer as used during photo capture on lines such as while (!myCAM.get_bit(ARDUCHIP_TRIG , CAP_DONE_MASK)); and temp = SPI.transfer(0x00);. Crashing being defined as locked up, no longer executing further code.
On the capture before the crash, using an Oscilloscope we noticed the chip select line not returning back to high after capture randomly (line stays low, the camera continues to believe to be the active device on the SPI bus), then while transceiving data with the LoRa radio, some information is incorrect. During the next capture, the temp = SPI.transfer(0x00) line will crash.
The issue seems to arise with a pattern of utilizing the radio and camera in a specific pattern, have not figured out the pattern, but it has been a noticeable issue for a while, it seems random when just trying to diagnose with no tools. I have seen others online complain about soundingly similar issues.
If you look within the library, it uses cbi and sbi a lot, and it's switching the chip select many, many times a capture.
void capture() {
char str[8];
byte buf[256];
static int i = 0;
static int k = 0;
uint8_t temp = 0, temp_last = 0;
uint32_t length = 0;
bool is_header = false;
File outFile;
//Flush the FIFO
myCAM.flush_fifo();
//Clear the capture done flag
myCAM.clear_fifo_flag();
//Start capture
myCAM.start_capture();
Serial.println(F("start Capture"));
while (!myCAM.get_bit(ARDUCHIP_TRIG , CAP_DONE_MASK)); // CAN CRASH HERE
Serial.println(F("Capture Done."));
length = myCAM.read_fifo_length(); // CAN CRASH HERE
Serial.print(F("The fifo length is :"));
Serial.println(length, DEC);
if (length >= MAX_FIFO_SIZE) //384K
{
Serial.println(F("Over size."));
return ;
}
if (length == 0 ) //0 kb
{
Serial.println(F("Size is 0."));
return ;
}
//Construct a file name
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 faild"));
return;
}
myCAM.CS_LOW();
myCAM.set_fifo_burst();
while ( length-- )
{
temp_last = temp;
temp = SPI.transfer(0x00); // CAN CRASH HERE
//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(); // CAN CRASH HERE
}
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;
buf[i++] = temp_last;
buf[i++] = temp;
}
}
}
For now, I can't put the camera on another bus, but I require a software fix, has anyone had this issue with possibly a different Arduino accessory, and if so, what was your fix? I have wasted so much time on this and I'm this close to rewriting the library.