/********* Pleasedontcode.com **********
Pleasedontcode thanks you for automatic code generation! Enjoy your code!
- Terms and Conditions:
You have a non-exclusive, revocable, worldwide, royalty-free license
for personal and commercial use. Attribution is optional; modifications
are allowed, but you're responsible for code maintenance. We're not
liable for any loss or damage. For full terms,
please visit pleasedontcode.com/termsandconditions.
- Project: "RTC Synchronization"
- Source Code NOT compiled for: Arduino Nano ESP32
- Source Code created on: 2024-06-13 15:52:27
********* Pleasedontcode.com **********/
/****** SYSTEM REQUIREMENTS *****/
/****** SYSTEM REQUIREMENT 1 *****/
/* initialize gsm */
/****** SYSTEM REQUIREMENT 2 *****/
/* align one time per day the clock from gsm to RTC */
/****** END SYSTEM REQUIREMENTS *****/
/****** DEFINITION OF LIBRARIES *****/
#include //https://github.com/plerup/espsoftwareserial
#include
#include //https://github.com/vittorioexp/Sim800L-Arduino-Library-revised
#include //https://github.com/NorthernWidget/DS3231
/****** FUNCTION PROTOTYPES *****/
void setup(void);
void loop(void);
void updateOutputs(void);
void inputDateFromSerial(void);
void syncClockFromGSM(void);
/***** DEFINITION OF DIGITAL INPUT PINS *****/
const uint8_t gsm_SIM800L_RING_PIN_D3 = 3;
/***** DEFINITION OF DIGITAL OUTPUT PINS *****/
const uint8_t gsm_SIM800L_RST_PIN_D2 = 2;
const uint8_t gsm_SIM800L_DTR_PIN_D4 = 4;
/***** DEFINITION OF Software Serial *****/
const uint8_t gsm_SIM800L_Serial_PIN_SERIAL_TX_A0 = A0;
const uint8_t gsm_SIM800L_Serial_PIN_SERIAL_RX_A1 = A1;
EspSoftwareSerial::UART gsm_SIM800L_Serial;
/***** DEFINITION OF I2C PINS *****/
const uint8_t clock_DS3231_I2C_PIN_SDA_A4 = A4;
const uint8_t clock_DS3231_I2C_PIN_SCL_A5 = A5;
const uint8_t clock_DS3231_I2C_SLAVE_ADDRESS = 104;
/***** DEFINITION OF OUTPUT RAW VARIABLES *****/
/***** used to store raw data *****/
bool gsm_SIM800L_RST_PIN_D2_rawData = 0;
bool gsm_SIM800L_DTR_PIN_D4_rawData = 0;
/***** DEFINITION OF OUTPUT PHYSICAL VARIABLES *****/
/***** used to store data after characteristic curve transformation *****/
float gsm_SIM800L_RST_PIN_D2_phyData = 0.0;
float gsm_SIM800L_DTR_PIN_D4_phyData = 0.0;
/****** DEFINITION OF LIBRARIES CLASS INSTANCES*****/
Sim800L GSM(gsm_SIM800L_Serial_PIN_SERIAL_RX_A1, gsm_SIM800L_Serial_PIN_SERIAL_TX_A0, gsm_SIM800L_RST_PIN_D2, gsm_SIM800L_DTR_PIN_D4, gsm_SIM800L_RING_PIN_D3); // Initialize Sim800L object
DS3231 myRTC; // Initialize DS3231 object
// Variables for DS3231
byte year, month, date, dow, hour, minute, second;
bool century = false, h12Flag, pmFlag;
unsigned long lastSyncTime = 0; // Variable to store the last sync time
const unsigned long syncInterval = 86400000; // 24 hours in milliseconds
void setup(void)
{
// put your setup code here, to run once:
pinMode(gsm_SIM800L_RING_PIN_D3, INPUT_PULLUP);
pinMode(gsm_SIM800L_RST_PIN_D2, OUTPUT);
pinMode(gsm_SIM800L_DTR_PIN_D4, OUTPUT);
gsm_SIM800L_Serial.begin(9600, SWSERIAL_8N1, gsm_SIM800L_Serial_PIN_SERIAL_RX_A1, gsm_SIM800L_Serial_PIN_SERIAL_TX_A0, false);
/* initialize gsm */
GSM.begin(4800); // Initialize GSM module
GSM.updateRtc(+1); // Update RTC with UTC offset
// Initialize I2C communication for DS3231
Wire.begin(clock_DS3231_I2C_PIN_SDA_A4, clock_DS3231_I2C_PIN_SCL_A5);
// Start the serial port for debugging
Serial.begin(57600);
// Request the time correction on the Serial
delay(4000);
Serial.println("Format YYMMDDwhhmmssx");
Serial.println("Where YY = Year (ex. 20 for 2020)");
Serial.println(" MM = Month (ex. 04 for April)");
Serial.println(" DD = Day of month (ex. 09 for 9th)");
Serial.println(" w = Day of week from 1 to 7, 1 = Sunday (ex. 5 for Thursday)");
Serial.println(" hh = hours in 24h format (ex. 09 for 9AM or 21 for 9PM)");
Serial.println(" mm = minutes (ex. 02)");
Serial.println(" ss = seconds (ex. 42)");
Serial.println("Example for input : 2004095090242x");
Serial.println("-----------------------------------------------------------------------------");
Serial.println("Please enter the current time to set on DS3231 ended by 'x':");
}
void loop(void)
{
// put your main code here, to run repeatedly:
updateOutputs(); // Refresh output data
// If something is coming in on the serial line, it's
// a time correction so set the clock accordingly.
if (Serial.available()) {
inputDateFromSerial();
myRTC.setClockMode(false); // set to 24h
myRTC.setYear(year);
myRTC.setMonth(month);
myRTC.setDate(date);
myRTC.setDoW(dow);
myRTC.setHour(hour);
myRTC.setMinute(minute);
myRTC.setSecond(second);
// Give time at next five seconds
for (uint8_t i = 0; i < 5; i++){
delay(1000);
Serial.print(myRTC.getYear(), DEC);
Serial.print("-");
Serial.print(myRTC.getMonth(century), DEC);
Serial.print("-");
Serial.print(myRTC.getDate(), DEC);
Serial.print(" ");
Serial.print(myRTC.getHour(h12Flag, pmFlag), DEC); //24-hr
Serial.print(":");
Serial.print(myRTC.getMinute(), DEC);
Serial.print(":");
Serial.println(myRTC.getSecond(), DEC);
}
// Notify that we are ready for the next input
Serial.println("Please enter the current time to set on DS3231 ended by 'x':");
}
/* align one time per day the clock from gsm to RTC */
if (millis() - lastSyncTime >= syncInterval) {
syncClockFromGSM();
lastSyncTime = millis();
}
delay(1000);
}
void updateOutputs()
{
digitalWrite(gsm_SIM800L_RST_PIN_D2, gsm_SIM800L_RST_PIN_D2_rawData);
digitalWrite(gsm_SIM800L_DTR_PIN_D4, gsm_SIM800L_DTR_PIN_D4_rawData);
}
void inputDateFromSerial() {
// Call this if you notice something coming in on
// the serial port. The stuff coming in should be in
// the order YYMMDDwHHMMSS, with an 'x' at the end.
boolean isStrComplete = false;
char inputChar;
byte temp1, temp2;
char inputStr[20];
uint8_t currentPos = 0;
while (!isStrComplete) {
if (Serial.available()) {
inputChar = Serial.read();
inputStr[currentPos] = inputChar;
currentPos += 1;
// Check if string complete (end with "x")
if (inputChar == 'x') {
isStrComplete = true;
}
}
}
Serial.println(inputStr);
// Find the end of char "x"
int posX = -1;
for(uint8_t i = 0; i < 20; i++) {
if(inputStr[i] == 'x') {
posX = i;
break;
}
}
// Consider 0 character in ASCII
uint8_t zeroAscii = '0';
// Read Year first
temp1 = (byte)inputStr[posX - 13] - zeroAscii;
temp2 = (byte)inputStr[posX - 12] - zeroAscii;
year = temp1 * 10 + temp2;
// now month
temp1 = (byte)inputStr[posX - 11] - zeroAscii;
temp2 = (byte)inputStr[posX - 10] - zeroAscii;
month = temp1 * 10 + temp2;
// now date
temp1 = (byte)inputStr[posX - 9] - zeroAscii;
temp2 = (byte)inputStr[posX - 8] - zeroAscii;
date = temp1 * 10 + temp2;
// now Day of Week
dow = (byte)inputStr[posX - 7] - zeroAscii;
// now Hour
temp1 = (byte)inputStr[posX - 6] - zeroAscii;
temp2 = (byte)inputStr[posX - 5] - zeroAscii;
hour = temp1 * 10 + temp2;
// now Minute
temp1 = (byte)inputStr[posX - 4] - zeroAscii;
temp2 = (byte)inputStr[posX - 3] - zeroAscii;
minute = temp1 * 10 + temp2;
// now Second
temp1 = (byte)inputStr[posX - 2] - zeroAscii;
temp2 = (byte)inputStr[posX - 1] - zeroAscii;
second = temp1 * 10 + temp2;
}
void syncClockFromGSM() {
// Get the current time from the GSM module
GSM.RTCtime(&date, &month, &year, &hour, &minute, &second);
// Set the DS3231 RTC with the GSM time
myRTC.setClockMode(false); // set to 24h
myRTC.setYear(year);
myRTC.setMonth(month);
myRTC.setDate(date);
myRTC.setDoW(dow);
myRTC.setHour(hour);
myRTC.setMinute(minute);
myRTC.setSecond(second);
Serial.println("RTC synchronized with GSM time.");
}