Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Wire.h>
- #include <DS3232RTC.h>
- #include <TimeLib.h>
- #include <EEPROM.h>
- #include <avr/sleep.h>
- #include <avr/interrupt.h>
- #include <PinChangeInterrupt.h>
- struct Record {
- byte hour;
- byte minute;
- byte second;
- byte day;
- byte month;
- byte year;
- int value;
- };
- DS3232RTC rtc;
- const int rtcIntPin = 2; // INT0 - RTC alarm
- const int sensorPin3 = 3; // INT1 - Ball sensor
- const int buttonPin4 = 4; // PCINT - Show records
- const int sensorPin8 = 8; // PCINT - Log value
- const int relayPin = 5;
- volatile bool sensor3Triggered = false;
- volatile bool rtcAlarmTriggered = false;
- volatile bool buttonPressed = false;
- volatile bool sensor8Triggered = false;
- const int EEPROM_SIZE = 1024;
- const int DATA_SIZE = sizeof(Record);
- const int MAX_DATA_ADDRESS = EEPROM_SIZE - 2 * DATA_SIZE;
- int writeIndex = 0;
- time_t lastRecordTime = 0;
- const unsigned long DEBOUNCE_TIME = 500;
- volatile unsigned long lastSensor3Time = 0;
- void setup() {
- pinMode(sensorPin3, INPUT);
- pinMode(buttonPin4, INPUT); // External resistor connected
- pinMode(sensorPin8, INPUT);
- pinMode(relayPin, OUTPUT);
- digitalWrite(relayPin, LOW);
- Serial.begin(9600);
- Wire.begin();
- rtc.begin();
- setSyncProvider(rtc.get);
- rtc.setAlarm(DS3232RTC::ALM1_MATCH_SECONDS, 0, 0, 0, 0);
- rtc.alarmInterrupt(DS3232RTC::ALARM_1, true);
- rtc.alarm(DS3232RTC::ALARM_1); // clear flag
- attachInterrupt(digitalPinToInterrupt(sensorPin3), handleSensor3Interrupt, FALLING);
- attachInterrupt(digitalPinToInterrupt(rtcIntPin), handleRTCAlarmInterrupt, FALLING);
- attachPinChangeInterrupt(digitalPinToPCINT(buttonPin4), handleButton, FALLING);
- attachPinChangeInterrupt(digitalPinToPCINT(sensorPin8), handleSensor8, RISING);
- loadWriteIndex();
- }
- void loop() {
- time_t now = rtc.get();
- if (sensor3Triggered) {
- sensor3Triggered = false;
- unsigned long nowMillis = millis();
- if (nowMillis - lastSensor3Time >= DEBOUNCE_TIME && now - lastRecordTime >= 60) {
- recordTime(773);
- lastRecordTime = now;
- }
- lastSensor3Time = nowMillis;
- }
- if (sensor8Triggered) {
- sensor8Triggered = false;
- recordTime(778);
- }
- if (buttonPressed) {
- buttonPressed = false;
- showAllRecords();
- }
- if (rtcAlarmTriggered) {
- rtcAlarmTriggered = false;
- rtc.alarm(DS3232RTC::ALARM_1); // clear flag
- checkRelayState();
- }
- goToSleep();
- }
- void handleSensor3Interrupt() {
- sensor3Triggered = true;
- }
- void handleRTCAlarmInterrupt() {
- rtcAlarmTriggered = true;
- }
- void handleButton() {
- static unsigned long lastPress = 0;
- if (millis() - lastPress > 300) {
- buttonPressed = true;
- lastPress = millis();
- }
- }
- void handleSensor8() {
- static unsigned long lastTrigger = 0;
- if (millis() - lastTrigger > 500) {
- sensor8Triggered = true;
- lastTrigger = millis();
- }
- }
- void goToSleep() {
- Serial.flush(); // wait for output
- set_sleep_mode(SLEEP_MODE_PWR_DOWN);
- sleep_enable();
- sleep_bod_disable();
- sei(); // ensure global interrupts are on
- sleep_cpu();
- sleep_disable();
- if (Serial) {
- Serial.begin(9600);
- delay(200);
- while (Serial.available()) Serial.read();
- }
- }
- void checkRelayState() {
- time_t now = rtc.get();
- byte hr = hour(now);
- byte min = minute(now);
- if (hr == 21 && min >= 5 && min <= 45) {
- digitalWrite(relayPin, HIGH);
- } else {
- digitalWrite(relayPin, LOW);
- }
- }
- Record createRecordFromRTC(int value) {
- time_t t = rtc.get();
- Record rec;
- rec.hour = hour(t);
- rec.minute = minute(t);
- rec.second = second(t);
- rec.day = day(t);
- rec.month = month(t);
- rec.year = year(t) % 100;
- rec.value = value;
- EEPROM.put(writeIndex, rec);
- return rec;
- }
- void printRecord(const Record& rec) {
- Serial.print(rec.hour); Serial.print(":");
- if (rec.minute < 10) Serial.print("0");
- Serial.print(rec.minute); Serial.print(":");
- if (rec.second < 10) Serial.print("0");
- Serial.print(rec.second); Serial.print(" ");
- if (rec.day < 10) Serial.print("0");
- Serial.print(rec.day); Serial.print(".");
- if (rec.month < 10) Serial.print("0");
- Serial.print(rec.month); Serial.print(".");
- Serial.print("20");
- if (rec.year < 10) Serial.print("0");
- Serial.print(rec.year); Serial.print(" ");
- Serial.println(rec.value);
- Serial.flush();
- }
- void recordTime(int value) {
- Record rec = createRecordFromRTC(value);
- Serial.print("Saved RTC record at ");
- Serial.println(writeIndex);
- printRecord(rec);
- writeIndex += DATA_SIZE;
- if (writeIndex >= MAX_DATA_ADDRESS) {
- Serial.println("EEPROM full. Wrapping to 0.");
- writeIndex = 0;
- }
- saveWriteIndex();
- }
- void showAllRecords() {
- Serial.println("----- EEPROM Records -----");
- for (int index = 0; index < MAX_DATA_ADDRESS; index += DATA_SIZE) {
- Record rec;
- EEPROM.get(index, rec);
- if (rec.year == 0xFF || rec.year == 0x00 || rec.year > 99 ||
- rec.hour > 23 || rec.minute > 59 || rec.second > 59 ||
- rec.day == 0 || rec.day > 31 || rec.month == 0 || rec.month > 12) {
- continue;
- }
- printRecord(rec);
- }
- Serial.println("--------------------------");
- Serial.flush();
- }
- void saveWriteIndex() {
- EEPROM.put(EEPROM_SIZE - DATA_SIZE, writeIndex);
- }
- void loadWriteIndex() {
- EEPROM.get(EEPROM_SIZE - DATA_SIZE, writeIndex);
- if (writeIndex < 0 || writeIndex >= MAX_DATA_ADDRESS) writeIndex = 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement