Code does not exit setup

The following code compiles and all wiring connections seem to work but it does not exit the setup () section; it repeats the Setup() indefinitely.
Setup is followed by several functions (not completely included to save space) before the loop is called. None of the serial monitor control texts in the functions are displayed.
Any advice or comment is appreciated.

include <Wire.h>
#include <ArduCAM.h>
#include "memorysaver.h"
#include <SPI.h>
#include <SD.h>
#include <Adafruit_MMA8451.h> // I2C address for accelerometer = 0x1C or 0x1D
#include <Adafruit_Sensor.h>
#include "RTClib.h"
RTC_DS3231 rtc; // 0x68 = I2C address 
#define FRAMES_NUM 0x00
#define SD_CS 10
#define CS 7
String name1 = "I-";  // Image file name, < 8 characters
String name;
bool myCAM_EXIST = false;
//const int MPU = 0x68;  //0x68 = I2C address for accelerometer
//double AccX, AccY, AccZ, ToTA = 0;
double AX, AY, AZ;
uint8_t vid, pid;  // communication with Arducam
uint8_t temp;
double mx, my, mz = 0;
float TotA=0.005;
//float DTime, STime, ETime;  //not needed for final implementation
int i, j, l, lmax = 500;  // i = image buffer, j = number of images and file number, l = accelerator reads, lmax = max number of accelerometer reads
// CHANGE TO LAUNCH = 3 for actual implementation
// int Launch = 3;   // requires 3 accelerometer readings greater than 14 m/s^2
int Launch = 0;  // for testing purposes only
ArduCAM myCAM(OV5642, CS);
Adafruit_MMA8451 mma = Adafruit_MMA8451();

void setup() {
   Serial.begin(115200);
    if (! mma.begin()) {
    Serial.println("Couldnt start");
    while (1);
  }
  Serial.println("MMA8451 found!");
  mma.setRange(MMA8451_RANGE_4_G);
  pinMode(A1, OUTPUT);
  digitalWrite(A1, LOW);  //enables MOSFET (LEDs)
  delay(5000);

  Wire.begin();
  Serial.println(F("ArduCAM Start!"));
  // set the CS output:
  digitalWrite(CS, HIGH); //pin 7
  pinMode(SD_CS, OUTPUT);  //pin 10
  SPI.begin();  // initialize SPI:
  myCAM.write_reg(0x07, 0x80);   //Reset the CPLD
  delay(100);
  //Check if the ArduCAM Mini 5MP PLus SPI bus is OK
  while (1) {
    myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
    temp = myCAM.read_reg(ARDUCHIP_TEST1);
    if (temp != 0x55) {
      Serial.print(F("SPI interface Error! temp = "));
      Serial.println(temp);
      while (1) {}
    } else {
      myCAM_EXIST = true;
    }
    if (!(myCAM_EXIST)) {
      delay(100);
      continue;
    } else
      Serial.println(F("SPI interface OK."));
      break;  // exit if SPI is OK
  }
  while (!SD.begin(SD_CS)) {  //Initialize SD Card - pin 10
    Serial.println(F("SD Card Error"));
  }
  Serial.println(F("SD Card detected."));
  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!"));
      continue;
    } else 
      Serial.println(F("OV5642 detected."));
      break;
  }
  myCAM.set_format(JPEG);
  myCAM.InitCAM();
  myCAM.OV5642_set_JPEG_size(OV5642_1600x1200);
  delay(1000);
  myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);  //VSYNC is active HIGH
  myCAM.clear_fifo_flag();
  myCAM.write_reg(ARDUCHIP_FRAMES, FRAMES_NUM);
}  // end setup

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
  //Start capture
  myCAM.start_capture();
  // Serial.println(F("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 remain bytes in the buffer
      outFile.write(buf, i);
      outFile.close();  //Close the file
                        // Serial.println(F("Image saved."));
      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;
    }
  }
}

void Read_Accel() {    
//omitted code
  } 

void loop() {
  File myFile;
if ((Launch == 0)){
    digitalWrite(A1, HIGH);  // turns MOSFET on, powers LED's
    lmax = 200;              // number of accelerometer reads
    Read_Accel();
    // save accelerometer data to file in folder Accl/
    DateTime now = rtc.now();
    name = String("Accl/") + "Data" + ".cvs";  // Accl is subfolder on SD card
    SD.begin(SD_CS);
    myFile = SD.open(name, FILE_WRITE);  // Open new file
    
    myFile.print(j);
    myFile.print(", ");
    myFile.print(l);
    myFile.print(", ");
    myFile.print(AX);
    myFile.print(", ");
    myFile.print(AY);
    myFile.print(", ");
    myFile.print(AZ);
    myFile.print(", ");
    myFile.print(TotA);
    AX = AY = AZ = 0;
    
    myFile.print(now.timestamp(DateTime::TIMESTAMP_FULL));
    myFile.print(", ");
    myFile.print("Temperature: ");
    myFile.print(rtc.getTemperature());
    myFile.println(" C");
    myFile.close();
    if (j < 3000) {    // use for specific number of images, here 3000, one image per cycle
        Serial.println(j);
      myCAMSaveToSDFile(myCAM);
       j ++;
      delay(100);
    }
  }
    lmax = 500;
    Read_Accel();
}  // End loop

