Data logger using analogRead and SPI Flash resetting/crashing for unknown reason

I’m working on a small datalogger that will read from an analog hall sensor and write changes in the value of the reading to the 2MB SPI Flash built in to the Adafruit ItsyBitsy M0 Express, and the Adafruit SPI Flash libraries. The hall sensor is a DRV5053VA, with wiring :
VCC->Pin A1
OUT->Pin A0.
i’m powering the sensor from a data pin so that i can easily turn it on and off to save power. The sensor uses a max of 3.6 mA according to the datasheet. The whole project is powered by a 2000mah Lipo battery, though i’ve also been testing with USB power and i get problems either way.

I’ve cut out all other code, so that i just have the datalogging functions to post here.
Every 60 cycles (~30 seconds) it records a reference reading, then compare subsequent readings to it. If they are sufficiently different, it writes those to the datafile. After 600 cycles (~5 minutes) i flush the data file. I put the board to sleep using the SleepyDog library for 500ms between reads.

The program works fine for several minutes to over an hour, but it always eventually crashes/resets, usually within an hour (indicated by looking at the resulting data file). I’ve checked the SRAM using freeMemory() and it still says i have >24K available.

I’m at a loss as to what to try next. It seems so simple that i must be missing something obvious, but then i’m new to programming arduino so that seems likely. I would greatly appreciate any advice on what to look for or where i’ve screwed up.

#include <Adafruit_FlashTransport.h>
#include <Adafruit_FlashCache.h>
#include <flash_devices.h>
#include <Adafruit_SPIFlash.h>
#include <SPI.h>
#include <SdFat.h>
#include <Adafruit_SleepyDog.h>
#include <RTCZero.h>

//using Adafruit Itsybitsy M0 Express, with builtin 2mb SPI Flash. 
//breadboard connections to DRV5053 analog hall sensor: A0->input, A1->VCC, Grd->ground

// Configuration for the datalogging file:
#define FILE_NAME      "data1.csv"
#define SamplesPerRef 60 //number of cycles before resetting the reference value
#define SamplesPerWrite 600 //number of cycles before flushing the data file

#define hallin 14 // this is the input pin A0 from the Hall sensor
#define hallpower 15 // this is the pin A1 we turn on to power the Hall sensor

/* Create an rtc object */
RTCZero rtc;

/* Change these values to set the current initial time */
byte seconds = 0;
byte minutes = 0;
byte hours = 0;

/* Change these values to set the current initial date */
byte day = 17;
byte month = 5;
byte year = 20;

boolean first = true;
boolean firstanomaly = true; //if first anomaly in a series, run the loop
uint16_t ref; //reference reading
uint8_t RefCycleCount = 0; //count of cycles before resetting reference
uint16_t WriteCycleCount = 0; //count of cycles before flushing data file
uint16_t sameCount = 0; //count of readings in a write cycle that are the same as the reference
uint16_t reading; //value read from sensor using read hall
boolean written = false;
File dataFile;

Adafruit_FlashTransport_QSPI flashTransport;

Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);

#error No QSPI/SPI flash are defined on your board variant.h !

Adafruit_SPIFlash flash(&flashTransport);

// file system object from SdFat
FatFileSystem fatfs;

void setup() {
  // Setup all unused pins (digital and analog) to OUTPUT mode (default is nothing) to save power. Doesn't screw up Flash SPI cuz that's on 36-39
  for (uint8_t ul = 0 ; ul < 32 ; ul++ )
    pinMode( ul, OUTPUT ) ;
  pinMode(hallin, INPUT);      // sets the hall sensor input pin as input

  // Initialize flash library and check its chip ID.
  if (!flash.begin()) {
    while (1);

  // First call begin to mount the filesystem.  Check that it returns true
  // to make sure the filesystem was mounted.
  if (!fatfs.begin(&flash)) {
    while (1);

  //now set the rtc
  rtc.setTime(hours, minutes, seconds);
  rtc.setDate(day, month, year);

void loop() {
  if (first == true) {
    ref = readhall(10); //define the reference
    first = false;
    dataFile =, FILE_WRITE); //open the data file for writing
    dataFile.print("START LOG: "); //dataFile.print (tortname);
    dataFile.print(" "); PrintDate(); PrintTime(); dataFile.println(); // print the Start log line with date and time

  reading = readhall(10);   //first, take a reading

  RefCycleCount += 1;   //increment the Cycle Counts
  WriteCycleCount += 1;

  if (RefCycleCount >= SamplesPerRef) {
    ref = reading; //set reference to the current read every SampelsPerRef cycles
    RefCycleCount = 0;

  if (abs(reading - ref) < 4) { //if the reading is the same as the reference (ie less than 4 units difference in value)
    sameCount += 1; //increment the sameCount for this write cycle
    firstanomaly = true; //reset firstanomaly, since we're now back to reference

  } else { //however, if the reading indicates an anomaly...
    if (firstanomaly) { //only for the first anomaly, print the time and the anomaly reference value
      dataFile.println(); PrintTime();  
      dataFile.print("a"); dataFile.println(ref); //write the reference for this anomaly series
      firstanomaly = false; //after this, any subsequent anomalies before a return to reference values will not print time or reference value
    dataFile.println(reading); ///write the anomalous reading to the data file

  //If write cycle is up, flush file
  if ( WriteCycleCount >= SamplesPerWrite ) {
  int sleepMS = Watchdog.sleep(500);


int readhall(int samples) {
  digitalWrite(hallpower, HIGH);   // turns on the sensor
  uint16_t measure = 0;
  for (int i = 0; i < samples; i++) {
    measure += analogRead(hallin);
  digitalWrite(hallpower, LOW);   // turns off the sensor
  return measure / samples;

void PrintTime() {

void PrintDate() {
  dataFile.print(" ");


void WriteToFile() {
  WriteCycleCount = 0;
  if (rtc.getHours() == 0) { //if it's the first hour of the day, write the date
  dataFile.print("r"); dataFile.print(ref); //prints the reference value so we can keep track of any drift
  dataFile.print("a"); dataFile.println(SamplesPerWrite - sameCount);//prints the number of anomalous readings
  //dataFile.print(freeMemory());  //print SRAM to see if this is the problem
  sameCount = 0; //reset the sameCount for the next write cycle
  digitalWrite(13, HIGH); delay(500); digitalWrite(13, LOW); //blink so i know you're still going
  //dataFile.close(); //close the file to flush the buffer and actually write the printed data to flash


void print2digits(int number) {
  if (number < 10) {
    dataFile.print("0"); // print a 0 before if the number is < than 10