Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * SD Card Data Logger with Buffered Writing
- *
- * Developed by: 3Domse3
- * Date: 2024-08-27
- * Version: 2.1
- *
- * Description:
- * This Arduino sketch logs the runtime of the microcontroller in microseconds
- * to an SD card. The data is buffered in memory and written to the SD card in
- * larger chunks to improve efficiency. The filename is generated incrementally
- * to avoid overwriting existing files on the SD card.
- *
- * Hardware:
- * - Arduino board (e.g., UNO, Mega)
- * - SD card module connected via SPI
- * - SD card formatted with FAT16/FAT32
- * - Built-in LED used for error indication
- *
- * Pin Connections:
- * - MOSI (pin 11)
- * - MISO (pin 12)
- * - SCK (pin 13)
- * - CS (pin 4)
- * - Built-in LED (pin 13)
- */
- /************************** Section 1: Libraries and Constants **************************/
- #include <SPI.h>
- #include <SD.h>
- // Constants for SD card and LED
- const int chipSelect = 4; // SD card chip select pin
- const int ledPin = LED_BUILTIN; // Built-in LED pin
- // Constants for buffering data
- const int BUFFER_SIZE = 512; // Buffer size in bytes
- /************************** Section 2: Global Variables **************************/
- uint32_t lastMicros = 0; // Last microsecond value read
- uint32_t overflowCount = 0; // Overflow counter for micros()
- uint64_t totalMicros = 0; // Total elapsed time in microseconds
- char dataString[20]; // Buffer for the formatted runtime string
- char fileName[13]; // Buffer for the file name (8.3 format)
- char buffer[BUFFER_SIZE]; // Buffer for storing multiple data strings before writing to SD
- int bufferIndex = 0; // Index to keep track of the current position in the buffer
- File dataFile; // SD file object
- /************************** Section 3: Setup Function **************************/
- void setup() {
- pinMode(ledPin, OUTPUT); // Set the LED pin as output
- Serial.begin(115200);
- while (!Serial) {
- ; // Wait for serial port to connect. Needed for native USB port only
- }
- // Initialize the SD card
- if (!SD.begin(chipSelect)) {
- Serial.println("Card failed, or not present");
- errorBlink(); // Blink LED to indicate error
- }
- // Generate and print the filename
- getIncrementalFilename(fileName);
- Serial.print("File name: ");
- Serial.println(fileName);
- // Open the file for writing
- dataFile = SD.open(fileName, FILE_WRITE);
- if (!dataFile) {
- Serial.println("Failed to open file for writing");
- errorBlink(); // Blink LED to indicate error
- }
- delay(1000); // Optional delay before starting logging
- }
- /************************** Section 4: Loop Function **************************/
- void loop() {
- // Update the runtime buffer with the current runtime
- getRuntime(dataString);
- // Add the data to the buffer
- bufferIndex += snprintf(buffer + bufferIndex, BUFFER_SIZE - bufferIndex, "%s\n", dataString);
- // If the buffer is full, write it to the SD card
- if (bufferIndex >= BUFFER_SIZE - 20) { // Leave space for one more line
- writeBufferToSD();
- }
- // Optional: Output to serial for debugging
- Serial.println(dataString);
- }
- /************************** Section 5: Runtime Calculation **************************/
- void getRuntime(char* buffer) {
- uint32_t currentMicros = micros();
- // Check for overflow
- if (currentMicros < lastMicros) {
- overflowCount++;
- }
- lastMicros = currentMicros;
- // Calculate total elapsed time in microseconds
- totalMicros = ((uint64_t)overflowCount << 32) | (uint64_t)currentMicros;
- // Convert the totalMicros to a string and store it in the buffer
- sprintf(buffer, "%01lu", totalMicros);
- }
- /************************** Section 6: Buffer Management **************************/
- void writeBufferToSD() {
- if (dataFile) {
- dataFile.write(buffer, bufferIndex); // Write the buffer to the SD card
- dataFile.flush(); // Ensure data is written to the card
- bufferIndex = 0; // Reset buffer index after writing
- } else {
- Serial.println("Error: File not open");
- errorBlink(); // Blink LED to indicate error
- }
- }
- void flushBufferOnExit() {
- // Ensure any remaining data in the buffer is written to the SD card
- if (bufferIndex > 0) {
- writeBufferToSD();
- }
- dataFile.close(); // Close the file after writing
- }
- /************************** Section 7: Error Handling **************************/
- void errorBlink() {
- while (true) {
- digitalWrite(ledPin, HIGH); // Turn the LED on
- delay(250); // Wait for 250 ms
- digitalWrite(ledPin, LOW); // Turn the LED off
- delay(250); // Wait for 250 ms
- }
- }
- /************************** Section 8: Filename Generation **************************/
- // Generate the next available incremental filename (e.g., "BUF0001.TXT")
- void getIncrementalFilename(char* buffer) {
- int number = 1; // Start with 1 instead of 0 for better readability
- do {
- sprintf(buffer, "BUF%04d.TXT", number);
- number++;
- } while (SD.exists(buffer));
- }
- /************************** Section 9: Cleanup on Exit **************************/
- // Ensure the buffer is flushed before the program exits
- void __attribute__((destructor)) cleanup() {
- flushBufferOnExit();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement