I have written this code and cannot see what the issue is and why it keeps failing, im using an arduino R4 minima with an sd shield and an mpu6050 accelorimitor, the data starts to record on the sd card and after 11 data entries the logger stops, any help on this would be appreciated.
the idea of the code is to know the state of a machine using a limit switch, motion detection and the status of an ldr
/*
Live 5. 24/02/2025. 11:53
*/
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <SD.h>
// Pin Definitions
#define LIMIT_SWITCH_PIN 2
#define LDR_PIN 3
#define SD_CS_PIN 10
#define ERROR_LED_PIN 12
#define STATUS_LED_PIN 13 // Status LED pin
//#define MPU_INT_PIN 4 // Interrupt pin for MPU6050
// Constants
const unsigned long DAY_INTERVAL = 86400000; // 24 hours in milliseconds
const long LOGGING_INTERVAL = 15000; // Log every 15 seconds
const int MAX_DAYS = 7; // Maximum of 7 days of logging
const long MOVEMENT_DETECTION_WINDOW = 8000; // 8 seconds for motion detection
const long LDR_CHECK_INTERVAL = 100; // 10000 ms for frequent LDR checks
// Objects
Adafruit_MPU6050 mpu;
// Global Variables
File logFile;
unsigned long previousMillis = 0;
unsigned long dayStartMillis = 0;
unsigned long lastMovementMillis = 0;
unsigned long lastLdrCheckMillis = 0;
int currentDay = 0;
bool sdInitialized = false;
bool movementDetected = false;
bool lightDetected = false;
String allData[MAX_DAYS];
int ldrReadings[5] = {0}; // Store last 5 LDR readings for averaging
int ldrIndex = 0;
int currentFileIndex = 1; // To store the current file number (data1, data2, etc.)
bool sdWasRemoved = false; // To track if SD card was removed
int highestFileIndex = 0; // To track the highest file index found
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("Initializing...");
pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
pinMode(LDR_PIN, INPUT);
pinMode(ERROR_LED_PIN, OUTPUT);
pinMode(STATUS_LED_PIN, OUTPUT);
// pinMode(MPU_INT_PIN, INPUT);
digitalWrite(ERROR_LED_PIN, LOW);
digitalWrite(STATUS_LED_PIN, LOW);
initializeSD();
//initializeMPU();
// Initialize MPU6050
if (!mpu.begin()) {
Serial.println("MPU6050 initialization failed!");
while (true); // Stop execution if MPU initialization fails
}
Serial.println("MPU6050 initialized.");
mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ);
mpu.setMotionDetectionThreshold(1); // Set motion detection threshold
mpu.setMotionDetectionDuration(20); // Set duration for motion detection
mpu.setInterruptPinLatch(true); // Latch interrupt pin status
mpu.setInterruptPinPolarity(true); // Set interrupt pin polarity
mpu.setMotionInterrupt(true); // Enable motion interrupt
// Initialize timing
dayStartMillis = millis(); // Set the starting time for day tracking
}
void loop() {
unsigned long currentMillis = millis();
// If SD card is not initialized, attempt to reinitialize it
if (!sdInitialized) {
Serial.println("SD card not available. Attempting reinitialization...");
initializeSD();
delay(1000);
return;
}
// Handle day increment
if (currentMillis - dayStartMillis >= DAY_INTERVAL) {
dayStartMillis += DAY_INTERVAL;
currentDay++;
if (currentDay >= MAX_DAYS) {
Serial.println("Maximum logging period reached (7 days). Stopping.");
digitalWrite(STATUS_LED_PIN, LOW);
while (true);
}
}
// Handle movement detection
if (mpu.getMotionInterruptStatus()) {
lastMovementMillis = currentMillis;
movementDetected = true;
} else if (currentMillis - lastMovementMillis > MOVEMENT_DETECTION_WINDOW) {
movementDetected = false; // Reset movement detection if no movement for 2 seconds
}
// Check LDR state every 100 ms
if (currentMillis - lastLdrCheckMillis >= LDR_CHECK_INTERVAL) {
lastLdrCheckMillis = currentMillis;
ldrReadings[ldrIndex] = digitalRead(LDR_PIN);
ldrIndex = (ldrIndex + 1) % 5;
int sum = 0;
for (int i = 0; i < 5; i++) sum += ldrReadings[i];
lightDetected = (sum >= 3);
}
// Handle movement detection
if (currentMillis - lastMovementMillis > MOVEMENT_DETECTION_WINDOW) {
movementDetected = false;
}
// Check if SD card is still present (every loop iteration)
if (!SD.begin(SD_CS_PIN)) {
if (!sdWasRemoved) {
Serial.println("SD card removed. Stopping logging.");
digitalWrite(ERROR_LED_PIN, HIGH);
blinkStatusLED(1); // Blink once per second for SD card problem
sdWasRemoved = true;
sdInitialized = false;
}
} else {
// SD card is reinserted, resume logging
if (sdWasRemoved) {
Serial.println("SD card reinserted. Resuming logging...");
sdWasRemoved = false;
initializeSD(); // Reinitialize SD card and continue from previous file
}
// If SD card is present, continue logging
sdInitialized = true;
digitalWrite(ERROR_LED_PIN, LOW); // Ensure error LED is off if SD is available
// Solid LED indicating normal operation
digitalWrite(STATUS_LED_PIN, HIGH);
// Log data every 15 seconds
if (currentMillis - previousMillis >= LOGGING_INTERVAL) {
previousMillis = currentMillis;
bool isHome = digitalRead(LIMIT_SWITCH_PIN) == LOW;
String state = determineState(isHome, lightDetected, movementDetected);
allData[currentDay] = state;
// Open the current log file (data1.csv, data2.csv, etc.)
logFile = SD.open("data" + String(currentFileIndex) + ".csv", FILE_WRITE);
if (logFile) {
// If this is the first time the file is being created, write the header
if (logFile.size() == 0) {
logFile.print("Time (ms)"); // Log time column
for (int i = 0; i < MAX_DAYS; i++) {
logFile.print(",Day ");
logFile.print(i + 1); // Log days as columns
}
logFile.println(); // Add the header row
}
logFile.println(String(currentMillis) + "," + allData[currentDay]);
logFile.close();
Serial.println("Logged: " + state);
} else {
Serial.println("Failed to open log file! Reinitializing SD card...");
digitalWrite(ERROR_LED_PIN, HIGH);
digitalWrite(STATUS_LED_PIN, LOW);
sdInitialized = false;
}
}
}
}
void motionDetectedISR() {
lastMovementMillis = millis();
movementDetected = true;
}
void initializeSD() {
//int highestFileIndex = 0; // To track the highest file index found
// Scan the SD card for existing data files (data1.csv, data2.csv, etc.)
for (int i = 1; i <= 100; i++) { // Assuming up to 100 files max (data1 to data100)
String filename = "data" + String(i) + ".csv";
if (SD.exists(filename)) {
highestFileIndex = i; // Update if a higher numbered file is found
}
}
// Set the current file index to the next available file
currentFileIndex = highestFileIndex + 1;
// Initialize the SD card
if (SD.begin(SD_CS_PIN)) {
sdInitialized = true;
Serial.println("SD card initialized successfully.");
digitalWrite(STATUS_LED_PIN, HIGH); // Solid LED indicating SD card is ready
} else {
Serial.println("SD card failed to initialize. Logging disabled.");
digitalWrite(ERROR_LED_PIN, HIGH);
digitalWrite(STATUS_LED_PIN, LOW);
}
}
String determineState(bool isHome, bool lightDetected, bool movementDetected) {
if (isHome) return "Home";
if (!isHome && lightDetected && movementDetected) return "Traversing";
if (!isHome && !lightDetected) return "Cutting";
if (!isHome && lightDetected && !movementDetected) return "Error";
return "Unknown";
}
// Blink the status LED based on the pattern passed in the argument
void blinkStatusLED(int blinkRate) {
unsigned long currentMillis = millis();
static unsigned long previousBlinkMillis = 0;
static bool ledState = LOW;
// Set blink interval based on the blink rate
int blinkInterval = 1000 / blinkRate; // Calculate interval based on blink rate
if (currentMillis - previousBlinkMillis >= blinkInterval) {
ledState = !ledState;
digitalWrite(STATUS_LED_PIN, ledState);
previousBlinkMillis = currentMillis;
}
}