Advertisement
username32390394054

Untitled

Jul 5th, 2025
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.40 KB | Source Code | 0 0
  1. #include <Wire.h>
  2. #include <DS3232RTC.h>
  3. #include <TimeLib.h>
  4. #include <EEPROM.h>
  5. #include <avr/sleep.h>
  6. #include <avr/interrupt.h>
  7. #include <PinChangeInterrupt.h>
  8.  
  9. struct Record {
  10.   byte hour;
  11.   byte minute;
  12.   byte second;
  13.   byte day;
  14.   byte month;
  15.   byte year;
  16.   int value;
  17. };
  18.  
  19. DS3232RTC rtc;
  20.  
  21. const int rtcIntPin    = 2; // INT0 - RTC alarm
  22. const int sensorPin3   = 3; // INT1 - Ball sensor
  23. const int buttonPin4   = 4; // PCINT - Show records
  24. const int sensorPin8   = 8; // PCINT - Log value
  25. const int relayPin     = 5;
  26.  
  27. volatile bool sensor3Triggered = false;
  28. volatile bool rtcAlarmTriggered = false;
  29. volatile bool buttonPressed = false;
  30. volatile bool sensor8Triggered = false;
  31.  
  32. const int EEPROM_SIZE = 1024;
  33. const int DATA_SIZE = sizeof(Record);
  34. const int MAX_DATA_ADDRESS = EEPROM_SIZE - 2 * DATA_SIZE;
  35. int writeIndex = 0;
  36.  
  37. time_t lastRecordTime = 0;
  38. const unsigned long DEBOUNCE_TIME = 500;
  39. volatile unsigned long lastSensor3Time = 0;
  40.  
  41. void setup() {
  42.   pinMode(sensorPin3, INPUT);
  43.   pinMode(buttonPin4, INPUT); // External resistor connected
  44.   pinMode(sensorPin8, INPUT);
  45.   pinMode(relayPin, OUTPUT);
  46.   digitalWrite(relayPin, LOW);
  47.  
  48.   Serial.begin(9600);
  49.   Wire.begin();
  50.   rtc.begin();
  51.   setSyncProvider(rtc.get);
  52.  
  53.   rtc.setAlarm(DS3232RTC::ALM1_MATCH_SECONDS, 0, 0, 0, 0);
  54.   rtc.alarmInterrupt(DS3232RTC::ALARM_1, true);
  55.   rtc.alarm(DS3232RTC::ALARM_1); // clear flag
  56.  
  57.   attachInterrupt(digitalPinToInterrupt(sensorPin3), handleSensor3Interrupt, FALLING);
  58.   attachInterrupt(digitalPinToInterrupt(rtcIntPin), handleRTCAlarmInterrupt, FALLING);
  59.   attachPinChangeInterrupt(digitalPinToPCINT(buttonPin4), handleButton, FALLING);
  60.   attachPinChangeInterrupt(digitalPinToPCINT(sensorPin8), handleSensor8, RISING);
  61.  
  62.   loadWriteIndex();
  63. }
  64.  
  65. void loop() {
  66.   time_t now = rtc.get();
  67.  
  68.   if (sensor3Triggered) {
  69.     sensor3Triggered = false;
  70.     unsigned long nowMillis = millis();
  71.     if (nowMillis - lastSensor3Time >= DEBOUNCE_TIME && now - lastRecordTime >= 60) {
  72.       recordTime(773);
  73.       lastRecordTime = now;
  74.     }
  75.     lastSensor3Time = nowMillis;
  76.   }
  77.  
  78.   if (sensor8Triggered) {
  79.     sensor8Triggered = false;
  80.     recordTime(778);
  81.   }
  82.  
  83.   if (buttonPressed) {
  84.     buttonPressed = false;
  85.     showAllRecords();
  86.   }
  87.  
  88.   if (rtcAlarmTriggered) {
  89.     rtcAlarmTriggered = false;
  90.     rtc.alarm(DS3232RTC::ALARM_1); // clear flag
  91.     checkRelayState();
  92.   }
  93.  
  94.   goToSleep();
  95. }
  96.  
  97. void handleSensor3Interrupt() {
  98.   sensor3Triggered = true;
  99. }
  100.  
  101. void handleRTCAlarmInterrupt() {
  102.   rtcAlarmTriggered = true;
  103. }
  104.  
  105. void handleButton() {
  106.   static unsigned long lastPress = 0;
  107.   if (millis() - lastPress > 300) {
  108.     buttonPressed = true;
  109.     lastPress = millis();
  110.   }
  111. }
  112.  
  113. void handleSensor8() {
  114.   static unsigned long lastTrigger = 0;
  115.   if (millis() - lastTrigger > 500) {
  116.     sensor8Triggered = true;
  117.     lastTrigger = millis();
  118.   }
  119. }
  120.  
  121. void goToSleep() {
  122.   Serial.flush(); // wait for output
  123.   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  124.   sleep_enable();
  125.   sleep_bod_disable();
  126.   sei(); // ensure global interrupts are on
  127.   sleep_cpu();
  128.   sleep_disable();
  129.  
  130.   if (Serial) {
  131.     Serial.begin(9600);
  132.     delay(200);
  133.     while (Serial.available()) Serial.read();
  134.   }
  135. }
  136.  
  137. void checkRelayState() {
  138.   time_t now = rtc.get();
  139.   byte hr = hour(now);
  140.   byte min = minute(now);
  141.   if (hr == 21 && min >= 5 && min <= 45) {
  142.     digitalWrite(relayPin, HIGH);
  143.   } else {
  144.     digitalWrite(relayPin, LOW);
  145.   }
  146. }
  147.  
  148. Record createRecordFromRTC(int value) {
  149.   time_t t = rtc.get();
  150.   Record rec;
  151.   rec.hour = hour(t);
  152.   rec.minute = minute(t);
  153.   rec.second = second(t);
  154.   rec.day = day(t);
  155.   rec.month = month(t);
  156.   rec.year = year(t) % 100;
  157.   rec.value = value;
  158.   EEPROM.put(writeIndex, rec);
  159.   return rec;
  160. }
  161.  
  162. void printRecord(const Record& rec) {
  163.   Serial.print(rec.hour); Serial.print(":");
  164.   if (rec.minute < 10) Serial.print("0");
  165.   Serial.print(rec.minute); Serial.print(":");
  166.   if (rec.second < 10) Serial.print("0");
  167.   Serial.print(rec.second); Serial.print("  ");
  168.   if (rec.day < 10) Serial.print("0");
  169.   Serial.print(rec.day); Serial.print(".");
  170.   if (rec.month < 10) Serial.print("0");
  171.   Serial.print(rec.month); Serial.print(".");
  172.   Serial.print("20");
  173.   if (rec.year < 10) Serial.print("0");
  174.   Serial.print(rec.year); Serial.print("  ");
  175.   Serial.println(rec.value);
  176.   Serial.flush();
  177. }
  178.  
  179. void recordTime(int value) {
  180.   Record rec = createRecordFromRTC(value);
  181.   Serial.print("Saved RTC record at ");
  182.   Serial.println(writeIndex);
  183.   printRecord(rec);
  184.  
  185.   writeIndex += DATA_SIZE;
  186.   if (writeIndex >= MAX_DATA_ADDRESS) {
  187.     Serial.println("EEPROM full. Wrapping to 0.");
  188.     writeIndex = 0;
  189.   }
  190.   saveWriteIndex();
  191. }
  192.  
  193. void showAllRecords() {
  194.   Serial.println("----- EEPROM Records -----");
  195.   for (int index = 0; index < MAX_DATA_ADDRESS; index += DATA_SIZE) {
  196.     Record rec;
  197.     EEPROM.get(index, rec);
  198.     if (rec.year == 0xFF || rec.year == 0x00 || rec.year > 99 ||
  199.         rec.hour > 23 || rec.minute > 59 || rec.second > 59 ||
  200.         rec.day == 0 || rec.day > 31 || rec.month == 0 || rec.month > 12) {
  201.       continue;
  202.     }
  203.     printRecord(rec);
  204.   }
  205.   Serial.println("--------------------------");
  206.   Serial.flush();
  207. }
  208.  
  209. void saveWriteIndex() {
  210.   EEPROM.put(EEPROM_SIZE - DATA_SIZE, writeIndex);
  211. }
  212.  
  213. void loadWriteIndex() {
  214.   EEPROM.get(EEPROM_SIZE - DATA_SIZE, writeIndex);
  215.   if (writeIndex < 0 || writeIndex >= MAX_DATA_ADDRESS) writeIndex = 0;
  216. }
  217.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement