/********* 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: "ESP32 Automation"
- Source Code NOT compiled for: ESP32 DevKit V1
- Source Code created on: 2024-07-17 00:16:29
********* Pleasedontcode.com **********/
/****** SYSTEM REQUIREMENTS *****/
/****** SYSTEM REQUIREMENT 1 *****/
/* create a web server for setting sid and password */
/* and showing time on rtc once esp32 has wifi */
/* connection update rtc from nst. tun on relay1 */
/* every second and relay2 every 30 seconds using */
/* time from rtc */
/****** END SYSTEM REQUIREMENTS *****/
/****** DEFINITION OF LIBRARIES *****/
#include
#include //https://github.com/NorthernWidget/DS3231
#include //https://github.com/tzapu/WiFiManager.git
#include
#include
#include
#include
#include
#include
#ifdef ESP32
#include
#endif
/****** FUNCTION PROTOTYPES *****/
void setup(void);
void loop(void);
void updateOutputs(void);
void saveConfigCallback(void);
void isr_TickTock(void);
void handleRoot(void);
void handleNotFound(void);
void updateRTCFromNTP(void);
/***** DEFINITION OF DIGITAL OUTPUT PINS *****/
const uint8_t relay1_RelayModule_Signal_PIN_D4 = 4;
const uint8_t relay2_RelayModule_Signal_PIN_D13 = 13;
/***** DEFINITION OF I2C PINS *****/
const uint8_t rtc_DS3231_I2C_PIN_SDA_D21 = 21;
const uint8_t rtc_DS3231_I2C_PIN_SCL_D22 = 22;
const uint8_t rtc_DS3231_I2C_SLAVE_ADDRESS = 104;
/***** DEFINITION OF OUTPUT RAW VARIABLES *****/
/***** used to store raw data *****/
bool relay1_RelayModule_Signal_PIN_D4_rawData = 0;
bool relay2_RelayModule_Signal_PIN_D13_rawData = 0;
/***** DEFINITION OF OUTPUT PHYSICAL VARIABLES *****/
/***** used to store data after characteristic curve transformation *****/
float relay1_RelayModule_Signal_PIN_D4_phyData = 0.0;
float relay2_RelayModule_Signal_PIN_D13_phyData = 0.0;
/****** DEFINITION OF LIBRARIES CLASS INSTANCES*****/
DS3231 myRTC; // Initialize DS3231 object
WiFiManager wifiManager; // Initialize WiFiManager object
WebServer server(80); // Initialize WebServer on port 80
WiFiUDP ntpUDP; // Initialize WiFiUDP object
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 60000); // Initialize NTPClient to get time from NTP server
/****** WiFiManager Custom Parameters *****/
char mqtt_server[40];
char mqtt_port[6] = "8080";
char api_token[34] = "YOUR_API_TOKEN";
bool shouldSaveConfig = false;
/****** WiFiManager Custom Parameters Instances *****/
WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 6);
WiFiManagerParameter custom_api_token("apikey", "API token", api_token, 32);
void saveConfigCallback() {
Serial.println("Should save config");
shouldSaveConfig = true;
}
void setup(void) {
// Initialize I2C communication
Wire.begin(rtc_DS3231_I2C_PIN_SDA_D21, rtc_DS3231_I2C_PIN_SCL_D22);
// Initialize Serial communication for debugging
Serial.begin(9600);
while (!Serial);
// Print initialization message
Serial.println("Starting Serial");
// Initialize relay pins as outputs
pinMode(relay1_RelayModule_Signal_PIN_D4, OUTPUT);
pinMode(relay2_RelayModule_Signal_PIN_D13, OUTPUT);
// Set Alarm 1 to fire every second
myRTC.turnOffAlarm(1);
myRTC.setA1Time(0, 0, 0, 0, 0b00001111, false, false, false);
myRTC.turnOnAlarm(1);
myRTC.checkIfAlarm(1);
// Prevent Alarm 2 from interfering
myRTC.setA2Time(0, 0, 0xFF, 0b01100000, false, false, false);
myRTC.turnOffAlarm(2);
myRTC.checkIfAlarm(2);
// Attach clock interrupt
pinMode(2, INPUT_PULLUP); // Assuming interrupt pin is GPIO 2
attachInterrupt(digitalPinToInterrupt(2), isr_TickTock, FALLING);
// Use built-in LED to blink
pinMode(LED_BUILTIN, OUTPUT);
// Initialize SPIFFS
if (SPIFFS.begin()) {
if (SPIFFS.exists("/config.json")) {
File configFile = SPIFFS.open("/config.json", "r");
if (configFile) {
size_t size = configFile.size();
std::unique_ptr buf(new char[size]);
configFile.readBytes(buf.get(), size);
DynamicJsonDocument json(1024);
if (!deserializeJson(json, buf.get())) {
strcpy(mqtt_server, json["mqtt_server"]);
strcpy(mqtt_port, json["mqtt_port"]);
strcpy(api_token, json["api_token"]);
}
configFile.close();
}
}
}
// Set WiFiManager custom parameters
wifiManager.setSaveConfigCallback(saveConfigCallback);
wifiManager.addParameter(&custom_mqtt_server);
wifiManager.addParameter(&custom_mqtt_port);
wifiManager.addParameter(&custom_api_token);
// Attempt to connect to WiFi
if (!wifiManager.autoConnect("AutoConnectAP", "password")) {
Serial.println("Failed to connect and hit timeout");
ESP.restart();
}
Serial.println("Connected to WiFi");
// Save custom parameters
strcpy(mqtt_server, custom_mqtt_server.getValue());
strcpy(mqtt_port, custom_mqtt_port.getValue());
strcpy(api_token, custom_api_token.getValue());
if (shouldSaveConfig) {
DynamicJsonDocument json(1024);
json["mqtt_server"] = mqtt_server;
json["mqtt_port"] = mqtt_port;
json["api_token"] = api_token;
File configFile = SPIFFS.open("/config.json", "w");
if (configFile) {
serializeJson(json, configFile);
configFile.close();
}
}
Serial.println("Local IP: " + WiFi.localIP().toString());
// Initialize web server routes
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
server.begin();
// Initialize NTP client
timeClient.begin();
}
void loop(void) {
// Handle web server
server.handleClient();
// Update NTP client
timeClient.update();
// Update RTC from NTP if not already updated
static bool rtcUpdated = false;
if (!rtcUpdated && WiFi.status() == WL_CONNECTED) {
updateRTCFromNTP();
rtcUpdated = true;
}
updateOutputs(); // Refresh output data
static byte state = false;
static volatile byte tick = 1;
// If alarm went off, toggle LED
if (tick) {
tick = 0;
state = !state;
digitalWrite(LED_BUILTIN, state);
// Optional serial output
Serial.print("Turning LED ");
Serial.println(state ? "ON" : "OFF");
// Clear Alarm 1 flag
myRTC.checkIfAlarm(1);
}
// Loop delay to emulate other running code
delay(10);
}
void updateOutputs() {
// Get current time from RTC
DateTime now = myRTC.getDateTime();
// Turn on relay1 every second
relay1_RelayModule_Signal_PIN_D4_rawData = (now.second % 2 == 0);
// Turn on relay2 every 30 seconds
relay2_RelayModule_Signal_PIN_D13_rawData = (now.second % 30 == 0);
// Update relay states
digitalWrite(relay1_RelayModule_Signal_PIN_D4, relay1_RelayModule_Signal_PIN_D4_rawData);
digitalWrite(relay2_RelayModule_Signal_PIN_D13, relay2_RelayModule_Signal_PIN_D13_rawData);
}
void isr_TickTock() {
// Interrupt signals to loop
static volatile byte tick = 1;
}
void handleRoot() {
String html = "ESP32 Web Server
";
html += "Current Time: " + myRTC.getDateTime().toString() + "
";
html += "";
server.send(200, "text/html", html);
}
void handleNotFound() {
server.send(404, "text/plain", "404: Not found");
}
void updateRTCFromNTP() {
// Get time from NTP
time_t epochTime = timeClient.getEpochTime();
struct tm *ptm = gmtime(&epochTime);
// Update RTC with NTP time
myRTC.setDateTime(ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
Serial.println("RTC updated from NTP");
}