#include <SD.h>
const int baudRate = 9600;
#define chipSelect 10
unsigned int fileCounter = 1;
#define ANALOG0 A0
unsigned long interval = 1000;
File root;
unsigned long startTime = 0; // Micros and Milis requires unsigned long
struct Date {
int day;
int month;
};
Date date = {10, 10};
void setup() {
SPI_initialization();
SD_initialization();
Serial.println("Files in the card:");
root = SD.open("/");
printDirectory(root, 0);
Serial.println("");
// Ask for date
Serial.println("Enter date in format: MM/DD");
date = extractDateFromInput();
Serial.print("Date entered: ");
Serial.print(date.month);
Serial.print("/");
Serial.println(date.day);
// Ask for Desired File interval
Serial.println("Enter desired file interval (ms): ");
interval = extractIntervalFromInput();
Serial.print("Interval per file: ");
Serial.println(interval);
root = open_SD_tmp_File(fileCounter, date); // Create first file
Serial.print("File Created: ");
Serial.println(root.name());
// root.close();
startTime = millis();
}
void loop() {
unsigned long startTime = millis();
// unsigned long interval = 60000; //30s
Serial.print("----------Start Time");
Serial.println(startTime);
int count = 0;
while (millis() - startTime < interval)
{
int sensorValue = analogRead(ANALOG0);
String timeStamp = getTimeStamp_MMSSXXXX(millis());
// if (millis() % 100 == 0) {
// Serial.println(timeStamp);
// root.print(timeStamp);
// root.print(",");
// root.println(sensorValue);
// Serial.println("writing to file");
// }
// delay(5); // Wait for stability
root.print(timeStamp);
root.print(",");
root.println(sensorValue);
count ++ ;
}
root.close();
Serial.print("---------------Count:");
Serial.println(count);
Serial.print("---------------End Time:");
Serial.println(millis()- startTime);
// change the extension
// while written .tmp
// when closed .txt
// root = open_SD_tmp_File(fileCounter, date);
// if (root) {
// Serial.print(root.name());
// while (root.available()) {
// Serial.write(root.read());
// }
// root.close();
// }
// else {
// Serial.println("error opening!");
// }
fileCounter++;
if (fileCounter >= 1)
{
Serial.println("\nMaximum number of files created. Data logging stopped.");
Serial.print("file count... ");
Serial.println(fileCounter);
Serial.println("\nFiles in the card:");
root = SD.open("/");
printDirectory(root, 0);
Serial.println("");
// Example of reading file from the card:------------------
// File textFile = SD.open(root.name);
// if (textFile) {
// Serial.print("wokwi.txt: ");
// while (textFile.available()) {
// Serial.write(textFile.read());
// }
// textFile.close();
// } else {
// Serial.println("error opening wokwi.txt!");
// }
//-----------------------------------------------------
while (1)
;
} }
void printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
unsigned long extractIntervalFromInput() {
unsigned long interval_ms = 1000;
while (true) {
if (Serial.available() > 0) {
String userInput = Serial.readStringUntil('\n');
if (sscanf(userInput.c_str(), "%d", &interval_ms) == 1) {
// Successfully extracted interval
break;
} else {
Serial.println("Invalid");
}
}
// Add a small delay between checks to avoid excessive processor load
delay(100);
}
return interval_ms;
}
// Initialize SPI communication ------------------------------------------------------------------
void SPI_initialization()
{
// Open serial communications by initializing serial obj @ baudRate
// - Standard baudRate = 9600
Serial.begin(baudRate);
// Wait wait up to 15 seconds for Arduino Serial Monitor / serial port to connect
// - Needed for native USB port only
// - Ensure only one monitor is open
while (!Serial && millis() < 15000)
{
;
}
Serial.println("Serial Communication Secured");
}
// Initialize SD communication ------------------------------------------------------------------
void SD_initialization()
{
Serial.print("Initializing SD card... ");
// Check access to SD card "Initialize the SD card"
// - Chipselect pin is different per board
if (!SD.begin(chipSelect))
{
Serial.println("initialization failed!");
while (1)
; // endless loop which "stops" any useful function
// this may need to be changed to a user controlled break later
}
Serial.println("initialization done.");
}
Date extractDateFromInput() {
Date extractedDate = {0, 0};
while (true) {
if (Serial.available() > 0) {
String userInput = Serial.readStringUntil('\n');
if (sscanf(userInput.c_str(), "%d/%d", &extractedDate.month, &extractedDate.day) == 2) {
// Successfully extracted both month and day, break the loop
// setTime(0,0,0,extractedDate.day, extractedDate.month,2023);
break;
} else {
Serial.println("Invalid input format. Please enter in format: MM/DD");
}
}
// Add a small delay between checks to avoid excessive processor load
delay(100);
}
return extractedDate;
}
File open_SD_tmp_File(int fileIndex, Date date)
{
// Serial.print("\nInitilizing write to file... ");
//.tmp
String fileName = twoDigits(date.month) + twoDigits(date.day) + fourDigits(fileIndex) + ".txt";
File newFile = SD.open(fileName, FILE_WRITE);
if (newFile)
{
// Serial.println("File created successfully!");
return newFile;
}
else
{
Serial.println("Error creating file!");
while(1); // Stop recording if the file creation fails
}
return newFile;
}
String getTimeStamp_MMSSXXXX(unsigned long now)
{
/*
This function uses modulo to compute values
** 1 min = 60_000 ms
** 1 sec = 1_000 ms
** ms range: [0 - 1000]
*/
unsigned long minutes = (now / 60000 ) % 60;
unsigned long seconds = (now / 1000 ) % 60;
unsigned long milliseconds = now % 1000;
String timeStamp = "";
// timeStamp += "(MM:SS:XXXX): ";
timeStamp += twoDigits(minutes);
timeStamp += ":";
timeStamp += twoDigits(seconds);
timeStamp += ":";
timeStamp += fourDigits(milliseconds);
timeStamp += "\tRaw(ms):";
timeStamp += String(now);
return timeStamp;
}
String twoDigits(int digits)
{
if (digits < 10)
{
return "0" + String(digits);
}
else
{
return String(digits);
}
}
String fourDigits(int digits)
{
if (digits < 10)
{
return "000" + String(digits);
}
else if (digits < 100)
{
return "00" + String(digits);
}
else if (digits < 1000)
{
return "0" + String(digits);
}
else
{
return String(digits);
}
}