HI,
I've recently improved the write speed using a nano and I'd like to try the same thing on an esp32 I have. Unfortunately it's not a straight swap and I've found out some understanding of how the esp32 works has been needed.
All I'm trying to do is write accelerometer data to the SD card. To test it I wrote a little state machine using the nano, then tried the same thing on the esp32. Firstly I don't seem to be able to use Sdfat (that I know of, which I'm happy with for now). Secondly after looking at the SD_Test example I have to include a library called FS.h, which from what I understand is a filing system library. I've ended up completely confusing myself and not having a clue what is going on any more.
I really don't get what's going on in this part to be honest and what the arguments mean.
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();
}
After looking at some further examples online I noticed people weren't using the FS.h at all and just writing the code as you would for the Uno/Nano etc.
I gave it a go but for some reason the timer doesn't seem to be working on the esp32 version but there is not an issue on the nano version of the code.
So I it basically loops in Case 1 and never makes to to Case 2 to close the file.
I'd appreciate any help with this one as I just don't get it. It might just be that I've been looking at it too long. I feel like it's something obvious but just can't see it.
Thank you
Nano Code with SdFat.h, works fine
#include <Wire.h>
#include "SdFat.h"
#include "RTClib.h"
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
//----------------------
// I2C
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//SD Card
SdFat SD;
File dataFile;
const uint8_t SD_CHIP_SELECT = 10;
//SD Filename
char fileName[25];
//RTC2321
RTC_DS3231 rtc;
char DateAndTime[20];
//----------------------
//Millis Setup
unsigned long currentTime = 0;
unsigned long previousTime = 0;
unsigned long accelTime = 0;
const unsigned long sampleRate = 10;
const unsigned long recordPeriod = 60000;
const unsigned long timeStamp = 1000; //Stamp every 1 second
char accelX[7];
char accelY[7];
char accelZ[7];
char accelData[28];
int recordAccel = 0;
//=====================================================================
void setup(void) {
Serial.begin(115200);
//LIS3DH Accelerometer
lis.begin(0x18);
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
//RTC
rtc.begin(); //Start RCT
//SD Card
SD.begin();
SdFile::dateTimeCallback(dateTime); //timestamp file
}
//=====================================================================
void loop() {
SM();
}
//=====================================================================
void SM() {
switch (recordAccel) {
case 0: //Open SD Card
openCard();
recordAccel = 1;
break;
case 1: //Record Data
Accel();
currentTime = millis();
if (currentTime >= recordPeriod) {
recordAccel = 2;
}
break;
case 2: //Close SD card
closeCard();
break;
}
}
void openCard() {
getFileName();
dataFile = SD.open(fileName, FILE_WRITE);
}
void closeCard() {
dataFile.close();
}
void Accel() {
sensors_event_t event;
lis.getEvent(&event);
dtostrf(event.acceleration.x, 5, 3, accelX);
dtostrf(event.acceleration.y, 5, 3, accelY);
dtostrf(event.acceleration.z, 5, 3, accelZ);
sprintf(accelData, "%s,%s,%s", accelX, accelY, accelZ);
if (dataFile) {
//if (currentTime >= accelTime + sampleRate) {
dataFile.println(accelData);
//accelTime = currentTime;
if (currentTime - previousTime >= timeStamp) {
DateTime now = rtc.now();
sprintf(DateAndTime, ",%02d/%02d/%02d,%02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
dataFile.print(accelData);
dataFile.println(DateAndTime);
previousTime = currentTime;
}
}
}
//}
//=======================================================================
void getFileName() {
DateTime now = rtc.now();
sprintf(fileName, "Accel_%02d%02d%02d_%02d%02d.csv", now.year(), now.month(), now.day(), now.hour(), now.minute());
}
//=======================================================================
void dateTime(uint16_t* date, uint16_t* time) {
//used for callback function for file timestamp
DateTime now = rtc.now();
// return date using FAT_DATE macro to format fields
*date = FAT_DATE(now.year(), now.month(), now.day());
// return time using FAT_TIME macro to format fields
*time = FAT_TIME(now.hour(), now.minute(), now.second());
}
Esp32 code with SD.h, not working, making me feel a little crazy. You'll notice the offending append function commented out because I just didn't get what was going on can changed it all to FILE_WRITE.
/*
Connect the SD card to the following pins:
SD Card | ESP32
D2 -
D3 SS
CMD MOSI
VSS GND
VDD 3.3V
CLK SCK
VSS GND
D0 MISO
D1 -
*/
#include <Wire.h>
//#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include "RTClib.h"
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
//----------------------
// I2C
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//SD Card
File dataFile;
//File file;
const uint8_t SD_CHIP_SELECT = 5;
//SD Filename
char fileName[25];
//RTC2321
RTC_DS3231 rtc;
char DateAndTime[20];
//----------------------
//Millis Setup
unsigned long currentTime = 0;
unsigned long previousTime = 0;
unsigned long accelTime = 0;
const unsigned long sampleRate = 10;
const unsigned long recordPeriod = 5000;
const unsigned long timeStamp = 1000; //Stamp every 1 second
char accelX[7];
char accelY[7];
char accelZ[7];
char accelData[28];
int recordAccel = 0;
//=====================================================================
void setup() {
Serial.begin(115200);
//LIS3DH Accelerometer
lis.begin(0x18);
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
//RTC
rtc.begin(); //Start RCT
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//SD Card
SD.begin();
}
//=======================================================================
void loop() {
SM();
}
//=======================================================================
void SM() {
switch (recordAccel) {
case 0: //Open SD Card
openCard();
currentTime = (esp_timer_get_time()/1000);
recordAccel = 1;
break;
case 1: //Record Data
Accel();
if (currentTime >= recordPeriod) {
recordAccel = 2;
}
break;
case 2: //Close SD card
closeCard();
break;
}
}
//=======================================================================
void openCard() {
getFileName();
dataFile = SD.open(fileName, FILE_WRITE);
}
//=======================================================================
void closeCard() {
dataFile.close();
}
//=======================================================================
/*void appendFile(fs::FS &fs, const char * path, const char * message) {
Serial.printf("Appending to file: %s\n", path);
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 Accel() {
sensors_event_t event;
lis.getEvent(&event);
dtostrf(event.acceleration.x, 5, 3, accelX);
dtostrf(event.acceleration.y, 5, 3, accelY);
dtostrf(event.acceleration.z, 5, 3, accelZ);
sprintf(accelData, "%s,%s,%s", accelX, accelY, accelZ);
if (dataFile) {
//if (currentTime >= accelTime + sampleRate) {
dataFile.println(accelData);
//accelTime = currentTime;
if (currentTime - previousTime >= timeStamp) {
DateTime now = rtc.now();
sprintf(DateAndTime, ",%02d/%02d/%02d,%02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
dataFile.print(accelData);
dataFile.println(DateAndTime);
previousTime = currentTime;
}
}
}
//}
//=======================================================================
void getFileName() {
DateTime now = rtc.now();
sprintf(fileName, "/Accel_%02d%02d%02d_%02d%02d.csv", now.year(), now.month(), now.day(), now.hour(), now.minute());
}
//=======================================================================
/*void dateTime(uint16_t* date, uint16_t* time) {
//used for callback function for file timestamp
DateTime now = rtc.now();
// return date using FAT_DATE macro to format fields
date = FAT_DATE(now.year(), now.month(), now.day());
// return time using FAT_TIME macro to format fields
time = FAT_TIME(now.hour(), now.minute(), now.second());
}*/