Code Stops Working if Board is Power Cycled

My project uses a Sparkfun Arduino Pro Micro, and I'm using a fairly old version of the IDE, 1.8.13.

The Micro is connected to a micro SD card module, a GY-521 gyro/accelerometer module, and a NEO-6m GPS module. The point of the project is to collect data from these modules, save them to an SD card, and then transfer the data onto a computer via micro SD.

It all works as expected when the micro is connected to my computer via usb, however, when it is disconnected and powered by a battery, data is no longer being saved onto the SD card. The data is timestamped, so it's easy to see that the last data taken on a given file is from just before it was power cycled.

To make things more confusing, if I power the Micro through the RAW pin and usb at the same time, and then disconnect the usb, everything works just fine on battery power and I can continue collecting data. The issue is, if the battery ever runs out of power I would have to reconnect the board to a computer to set it up again, which would be inconvenient. I'm sure there's an explanation/solution, but I'm not sure what it could be.

#include <Wire.h>

#include <SPI.h>
#include <SD.h>

#include <SoftwareSerial.h> 
#include <TinyGPS++.h> 


File f;
// The TinyGPS++ object
TinyGPSPlus gps;

static const int TXPin = 9, RXPin = 5;
static const uint32_t GPSBaud = 9600;

SoftwareSerial ss(TXPin, RXPin);

String data;

const int MPU_addr=0x68;  // I2C address of the MPU-6050
double AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

String filename;
char filnum = 'a';


void setup() {
  
  pinMode(OUTPUT,7);
 
  // put your main code here, to run repeatedly:
  Serial.begin(9600);
  while (!Serial) {
    delay(10); // will pause Zero, Leonardo, etc until serial console opens
  }

  Serial.println("");
  delay(100);

  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);

  ss.begin(GPSBaud);

  filename = "RIDE"+String(filnum)+".txt";
  
  while(SD.exists(filename)){
    filnum += 1;
    filename = "RIDE"+String(filnum)+".txt";
  }
  Serial.println("Writing to"+filename);
  Serial.println(gps.date.month());
}



void SDwrite(String file, String text){
  f = SD.open(file, FILE_WRITE);
  if (f) {
    Serial.print("Writing to " + file + "...");
    f.println(text);
    // close the file:
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening " + file);
  }
  f.close();
}


void loop() {
  // put your main code here, to run repeatedly:
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) 


  while (ss.available() > 0)
    if (gps.encode(ss.read()))

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }

  digitalWrite(7, HIGH);
  delay(200);
  digitalWrite(7,LOW);
  
  data = String(AcX)+","+String(AcY)+","+String(AcZ)+","+String(GyX)+","+String(GyY)+","+String(GyZ)+","+String(gps.location.lat())+","+String(gps.location.lng())+","+String(gps.speed.mph())+","+String(gps.time.hour())+","+String(gps.time.minute());
  Serial.println(data);
  SDwrite(filename, data);  
}

This code will make your program stay in an infinite loop until the serial port is opened in Serial Monitor. The reason that is useful is because on native USB boards like yours, the board is not reset when you open Serial Monitor. That means any serial output printed between the time the program starts running and when you get Serial Monitor open will be lost.

In applications where missing that serial output would be a problem, it's useful to add this code to the sketch in order to make the program wait for the Serial Monitor before running.

However, if you are wanting to run your program when the board is not connected to Serial Monitor, you must remove that while loop to allow the rest of the sketch to run.

@ptillishch The final purpose of the project is to run without connection to a computer or the serial monitor, those print statements are only there for debugging and testing. Do you think using the serial monitor may be causing an issue?

The code I quoted in my previous reply is the cause of the behavior you reported. If you comment out that code then the code will run even when started without a connection to Serial Monitor on your computer.

The other Serial code won't cause that behavior so you can leave it in. However, it does make your sketch use more of the microcontroller's memory and also slows the program down a tiny bit. So if you ever have any problems with running short of memory to add all the features you want in your sketch, or you have code that needs to run very fast, then you can consider removing the other Serial code from your sketch as well.

If you search the "Programming Questions' category of the forum, you can find some information about setting up a "debug macro" in your sketch code that allows you to enable and disable the Serial code by changing only one line of your sketch.

Oh I see, thank you! I honestly didn't realize that code was in there, but program memory is running low so thank you for your other advice too!

If your using softwareserial, to read a GPS, then yes you should expect to have problems if you use Serial.Print() at the same time.

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