Hello, I have a project I’m working on that records data to a .txt file currently after taking in samples from the LSM6DS3 chip in the NRF52840 microcontroller. I used the high level example to implement that and have used various resources to come up with the code I have. One question that still plagues me is the ability to check the remaining space on the SD card every so often, which is why Im using SdFat.h rather than SD.h. I wouldn’t want to stop reading in data through a double tap or other means as that can be fallible (with me forgetting to stop data recording) and would prefer something that recognizes if theres less than a random number chosen on the SD card, for example less than a gigabyte. If anyone has any insight or tips they could give that would be appreciated
// Setting up libraries for LSM6DS3 and SD Card implementation
#include <Arduino.h>
#include <LSM6DS3.h>
#include <Wire.h> // Wire is needed for the movement sensor
#include <SdFat.h>
// Creating variables needed for the program
SdFat sdCard;
int num = 0;
SdFile myFile;
char fileName[] = "MovementData.txt";
bool hasSpace = true;
// Change this variable to match the SD chip
const int chipSelect = 2;
LSM6DS3 myIMU(I2C_MODE, 0x6A);
float aX, aY, aZ, gX, gY, gZ;
const float accelerationThreshold = 1.5;
const int numSamples = 10;
int samplesRead = numSamples;
// START OF FUNCTION DECLARATION
/**
* void InitializeSerial()
* Summary :
* Initializes the Serial port so we can get messages from the microcontroller if
* certain portions have been initialized correctly
*
* Parameters : None.
*
* Return Value : Nothing.
*/
void InitializeSerial() {
Serial.begin(9600);
while(!Serial) {
; // waiting for serial port to connect
}
}
/**
* void InitializeSDCard()
* Summary :
* Initializes the SD card inserted
*
* Parameters : None.
*
* Return Value : Nothing.
*/
void InitializeSDCard() {
Serial.print("Initializing the SD Card");
if(!sdCard.begin(chipSelect, SPI_FULL_SPEED)) {
sdCard.initErrorHalt();
} else {
Serial.println("Wiring is correct and a card was found!");
}
}
/**
* void OpenFile()
* Summary :
* Opens a file, ready to write into, prints out error or success
*
* Parameters : None.
*
* Return Value : Nothing.
*/
void OpenFile() {
if (!myFile.open(fileName, O_CREAT | O_WRITE)) {
sdCard.errorHalt("opening movementData.txt for write failed");
}
// if the file opened okay, write to it:
Serial.println("movementData.txt correctly Opened");
}
/**
* void CloseFile()
* Summary :
* Closes a file, prints out error or success
* THIS SHOULD BE USED AFTER THE OPEN FILE, NEVER BEFORE
* Parameters :
*
* Return Value : Nothing.
*/
void CloseFile() {
Serial.println("Closing File");
myFile.close();
}
/**
* void InitializeMotionSensor()
* Summary :
* Initializes the motion sensor chip, the LSM6DS3
*
* Parameters : None.
*
* Return Value : Nothing.
*/
void InitializeMotionSensor() {
if(myIMU.begin() != 0) {
Serial.println("Motion Sensors Error");
while(1);
} else {
Serial.println("Motion Sensors Ready");
}
}
/**
* bool CheckForMotion()
* Summary :
* Checks for Significant motion
*
* Parameters : None.
*
* Return Value : If significant motion, returns true, else false
*/
bool CheckForMotion() {
samplesRead = 0;
aX = myIMU.readFloatAccelX();
aY = myIMU.readFloatAccelY();
aZ = myIMU.readFloatAccelZ();
float aSum = fabs(aX) + fabs(aY) + fabs(aZ);
if(aSum >= accelerationThreshold) {
Serial.println("Significant Motion Detected");
return true;
} else {
Serial.println("Significant Motion Not Detected");
return false;
}
}
/**
* void RecordData()
* Summary :
* Records Data for amount of samples
*
* Parameters : None.
*
* Return Value : None.
*/
void RecordData() {
Serial.println("Started Recording Data");
while(samplesRead < numSamples) {
myFile.print("Acceleration X: ");
myFile.println(myIMU.readFloatAccelX());
myFile.print("Acceleration Y: ");
myFile.println(myIMU.readFloatAccelY());
myFile.print("Acceleration Z: ");
myFile.println(myIMU.readFloatAccelZ());
myFile.print("Gyroscope X: ");
myFile.println(myIMU.readFloatGyroX());
myFile.print("Gyroscope Y: ");
myFile.println(myIMU.readFloatGyroY());
myFile.print("Gyroscope Z: ");
myFile.println(myIMU.readFloatGyroZ());
Serial.print("Number of Samples Taken: ");
Serial.println(samplesRead);
samplesRead++;
}
Serial.println("Stopped Recording Data");
}
/**
* bool HasSpace(long v);
* Summary :
* Checks if there is enough space remaining in the SD Card
*
* Parameters: v: volume of the card
*
* Return: True if there is enough space, false if not
*/
bool HasSpace(long v) {
if(v < 5) { // this is checking if its less than 5 kb
return false;
} else {
return true;
}
}
/**
* uint32_t ShowFreeSpace();
* Summary :
* Shows space remaining in the SD Card
*
* Parameters: None.
*
* Return: a value of remaining kB
*/
void ShowFreeSpace() {
// Calculate free space (volume free clusters * blocks per clusters / 2)
long lFreeKB = sdCard.vol()->freeClusterCount();
lFreeKB *= sdCard.vol()->sectorsPerCluster()/2;
// return free space in KB
Serial.println(lFreeKB);
}
// END OF FUNCTION DECLARATION
void setup() {
// put your setup code here, to run once:
InitializeSerial();
OpenFile();
InitializeSDCard();
InitializeMotionSensor();
}
void loop() {
if(CheckForMotion()) {
RecordData();
}
CloseFile();
}