// Libraries for SD card
#include "FS.h"
#include "SD.h"
#include <SPI.h>
// Libraries to get time from NTP Server
#include <WiFi.h>
#include "time.h"
// Libraries for JSON data
#include <ArduinoJson.h>
// Replace with your network credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Define CS pin for the SD card module
#define SD_CS 5
// Save reading number on RTC memory
RTC_DATA_ATTR int readingID = 0;
String dataMessage;
String dataToSave;
// Temperature Sensor variables
float temperature;
// Define NTP Client to get time
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 25200;
const int daylightOffset_sec = 3600;
// Variables to save date and time
String dayStamp;
String timeStamp;
void setup() {
// Start serial communication for debugging purposes
Serial.begin(115200);
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
// Initialize a NTPClient to get time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
getTimeStamp();
// 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 data.txt file doesn't exist
// Create a file on the SD card and write the data labels
File file = SD.open("/data.txt");
if(!file) {
Serial.println("File doens't exist");
Serial.println("Creating file...");
// writeFile(SD, "/data.txt", "Reading ID, Date, Hour, Temperature \r\n");
}
else {
Serial.println("File already exists");
}
file.close();
}
void loop() {
getReadings();
getTimeStamp();
logSDCard();
// Increment readingID on every new reading
readingID++;
delay(2000);
}
// Function to get temperature
void getReadings(){
temperature = random(0, 100);
Serial.print("Temperature: ");
Serial.println(temperature);
}
// Function to get date and time from NTPClient
void getTimeStamp() {
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
char day[10];
char date[3];
char month[10];
char year[5];
char hour[3];
char minute[3];
char second[3];
strftime(day,10, "%A", &timeinfo);
strftime(date,3, "%d", &timeinfo);
strftime(month,10, "%B", &timeinfo);
strftime(year,5, "%Y", &timeinfo);
strftime(hour,3, "%H", &timeinfo);
strftime(minute,3, "%M", &timeinfo);
strftime(second,3, "%S", &timeinfo);
dayStamp = String(date) + " " + String(month) + " " + String(year);
timeStamp = String(hour) + ":" + String(minute) + ":" + String(second);
Serial.printf("Day: %s\n", String(day));
Serial.printf("Date: %s\n", String(date));
Serial.printf("Month: %s\n", String(month));
Serial.printf("Year: %s\n", String(year));
Serial.printf("Hour: %s\n", String(hour));
Serial.printf("Minute: %s\n", String(minute));
Serial.printf("second: %s\n", String(second));
Serial.println(dayStamp);
Serial.println(timeStamp);
}
// Write the sensor readings on the SD card
void logSDCard() {
// dataMessage = String(readingID) + "," + String(dayStamp) + "," + String(timeStamp) + "," +
// String(temperature) + "\r\n";
StaticJsonDocument<200> doc;
doc["ID"] = readingID;
doc["Tanggal"] = dayStamp;
doc["Jam"] = timeStamp;
doc["Suhu"] = temperature;
serializeJson(doc, dataMessage);
dataToSave = dataMessage + "\r\n";
// dataToSave = String(dataMessage) + "\r\n";
Serial.print("Save data: ");
Serial.println(dataToSave);
appendFile(SD, "/data.txt", dataToSave.c_str());
}
// 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();
}