#include <SD.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <RTClib.h>
#include "FS.h"
#define CS_PIN 5
#define DEVICE_NAME "SF999"
#define LOCATION "SNI999"
File root;
RTC_DS3231 rtc;
void setup() {
Serial.begin(115200);
Serial.print("Initializing SD card... ");
if (!SD.begin(CS_PIN)) {
Serial.println("Card initialization failed!");
while (true);
}
Serial.println("initialization done.");
root = SD.open("/");
Wire.begin();
if (!rtc.begin()) {
Serial.println("RTC is NOT running!");
// Following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Serial.println("Files in the card:");
// root = SD.open("/");
// printDirectory(root, 0);
// Serial.println("");
// // Example of reading file from the card:
// File textFile = SD.open("/data.json");
// if (textFile) {
// Serial.print("data.json: ");
// while (textFile.available()) {
// Serial.write(textFile.read());
// }
// textFile.close();
// } else {
// Serial.println("error opening wokwi.txt!");
// }
// for (int i = 0; i < 3; i++)
// {
// Serial.println(loadData(i));
// Serial.println("\n\n");
// delay(5000);
// }
}
void loop() {
saveDataToSD();
delay(1000);
}
void printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
double round2(double value)
{
return (int)(value * 100 + 0.50) / 100.00;
}
// void saveDataToSD()
// {
// String buffer = "";
// File fileR = SD.open("/data.json");
// Serial.print("data.json: ");
// // while (fileR.available()) {
// buffer = fileR.readString();
// // }
// fileR.close();
// // Serial.println(buffer);
// File file = SD.open("/data.json", FILE_WRITE);
// if (!file) {
// Serial.println("Failed to open file for writing");
// return;
// }
// // Serial.print("data.json: ");
// // while (file.available()) {
// // Serial.write(file.read());
// // }
// // Deserialize JSON from file
// DynamicJsonDocument doc(1024);
// DeserializationError error = deserializeJson(doc, buffer);
// if (error) {
// Serial.println("Failed to read file");
// file.close();
// return;
// }
// // Create a JSON array or use existing array
// int index = doc["lists"].size();
// JsonArray array = doc.to<JsonArray>();
// // Create a new JSON object and add to array
// JsonObject jsonDoc = array.createNestedObject();
// // obj["id"] = 3;
// // obj["name"] = "Alice";
// DateTime now = rtc.now();
// char formattedDate[50];
// sprintf(formattedDate, "%04d-%02d-%02dT%02d:%02d:%02dZ", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
// // Serial.println(formattedDate);
// // DynamicJsonDocument jsonDoc(1024);
// jsonDoc["lists"][index + 1]["measurement"] = "Water Quality";
// JsonObject tags = jsonDoc.createNestedObject("tags");
// tags["location"] = LOCATION;
// tags["deviceName"] = DEVICE_NAME;
// JsonObject fields = jsonDoc.createNestedObject("fields");
// fields["waterTemp"] = round2(random(5, 30));
// fields["DOvalue"] = round2(random(5, 30));
// fields["Salinity"] = round2(random(5, 30));
// fields["ECvalue"] = round2(random(5, 30));
// fields["PHvalue"] = round2(random(5, 30));
// // jsonDoc["time"] = "2023-01-01T12:34:56Z";
// jsonDoc["time"] = formattedDate;
// String payload = "";
// serializeJson(jsonDoc, payload);
// serializeJsonPretty(jsonDoc, Serial);
// // Rewind file pointer to beginning
// file.seek(0);
// // Write updated JSON to file
// file.print(payload);
// file.close();
// Serial.println("File updated successfully");
// }
void saveDataToSD()
{
// Read existing data from SD card
File fileR = SD.open("/data.json");
String buffer = fileR.readString();
fileR.close();
// Deserialize JSON from file
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, buffer);
if (error) {
Serial.println("Failed to read file");
return;
}
// Get the size of the "lists" array
int index = doc["lists"].size();
// Add new data to the JSON document
JsonObject newData = doc["lists"].createNestedObject();
newData["measurement"] = "Water Quality";
JsonObject tags = newData.createNestedObject("tags");
tags["location"] = LOCATION;
tags["deviceName"] = DEVICE_NAME;
JsonObject fields = newData.createNestedObject("fields");
fields["waterTemp"] = round2(random(5, 30));
fields["DOvalue"] = round2(random(5, 30));
fields["Salinity"] = round2(random(5, 30));
fields["ECvalue"] = round2(random(5, 30));
fields["PHvalue"] = round2(random(5, 30));
DateTime now = rtc.now();
char formattedDate[50];
sprintf(formattedDate, "%04d-%02d-%02dT%02d:%02d:%02dZ", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
newData["time"] = formattedDate;
// Serialize JSON to string
String output;
serializeJson(doc, output);
serializeJsonPretty(doc, Serial);
// Write updated JSON back to the file
File file = SD.open("/data.json", FILE_WRITE);
if (!file) {
Serial.println("Failed to open file for writing");
return;
}
file.print(output);
file.close();
Serial.println("File updated successfully");
}
// String loadDataFromSD(int index) {
// // Open the existing file
// File file = SD.open("/data.json");
// if (!file) {
// return "Failed to open file for reading";
// }
// // Read the existing JSON data
// DynamicJsonDocument doc(1024);
// DeserializationError error = deserializeJson(doc, file);
// if (error) {
// file.close();
// return "Failed to read file";
// }
// file.close();
// // Check if the index is within the bounds of the array
// if (index < 0 || index >= doc["lists"].size()) {
// return "Index out of bounds";
// }
// // Get the data at the specified index
// JsonObject data = doc["lists"][index];
// const char* measurement = data["measurement"];
// const char* location = data["tags"]["location"];
// const char* deviceName = data["tags"]["deviceName"];
// int waterTemp = data["fields"]["waterTemp"];
// int DOvalue = data["fields"]["DOvalue"];
// int Salinity = data["fields"]["Salinity"];
// int ECvalue = data["fields"]["ECvalue"];
// int PHvalue = data["fields"]["PHvalue"];
// const char* time = data["time"];
// // Remove the data at the specified index
// doc["lists"].remove(index);
// // Serialize the updated JSON document
// String output;
// serializeJson(doc, output);
// // Open the file for writing and clear its contents
// file = SD.open("/data.json", FILE_WRITE);
// if (!file) {
// return "Failed to open file for writing";
// }
// file.print(output);
// file.close();
// // Construct and return the data as a string
// String result = "Index: ";
// result += index;
// result += "\nMeasurement: ";
// result += measurement;
// result += "\nLocation: ";
// result += location;
// result += "\nDevice Name: ";
// result += deviceName;
// result += "\nWater Temp: ";
// result += waterTemp;
// result += "\nDO Value: ";
// result += DOvalue;
// result += "\nSalinity: ";
// result += Salinity;
// result += "\nEC Value: ";
// result += ECvalue;
// result += "\nPH Value: ";
// result += PHvalue;
// result += "\nTime: ";
// result += time;
// return result;
// }
bool loadJSON(const char* filename, DynamicJsonDocument& doc) {
// Open the file for reading
File file = SD.open(filename);
if (!file) {
Serial.println("Failed to open file for reading");
return false;
}
// Read the JSON data from the file
DeserializationError error = deserializeJson(doc, file);
file.close();
// Check for errors
if (error) {
Serial.println("Failed to parse JSON data");
return false;
}
return true;
}
JsonObject getJSONAtIndex(int index) {
const char* filename = "/data.json";
DynamicJsonDocument doc(1024);
// Load and parse JSON data from file
if (!loadJSON(filename, doc)) {
return JsonObject();
}
// Check if the index is within the bounds of the array
if (index < 0 || index >= doc["lists"].size()) {
Serial.println("Index out of bounds");
return JsonObject();
}
// Get the JSON object at the specified index
return doc["lists"][index];
}
String loadData(int index)
{
File fileR = SD.open("/data.json");
String buffer = fileR.readString();
fileR.close();
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, buffer);
if (error) {
Serial.println("Failed to read file");
// return -1;
}
return doc["lists"][index];
}