Arduino MKR Zero not writing data to sd card after unplugging from computer

Hi. I am hoping someone can help with this issue.
I have a project that uses DHT22, Photoresistor, RTC, and MKR GPS on an Arduino MKR Zero.
After I upload the sketch I unplug it from the computer and plug it to a 5v battery. The light is on and I let it run for a while.
When I look at the SD card, nothing has been written to it. However, when I leave it plugged to the computer, it works fine and it writes the data to the card.
I've tried resetting it several times when I unplug/plug it back but nothing seems to work.
Does anyone have any ideas as to why this happens?
I was thinking that it was the modules but not all can be faulty at the same time.
I appreciate any help. Thank you in advance.
This is my code.

//Libraries    
#include <Wire.h>    
#include <RTClib.h>    
#include <DHT.h>    
#include <Arduino_MKRGPS.h>    
#include <SPI.h>    
#include <SD.h>    
    
//Constants    
const int chipSelect = SDCARD_SS_PIN;    
#define DHTPIN 7     // what pin we're connected to    
#define DHTTYPE DHT22   // DHT 22  (AM2302)    
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino    
RTC_DS3231 rtc; // create an instance of the RTC_DS3231 class    
    
//Variables    
int chk;    
float hum;  //Stores humidity value    
float temp; //Stores temperature value    
int lightVal;    
    
void setup() {    
  Serial.begin(9600);    
  while (!Serial) {    
    ; // wait for serial port to connect. Needed for native USB port only    
  }    
    
  Wire.begin();    
  rtc.begin();    
    
  // If you are using the MKR GPS as shield, change the next line to pass    
  // the GPS_MODE_SHIELD parameter to the GPS.begin(...)    
  if (!GPS.begin()) {    
    Serial.println("Failed to initialize GPS!");    
    while (1);    
  }    
    
  dht.begin();    
    
  Serial.print("Initializing SD card...");    
    
  // see if the card is present and can be initialized:    
  if (!SD.begin(chipSelect)) {    
    Serial.println("Card failed, or not present");    
    // don't do anything more:    
    while (1);    
  }    
  Serial.println("card initialized.");    
}    
    
void loop() {    
  // check if there is new GPS data available    
  if (GPS.available()) {    
    // read GPS values    
    float latitude = GPS.latitude();    
    float longitude = GPS.longitude();    
    float altitude = GPS.altitude();    
    float speed = GPS.speed();    
    int satellites = GPS.satellites();    
    
    // print all data on a single line separated by commas  
    Serial.print(rtc.now().timestamp());  
    Serial.print(",");  
    Serial.print(latitude, 7);  
    Serial.print(",");  
    Serial.print(longitude, 7);  
    Serial.print(",");  
    Serial.print(altitude);  
    Serial.print(",");  
    Serial.print(speed);  
    Serial.print(",");  
    Serial.print(satellites);  
    Serial.print(",");  
    
    lightVal = analogRead(A1);    
    Serial.print(lightVal);    
    Serial.print(",");    
    
    hum = dht.readHumidity();    
    Serial.print(hum);    
    Serial.print(",");    
    
    temp = dht.readTemperature();    
    Serial.print(temp);    
  
    DateTime now = rtc.now(); //get current date and time  
    Serial.print(","); //add comma to separate from previous data  
    Serial.print(now.year(), DEC); //print year  
    Serial.print("/"); //add slash between year and month  
    Serial.print(now.month(), DEC); //print month  
    Serial.print("/"); //add slash between month and day  
    Serial.print(now.day(), DEC); //print day  
    Serial.print(" "); //add space between date and time  
    Serial.print(now.hour(), DEC); //print hour  
    Serial.print(":"); //add colon between hour and minute  
    Serial.print(now.minute(), DEC); //print minute  
    Serial.print(":"); //add colon between minute and second  
    Serial.print(now.second(), DEC); //print second  
    Serial.println();    
    
    delay(900000); //Delay 15 min.    
    
    File dataFile = SD.open("datalog.txt", FILE_WRITE);    
    
    // if the fileis available, write to it:      
    if (dataFile) {           
      dataFile.print(latitude, 7);      
      dataFile.print(",");      
      dataFile.print(longitude, 7);      
      dataFile.print(",");      
      dataFile.print(altitude);      
      dataFile.print(",");      
      dataFile.print(speed);      
      dataFile.print(",");      
      dataFile.print(satellites);      
      dataFile.print(",");      
      dataFile.print(lightVal);      
      dataFile.print(",");      
      dataFile.print(hum);      
      dataFile.print(",");      
      dataFile.print(temp);      
      dataFile.print(",");      
      dataFile.print(now.year(), DEC);      
      dataFile.print("/");      
      dataFile.print(now.month(), DEC);      
      dataFile.print("/");      
      dataFile.print(now.day(), DEC);      
      dataFile.print(" ");    
      dataFile.print(","); 
      dataFile.print(now.hour(), DEC);      
      dataFile.print(":");      
      dataFile.print(now.minute(), DEC);      
      dataFile.print(":");      
      dataFile.print(now.second(), DEC);      
      dataFile.println();      
      dataFile.close();      
    } else {      
      // if the file isn't open, pop up an error:      
      Serial.println("error opening datalog.txt");      
    } 
  }
}