The serial monitor output :
MMA8451 found!
ArduCAM Start!
SPI interface OK.
SD Card detected.
OV5642 detected.
MMA8451 found!
etc.

It is probably rebooting, which can be caused by an inadequate power supply, running out of dynamic memory, or programming errors, like writing out of array bounds.

For help, you will need to post more information. For instructions see the "How to get the bet out of this forum" post.

1 Like

Put Serial.println(F("got to <insert stage>")); Serial.flush(); between each statement at the end of setup to see where it's going wrong.

2 Likes

You need to start from the bottom of your setup function and start commenting out calls until setup manages to complete.

Resetting could be a number of things. Power issues, watchdog timer, or memory issues. What microcontroller are you using?

My guess is something you are using in setup is dynamocally allocating memory? And you dimply dont have. Enough memory. This wont get picked up when compiling, but will cause your microcontroller to crash.

1 Like

Maybe a bit obvious.
But:
Do you call your functions inside loop?
A function that is placed in between setup and loop will not run without a call...
Add a loop counter...

loop() {
  int counter = 0;
  counter++;
  Serial.println(counter);
// rest of code
1 Like

The problem does not necessarily inside setup(). It can be inside loop() or some of the functions it calls.

As pointed above, you can use prints to pinpoint the problem. Or problems.

You can also insert a LED blink instruction and move it around.

Does this execute?


This may be the culprit:

My apologies for not including more information. I'm trying to use an Arduino nano with external power (5V). Of course, I get the output only after connecting the USB cable.
Output after compiling:
Sketch uses 27592 bytes (89%) of program storage space. Maximum is 30720 bytes.
Global variables use 1268 bytes (61%) of dynamic memory, leaving 780 bytes for local variables. Maximum is 2048 bytes.
It seems that the capacity is not the problem.

Hi, @Gravity123

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Can you post some images of your project?
So we can see your component layout.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Hi @TomGeorge,
here is a picture of the layout in it's final stage.

However, I am still working with a breadboard until the programming bugs are worked out.

Did you try the advice in #3 or #4?

I don't know the library but it wouldn't take much dynamic allocation for image processing to use up 780 bytes.

Yes, memory capacity is a problem.

The first thing loop() does is to allocate 512 of the remaining 780 bytes of dynamic memory for the file buffer, which is already dangerously close to the limit.

And loop performs that allocation every single time it runs.

void loop() {
  File myFile;

The line File myFile; should be outside of loop() or setup().

It is a bad idea to open a file, write a few lines and the close the file, as that vastly increases the error rate, vastly increases the power consumption and vastly slows down data transfer.

The fix is to open the file once in setup, write data in loop(), and then close the file when you are done collecting data.

1 Like

The myFile variable is local to the loop() function. Assuming that the File class is implemented correctly, all memory allocated by its construction will be freed by its destructor when loop() returns.

Further increasing the overhead in transferring data to the file.

Interesting offshoot!
I close the file after every write operation to make sure the data are saved as I have no knowledge / control when the data acquisitions will stop.
I tried adding a counter at the end of setup, but it never increments. I will try detailed sections next.

What happens if you run out of space or have a write error on the card? Since the Arduino implementation of the SD card operations is very unreliable, your approach essentially guarantees a high error rate. Every time you open/close the file, the entire sector buffer has be accessed anew, read in, then written out again.

For long term data collection, File.flush(); can be used to update the file pointers every hour or day. Otherwise you lose everything on power outage.

I appreciate your input, but I first have to figure out why the setup function does not exit.
I followed post#3 and reach

Serial.println(F("got to OV")); 
Serial.flush();

i.e., the end of setup(). Then it starts over again.

You probably don't know whether loop() is called, which is immediately after setup() exits.

Put in a print statement as the very first line of loop() to see whether it is entered.

1 Like

There are functions after setup() and before loop() that have to be defined as they are called in loop.

Do the test before firing off another uninformed post.

The order of functions in the source code of an Arduino program is immaterial.

1 Like

Hopefully this is an 'informed' post:
You were correct about testing the loop() . I get a message that loop() is entered.