Hardware / software reliability

Hello,
I am struggling with a strange situation: After developing (partially with Forum help) a project that consist of a camera (OV5642 in 1600x1200 mode), accelerometer (MMA8451), real-time-clock (DS3231 RTC), and a microSD breakout board (Adafruit ADA254), I was able to record the desired information, which includes an image every three seconds, accelerometer and temperature data, and a time stamp. I intend to collect about 3000 images with accompanying information. Strangely, I get various numbers of images taken, ranging from a few dozens up to (maximum so far) 2780. I have used a breadboard and (after testing) a soldered setup.
Somehow the system quits prematurely and I cannot figure out what causes this behavior / instability. I am using an external power supply and do not use the Arduino (Nano or Nano every) as power source. I can restart a new run and get the system to collect information, suggesting that overheating is not the problem. The power settings are: 5V (+/- 0.1 V), 0.15 to 0.25 A. error observations focus on the uSD card as its on borad LED sometimes stays on (as opposed to showing the write activity. Sometimes the LED just stays off.
I appreciate any and all input.

RAM is full from overuse of String library, and intermittent solder joints.
(I see things without being shown things)

1 Like

The wires are too long and are acting like an antenna to pickup noise signals from something in the room.

1 Like

If RAM is 'full', then there should be a difference between Nano and Nano Every. That's not the case. All solder joints were tested and look reliable. The lengths of the various wires in less than 4". The entire setup is placed on a 4 x 4" board.

The schematic for the SD module shows the LED is driven by the CLK line. So if that's not lit up at all, then there's no reading or writing going on. But that's not necessarily the card's fault.

You might try diagnosis by substitution - the processor (which it sounds like you've done), the SD card, the power supply, the SD library, etc. Do you have a connection to the Arduino serial monitor while the project is running?

Well, so far we don't have either the code or the schematic, so it's kinda hard to say. But I tend to agree with you that the SD card is more likely to be the problem. I don't necessarily mean the card itself. It could be the library. Or you could just be pushing it too fast. Have you tried slowing everything down?

If you have not figured out, yet, from the responses, we cannot see or touch or do any tests to help you with the problem.
What have you done to narrow the problem to a single device or a single software problem?

There are no LEDs connected to the setup, so they are not a factor. I will try substitutions and believe (?) that the SD is the most finicky part of the story. I am using the following libraries:
Wire.h, ArduCAM.h, SPI.h, SD.h, Adafruit_MMA8451.h, Adafruit_Sensor.h, and RTClib.h. If there are alternatives that are more reliable, I'd appreciate advice.

Begin by telling us how you determine the systems quits prematurely! Do you have code that makes the system quite for some reason? HOW DO YOU KNOW WHAT QUITS? Power goes out, lights go off. Some help, please.

Thanks for bearing with me - First the code: since everything works as expected I chose not to post it. If that's inappropriate I'd be happy to post the code. As for How do I know - the uSD LED blinks at regular intervals when working properly but stops (off) when a problem occurs. The LEDs on the RTC and Arduino remain lit until I turn the power off. I then check two folders on the uSD – Imag and Accel. Imag contains images (I-n.jpg) and the second one single data file. Each line of which contains n, accelerometer values (x, y, z, and total), a time stamp (TIMESTAMP_FULL) and temperature.
The information between the data file and images is always in synch (same n) but occasionally, the last image is ‘empty’ (black). The time stamp shows intervals of three seconds between images. I assume that the time intervall is OK, I use a delay (250) after each file is written to the uSD card.

Pretty obvious that not everything works as expected. SD card files are all truncated because the Arduino code never closes the files. So, you can withhold the code if you want, but obviously there is a problem with the code.

OK - here is the code that writes the image file to the uSD card.

void myCAMSaveToSDFile(ArduCAM myCAM) {   // Function takes one picture and saves to SD card
  Serial.print("Picture");
  byte buf[256];
  static int i = 0;
  uint8_t temp = 0, temp_last = 0;
  uint32_t length = 0;
  bool header0 = false;
  File outFile;
  myCAM.flush_fifo();       //Flush the FIFO
  myCAM.clear_fifo_flag();  //Clear the capture done flag
  myCAM.start_capture();    //Start capture
  while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
  Serial.println(F("Capture Done."));
  length = myCAM.read_fifo_length();
  //Construct a file name
  name = "Imag/" + name1 + j + ".jpg";                   //Imag is subfolder on SD card
  outFile = SD.open(name, O_WRITE | O_CREAT | O_TRUNC);  // Open the new file
  if (!outFile) {
    Serial.println(F("File open failed"));
    return;
  }
  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 @ end, break while
    {
      buf[i++] = temp;  //save the last  0XD9
      myCAM.CS_HIGH();  //Write the remaining bytes in the buffer
      outFile.write(buf, i);
     outFile.close();  //Close the file
      header0 = false;
      i = 0;
    }
    if (header0 == true) {
      if (i < 256)  //Write image data to buffer if not full
        buf[i++] = temp;
      else {
        myCAM.CS_HIGH();  //Write 256 bytes image data to file
        outFile.write(buf, 256);
        i = 0;
        buf[i++] = temp;
        myCAM.CS_LOW();
        myCAM.set_fifo_burst();
      }
    } else if ((temp == 0xD8) && (temp_last == 0xFF)) {
      header0 = true;
      buf[i++] = temp_last;
      buf[i++] = temp;
    }
  }
}

Based on the line "outFile.close(); //Close the file" I think that the file is closed after each write.

Well. your program is stopping because there is at least one or more device error code or library return error code that you are not handling so the program can continue after it works around or corrects the problem. It is your assignment to ensure that there are no codes/errors that are not recovered from.

Exactly, that's why I'm asking for help. I don't know how to discover the error as it is not a regular event. Why would it occur after many (max >2700) files have been written?

I guess I would try the SdFat.h library in place of SD.h. And I would try slowing down the capture rate as a test just to see if it makes any difference.

The problem with SD cards is that things can get pretty complicated because of the file system overhead. When you close the file, the directory entry has to be updated, along with both copies of the FAT. And our Arduinos just don't have a lot of resources to deal with that.

I would not suggest that you close the file after each save. I know opinions differ on this, but it just takes up a lot of time and resources, particularly if the data is not exactly at the end of a 512-byte sector.

One other thing you might try is the SDFormatter.ino example found in the SdFat.h library. It actually erases the entire card before setting up the file system. Nothing is left that needs to be erased before it is written to, and no file needs to be fragmented.

These intermittent problems can be very tough to diagnose.

Excuse me! You do not know that is where the error is occurring. You are only looking at symptoms. I was going to begin looking at every call you made to a function and every device you read from, and see if any error is ever returned and see how your code handled it.
But you can do that, or should have done it already.

I think I found the problem: Closing the file without clearing the buffer.
The corrected code (placing the 'outFile.close();' ouside the loop) works :

 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 @ end, break while
    {
      buf[i++] = temp;  //save the last  0XD9
      myCAM.CS_HIGH();  //Write the remaining bytes in the buffer
      outFile.write(buf, i);
      header0 = false;
      break; // Exit loop after writing the end of the JPEG data
    }
    if (header0 == true) {
      if (i < 256)  //Write image data to buffer if not full
        buf[i++] = temp;
      else {
        myCAM.CS_HIGH();  //Write 256 bytes image data to file
        outFile.write(buf, 256);
        i = 0;
        buf[i++] = temp;
        myCAM.CS_LOW();
        myCAM.set_fifo_burst();
      }
    } 
    else if ((temp == 0xD8) && (temp_last == 0xFF)) {
      header0 = true;
      buf[i++] = temp_last;
      buf[i++] = temp;
    }
  }
**outFile.close();**
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.