#include #include #include #include #include #include #define DE_RE_PIN 4 #define RX_PIN 6 // SoftwareSerial RX pin #define TX_PIN 8 // SoftwareSerial TX pin #define SD_CS_PIN 10 // Chip Select for SD Card RTC_DS3231 rtc; // Create an RTC object File dataFile; SoftwareSerial modbusSerial(RX_PIN, TX_PIN); // Create a software serial instance Modbus slave(1, modbusSerial, DE_RE_PIN); uint16_t holdingRegisters[20]; // Array to hold Modbus registers void setup() { Serial.begin(9600); // For debugging Serial.println("Startup \n"); // Initialize RTC if (!rtc.begin()) { Serial.println("Couldn't find RTC\n"); } if (rtc.lostPower()) { Serial.println("RTC lost power, let's set the time!\n"); // Comment out the following line once the time is set to avoid resetting on every start rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } Serial.print("Time: "); Serial.print(rtc.now().timestamp()); Serial.println("\n"); // Initialize SD card Serial.println("SD card initializing..."); pinMode(SD_CS_PIN, OUTPUT); if (!SD.begin(SPI_HALF_SPEED, SD_CS_PIN)) { Serial.println("SD card initialization failed!\n"); return; } Serial.println("SD card initialized.\n"); Serial.println("Initialize RS485 module / Modbus \n"); // Initialize RS485 module // Initialize DE and RE pins pinMode(DE_RE_PIN, OUTPUT); digitalWrite(DE_RE_PIN, LOW); // Set to LOW for receiving mode initially slave.start(); // Initialize the holding registers // holdingRegisters[0] = 0x0000; // holdingRegisters[1] = 0x0000; } void writeFile(char *str) { if (!dataFile) { Serial.println("Error opening file"); return; } DateTime now = rtc.now(); // Log the current date and time dataFile.print(now.year(), DEC); dataFile.print('-'); dataFile.print(now.month(), DEC); dataFile.print('-'); dataFile.print(now.day(), DEC); dataFile.print(" "); dataFile.print(now.hour(), DEC); dataFile.print(':'); dataFile.print(now.minute(), DEC); dataFile.print(':'); dataFile.print(now.second(), DEC); dataFile.print(","); dataFile.print(str); dataFile.println(); } String getFilename() { DateTime now = rtc.now(); String mb = ""; mb += now.year(); mb += now.month(); mb += now.day(); mb += ".csv"; return mb; } void loop() { Serial.print("Time: "); Serial.print(rtc.now().timestamp()); // Serial.print("\nHeep:"); // Serial.print(ESP.getFreeHeap()); Serial.print("\n"); // Open file for writing String filename = getFilename(); Serial.print("Open Card "); Serial.print(filename.c_str()); Serial.print("\n"); dataFile = SD.open(filename.c_str(), FILE_WRITE); Serial.print("Error count "); Serial.print(slave.getErrCnt()); Serial.print("\n"); Serial.print(slave.getLastError()); Serial.print("\n"); // const int result = slave.poll(holdingRegisters, 20); String mb = "modbus,"; mb += result; mb += ","; for (int i = 0; i < 20; i++) { mb += holdingRegisters[i]; mb += ","; } Serial.println(mb.c_str()); writeFile(mb.c_str()); if (modbusSerial.available() > 0) { Serial.println(modbusSerial.read()); } if (dataFile) { dataFile.close(); // Close the file Serial.print("Data written to SD card: "); Serial.print(filename.c_str()); Serial.print("\n"); } Serial.print("\n\n"); delay(1000); // Delay between readings }