#include <LiquidCrystal_I2C.h> // Library for I2C LCD
#include <RTClib.h> // Library for Real Time Clock
#include <Wire.h> // Library for I2C communication
#include <EEPROM.h>
#include "DHT.h"
#define LOG_OPTION 1 // Option to enable logging
#define SERIAL_OPTION 1 // Serial communication option: 0 for off, 1 for on
#define UTC_OFFSET -3 // Time zone adjustment for UTC-3
// DHT22 Settings
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27,16,2); // I2C address: 0x3F or 0x27
RTC_DS1307 RTC;
// EEPROM Settings
const int maxRecords = 100;
const int recordSize = 8; // Size of each record in bytes
int startAddress = 0;
int endAddress = maxRecords * recordSize;
int currentAddress = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
dht.begin();
Serial.begin(9600);
lcd.init();
lcd.backlight();
RTC.begin();
RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); // Adjust date and time once initially, then comment out
EEPROM.begin();
}
void loop() {
DateTime now = RTC.now();
// Calculating the UTC offset
int offsetSeconds = UTC_OFFSET * 3600;
now = now.unixtime() + offsetSeconds;
// Convert the adjusted time back to DateTime
DateTime adjustedTime = DateTime(now);
if (LOG_OPTION) get_log();
if (adjustedTime.second() == 0) {
// Blink LED to indicate data logging
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
// Read temperature and humidity
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
// Convert values to integers for storage
int tempInt = (int)(temperature * 100);
int humiInt = (int)(humidity * 100);
// Get Unix timestamp
unsigned long timestamp = adjustedTime.unixtime();
// Write data to EEPROM
EEPROM.put(currentAddress, timestamp);
EEPROM.put(currentAddress + 4, tempInt);
EEPROM.put(currentAddress + 6, humiInt);
// Update address for next record
getNextAddress();
}
// Serial output
if (SERIAL_OPTION) {
// Convert timestamp to human-readable format
char buffer[20];
sprintf(buffer, "%02d-%02d-%04d %02d:%02d:%02d",
adjustedTime.day(), adjustedTime.month(), adjustedTime.year(),
adjustedTime.hour(), adjustedTime.minute(), adjustedTime.second());
Serial.println("Data logged at: " + String(buffer));
}
// LCD output
lcd.setCursor(0,0);
lcd.print("DATA: ");
lcd.print(adjustedTime.day() < 10 ? "0" : "");
lcd.print(adjustedTime.day());
lcd.print("-");
lcd.print(adjustedTime.month() < 10 ? "0" : "");
lcd.print(adjustedTime.month());
lcd.print("-");
lcd.print(adjustedTime.year());
lcd.setCursor(0,1);
lcd.print("HORA: ");
lcd.print(adjustedTime.hour() < 10 ? "0" : "");
lcd.print(adjustedTime.hour());
lcd.print(":");
lcd.print(adjustedTime.minute() < 10 ? "0" : "");
lcd.print(adjustedTime.minute());
lcd.print(":");
lcd.print(adjustedTime.second() < 10 ? "0" : "");
lcd.print(adjustedTime.second());
delay(1000);
}
void getNextAddress() {
currentAddress += recordSize;
if (currentAddress >= endAddress) {
currentAddress = 0; // Reset to the beginning if the limit is reached
}
}
void get_log() {
Serial.println("Data stored in EEPROM:");
Serial.println("Timestamp\tTemperature\tHumidity");
for (int address = startAddress; address < endAddress; address += recordSize) {
unsigned long timeStamp;
int tempInt, humiInt;
// Read data from EEPROM
EEPROM.get(address, timeStamp);
EEPROM.get(address + 4, tempInt);
EEPROM.get(address + 6, humiInt);
// Convert values
float temperature = tempInt / 100.0;
float humidity = humiInt / 100.0;
// Check if data is valid before printinga
if (timeStamp != 0xFFFFFFFF) {
// Convert timestamp to human-readable format
DateTime timestampDT = DateTime(timeStamp);
char buffer[20];
sprintf(buffer, "%02d-%02d-%04d %02d:%02d:%02d",
timestampDT.day(), timestampDT.month(), timestampDT.year(),
timestampDT.hour(), timestampDT.minute(), timestampDT.second());
Serial.print(buffer);
Serial.print("\t");
Serial.print(temperature);
Serial.print(" C\t\t");
Serial.print(humidity);
Serial.println(" %");
}
}
}