Vibration monitoring system - File name and data upload

Hi Everyone,

I'm new to coding and using Arduino and I was hoping someone might be able to help with a few issues I'm having with a project I'm working on.

I'm creating a vibration monitoring system to record the vibration created when a wheel crosses a gap in the surface it is rolling on. The wheel will be roll back and forth over this gap multiple times a day and each crossing must be recorded. In the final version of this I intend to incorporate a trigger system that will activate the recording, but for the time being having the recording controlled by a set delay is sufficient, as this is more of a proof case rather than the final product.

The hardware being used is an ESP32-DevkitC-V4, connected to a Model 4030 TE connectivity triaxial accelerometer, and a micro-Sd card module.

The accelerometer data is recorded and stored on the micro-SD card, and the csv produced is ideal for the post processing and visualization work I will be doing. I have written this code so that each crossing will be grouped with a group ID. This is done by having each reading assigned an ID and once this number reaches a certain value (depending on the sampling rate and recording time I want) the recording will stop and then a new group ID will be assigned for the next group of readings.

Current code:

// Libraries for SD card
#include "FS.h"
#include "SD.h"
#include "SPI.h"

// Define CS pin for the SD card module
#define SD_CS 5

// ID integers
int readingID = 1;
int groupID = 1;

String dataMessage;

// Sensor variables
float sensorPinX = 34;    // select the input pin for the potentiometer
float sensorPinY = 32;
float sensorPinZ = 35;

float sensorValueX = 0;  // variable to store the value coming from the sensor
float sensorValueY = 0;
float sensorValueZ = 0;


// Write to the SD card (DON'T MODIFY THIS FUNCTION)
void writeFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if(!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if(file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

// Append data to the SD card (DON'T MODIFY THIS FUNCTION)
void appendFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if(!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if(file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

void setup() {
  // Start serial communication for debugging purposes
  Serial.begin(115200);

  // Initialize SD card
  SD.begin(SD_CS);  
  if(!SD.begin(SD_CS)) {
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();
  if(cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }
  Serial.println("Initializing SD card...");
  if (!SD.begin(SD_CS)) {
    Serial.println("ERROR - SD card initialization failed!");
    return;    // init failed
  }

  // If the .txt file doesn't exist
  // Create a file on the SD card and write the data labels
  File file = SD.open("/accelerometer.csv");
  if(!file) {
    Serial.println("File doens't exist");
    Serial.println("Creating file...");
    writeFile(SD, "/accelerometer.csv", "Group ID, Reading ID, X, Y, Z, SR = 100Hz, Sample Interval = 10s, Group Interval = 5min  \r\n");
  }
  else {
    Serial.println("File already exists");  
  }
  file.close();
}

void loop() {

  //for loop to group 1000 readings
  //the groupID then increases by 1
  //this would be a single pass
  for (int groupID = 1; groupID <=300; groupID++){
    //readings sampled at 100Hz for 10s
    for (int readingID = 1; readingID <=1000; readingID++){
      // read the value from the sensor:
      sensorValueX = analogRead(sensorPinX)-2895;
      sensorValueY = analogRead(sensorPinY)-2903;
      sensorValueZ = analogRead(sensorPinZ)-4095;
    
      //prints sensor readings with group and reading IDs:
      Serial.print("G-ID = ");
      Serial.print(groupID);
      Serial.print("\t");
      Serial.print("R-ID = ");
      Serial.print(readingID);
      Serial.print("\t");
      Serial.print("X = ");
      Serial.print(sensorValueX);
      Serial.print("\t");
      Serial.print("Y = ");
      Serial.print(sensorValueY);
      Serial.print("\t");
      Serial.print("Z = ");
      Serial.print(sensorValueZ);
      Serial.println();
      //using the raw code from this function allows the correct int values to be used
      //if pre-defined the wrong values are used:
      dataMessage = String(groupID) + "," + String(readingID) + "," + String(sensorValueX) + "," + String(sensorValueY) + "," + 
                    String(sensorValueZ) + "\r\n";
      Serial.print("Save data: ");
      Serial.println(dataMessage);
      appendFile(SD, "/accelerometer.csv", dataMessage.c_str());
      //sample rate
      delay(10);
    }
  //time between groups
  delay(60000);
  }

delay(10000);    
}

However, the issues I am facing are the naming of the .csv produced and the uploading of that .csv to a cloud server.

I want each cycle to create a new .csv file with the time and date as the file name – In this format YYMMDDHH:mm:ss.

I then want this file uploaded from the SD card to the cloud server to allow for remote access, as once installed I will not have access to the board or SD card.

Any advice would be greatly appreciated!

Thanks!

Unfortunately, the SD library supports only 8.3 format file names. Create a longer one when you upload the file to the cloud.

Thanks! I was aware of the limitations of the file naming, but the formet i stated above is just as an example.

As long as I can create a variable file name the actual name doesn't matter.

For example I could just call them passXXXX.csv and than the XXXX be the groupID - If thats possible.

I can then just have the time stamp recorded within the file along side the readingID.

Would that work?

I would use snprintf() to create a variable file name, for example

char filename[14]={0};
int id=1234;  //arbitrary file id, at most four digits
snprintf(filename,sizeof(filename),"pass%04d.csv",id);  //zero filled, example pass0785.csv
File file=SD.open(filename);

See the C/C++ reference for printf(), for a complete list of the format specifiers.

Incidentally, on an AVR-base Arduino, avoid Strings. They cause program malfunctions and crashes.

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