Could you help me on writing Struct data in Particle file system as text/csv file?
typedef struct {
int humidity;
time_t timestamp;
const char * date_time;
String device_id;
} SensorData;
Could you help me on writing Struct data in Particle file system as text/csv file?
typedef struct {
int humidity;
time_t timestamp;
const char * date_time;
String device_id;
} SensorData;
Your date_time
would need to be a character array, and not a mere pointer to some memory which will definitely not hold the same date once you retrieve that pointer
However, a UNIX epoch timestamp can be held in an int32_t
much more compact and can be used for calculations much easier too - in order to format such a numeric timestamp you can use Time.format()
anytime - hence I’m not sure why you want to store timestamp
and date_time
in the same struct, when both are virtually the same piece of information.
As for the device_id
you’d also need a char[25]
as a String
for the same reasons as above.
I am using these 2 functions for file read and write. Passing my data as comma separated string as
fileString = “DEVICE_001,27,80,1655966444” but after writing I called the read file function but it prints empty values. Could you suggest ?
void writeFile(String fileString) {
int fd = open("/rssi.txt", O_RDWR | O_CREAT | O_TRUNC | O_APPEND);
if (fd != -1) {
write(fd, fileString.c_str(), fileString.length());
close(fd);
}
}
void readFile() {
struct stat statbuf;
int sd = stat("/rssi.txt", &statbuf);
if (sd != 0) {
return;
}
int fd = open("/rssi.txt", O_RDONLY);
Log.info("fd %d", fd);
if (fd != -1) {
void *buffer;
int rd = read(fd, buffer, 6);
char* content = static_cast<char*> (buffer);
Log.info("rd %d", rd);
close(fd);
Log.info("got a msg buffer");
Log.info(content);
}
}
Not sure how you even were able to compile this ?
don’t think that stat();
function even exist for Particle dev and SD card.
Which Lib for SD card are you using ? (I’m assuming that you want to read/write from/to SD card)
You can’t do this:
you have to initialize the File class first e.g: File myFile
; or SdFile csvFile
; not int myFile
; as is not going to work 100% what will happen when you will try
myFile.println("TESTUS....");
compiler will give up believe me
i suggest to start from here and look for: examples/LowLatencyLoggerADXL345/LowLatencyLogger.ino
there’s some info how to write/read from/to struct named block_t
good luck
This is the entire code I am using. I am trying to write on Particle’s internal file system not on SD card. I just wanted to confirm my data is stored in file or not that’s why I printed content. In real time I post that file content via MQTT.
#include "Particle.h"
#include <fcntl.h>
SYSTEM_MODE(MANUAL);
SerialLogHandler logHandler(LOG_LEVEL_TRACE);
#define SCAN_INTERVAL 5000
#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync;
//Function Declarations
void syncCloudTime();
void readFile();
void writeFile();
typedef struct{
String device_id;
unsigned long timestamp;
float sensorReading;
} SensorData;
void setup() {
(void)logHandler; // Does nothing, just to eliminate warning for unused variable
//DynamicJsonDocument deviceList(1024);
syncCloudTime();
}
void loop() {
if (millis() - lastSync >= ONE_DAY_MILLIS) {
syncCloudTime();
}
SensorData data;
data.device_id = "SENSOR_01";
data.timestamp = Time.now();
data.sensorReading = 22.0;
String fileString = String(data.device_id) + ","
+ String(data.timestamp) + ","
+ String(data.sensorReading);
writeFile(fileString);
delay(250);
readFile();
delay(5000);
}
void syncCloudTime() { // Request time synchronization from the Particle Device Cloud
WiFi.on();
WiFi.connect();
waitFor(WiFi.ready,60000);
Particle.connect();
Particle.syncTime();
waitFor(Time.isValid, 60000);
lastSync = millis();
Particle.disconnect();
WiFi.disconnect();
WiFi.off();
}
void writeFile(String fileString) {
int fd = open("/data.txt", O_RDWR | O_CREAT | O_TRUNC | O_APPEND);
if (fd != -1) {
write(fd, fileString.c_str(), fileString.length());
close(fd);
}
}
void readFile() {
struct stat statbuf;
int sd = stat("/data.txt", &statbuf);
if (sd != 0) {
return;
}
// this always returns 1823 for me, event if I change the file contents
// read the file
int fd = open("/rssi.txt", O_RDONLY);
Log.info("fd %d", fd);
if (fd != -1) {
void *buffer;
int rd = read(fd, buffer, 6);
char* content = static_cast<char*> (buffer);
Log.info("rd %d", rd);
close(fd);
Log.info("got a msg buffer");
// THIS IS JUST EMPTY, I would expect it to be "foobar"
Log.info(content);
}
}
This only creates a pointer. It does not reserve any memory to read the data into.
I’d also do away with String
and rather use a character array
e.g. instead of
I’d do this
char fileString[128];
snprintf(fileString, sizeof(fileString)
, "%s,%012lu,%.3f"
, data.device_id // where device_id should be declared as char[25] in the struct, not String
, data.timestamp
, data.sensorReading
);
writeFile(fileString, strlen(fileString)+1);
...
void writeFile(const char* fileString, size_t len) {
...
}
However, since you have a struct, why not write that as is and as your original question was indicating you wanted anyhow?
write(fd, (const void*)&data, sizeof(data));
// and
read(fd, (void*)&data, sizeof(data));
(providing device_id
is defined as char device_id[25]
)
Sure I try this definitely . Thanks a lot