Really - a 5V battery?

EDIT

Oh - do you mean a USB "power bank"?


Solar Charger Power Bank Portable Charger, 5v

This line waits for a connection to the serial monitor on a PC. Remove it for standalone operation.

  while (!Serial) {    
    ; // wait for serial port to connect. Needed for native USB port only    
  }    
1 Like

Ok. I will try it. Will I need that line if I want to see the serial monitor?

Replace the wait with delay(3000); or similar.

I've made those changes but still nothing seems to happen. Nothing gets written to the card.

You will need to put in Serial.print() statements to see where it is hanging up.

Are you outside, with a clear view of the sky, and a satellite fix? Otherwise no GPS data will be available.

This is a huge problem for debugging:

  delay(900000); //Delay 15 min.

I'm not sure what you mean by "where it is hanging up", sorry.
I do have a clear view of the sky and like I mentioned, it seems to work fine when it was plugged into the computer.
The delay is too much?

Most likely, the code is getting stuck somewhere - aka "hanging" - meaning it never gets to the bits that so the writing to the SD Card.

If you have other Serial.print() calls in the code, they may be hanging due to there being to USB connection to print over!

Not if you are willing to wait 15 minutes for each debug print.

1 Like

My plan was for it to take measurements every 15 minutes once it is all working. While testing, I can change it no problem.
I'm still not sure what to do do. I will try individual modules and see what happens.

If you want to get debug prints while not connected to USB, you'll need to use a UART and separate UART-to-USB converter - not the Arduino's USB.

So I can't use the mini usb from the battery/power bank directly to the Arduino MKR Zero?
And if I get a UART-to-USB, would I need to change anything on the code?
Thanks.

I very much doubt that it connects data through - but you could try it.

Even if it does, it won't help you, because then you'll be back to having a USB connection - and you're saying that the problem happens is when there is no USB connection!

Alright. Thanks. I'll see what works.

Has anyone solved this problem... getting the MKR Zero to successfully log data to the SD card without being connected to the computer (IDE Serial Monitor)?
Code example from Arduino = https://docs.arduino.cc/tutorials/mkr-zero/mkr-zero-data-logger
Eliminating the "While(!Serial){;}" piece of code renders the entire program useless.
Maybe it's somehow a hardware requirement of the MKR Zero board? If so, can it be faked?
Having a MKR Zero datalogger that MUST be connected to the computer kinda eliminates the need for the MKR Zero.
Thanks, everyone!

Well, I'm an idiot.
It may not be the prettiest solution but in all of my searching nobody has actually posted a solution for the MKR Zero. It appears to be a simple timing issue. A delay(xxx) won't work, but a simple for() loop does the trick. It allows the micro to run and finish initializing the Serial, but doesn't actually require a computer connection to monitor the serial. This allows the MKR Zero to be powered by a USB cable (from a power supply of your choice) and NOT connected to a computer.
Solution = Replace the "while(!Serial){}" with a for() loop.
Example:

void setup() {
  Serial.begin(9600);

  // while (!Serial) {
  //   ;  // wait for serial port to connect. Needed for native USB port only
  // }

  for (int i = 0; i <= 10000; i++) {  // Eliminates the need for the "while (!Serial){}" above.
    ;
  }

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