Hencoop with automatic light and door
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

403 lines
11KB

  1. /*
  2. * Hencoop with automatic lamp and door timer, TM1637 display, two buttons and magnetically operated sealed switch
  3. */
  4. #include <Arduino.h>
  5. #include <TimeLib.h>
  6. #include <Thread.h>
  7. #include <DS1307RTC.h>
  8. #include <SevenSegmentExtended.h> // Extended TM1637 library https://github.com/bremme/arduino-tm1637
  9. long maxOpenDoorVar = 8667; // Interval for maximum door opening time
  10. long closeDoorVar = 3667; // Interval for door closing
  11. const byte redButton = 4; // RedButton: light on, open door
  12. const byte blackButton = 5; // BlackButton: light off, close door
  13. const byte pinLight = 6; // Light power relay
  14. const byte pinDC = 7; // DC motor power relay
  15. const byte pinRelay3 = 8; // Motor relay control
  16. const byte pinRelay4 = 9; // Motor relay control
  17. const byte PIN_CLK = 10; // Define CLK pin (for 4-Digit Display)
  18. const byte PIN_DIO = 11; // Define DIO pin (for 4-Digit Display)
  19. const byte doorSwitch = 12; // Door's magnetically operated sealed switch
  20. long buttonCheck = 200; // Interval for checking button state
  21. byte buttonCommand = 0; // Variable for buttons value: 0 - nothing, 1 - light on, 2 - light off
  22. byte displayWork = 0; // Variable for display status: 0 - nothing, 1 - work
  23. long previousButtonMillis = 0; // Button previous press counter
  24. long buttonPressed = 0; // Button ms pressed counter
  25. long buttonLongPress = 5000; // Interval for long press button action
  26. long buttonShortPress = 600; // Interval for short press button action
  27. unsigned long lastButtonPressed;
  28. SevenSegmentExtended display(PIN_CLK, PIN_DIO);
  29. // Threads:
  30. Thread pressButtonThread = Thread(); // Create thread for button state checking
  31. void setup() {
  32. Serial.begin(9600); // Initializes the Serial connection @ 9600 baud for debug
  33. serStr("starting setup...");
  34. display.begin(); // Initializes the display
  35. display.setBacklight(100); // Set the brightness to 100 %
  36. display.print("INIT"); // Display INIT on the display
  37. pinMode(pinRelay3, OUTPUT);
  38. pinMode(pinRelay4, OUTPUT);
  39. pinMode(pinDC, OUTPUT);
  40. pinMode(pinLight, OUTPUT);
  41. pinMode(redButton, INPUT);
  42. pinMode(blackButton, INPUT);
  43. pinMode(doorSwitch, INPUT);
  44. digitalWrite(pinRelay3, HIGH);
  45. digitalWrite(pinRelay4, HIGH);
  46. digitalWrite(pinDC, HIGH);
  47. digitalWrite(pinLight, HIGH);
  48. while (!Serial); // Wait until Arduino Serial Monitor opens
  49. setSyncProvider(RTC.get); // The function to get the time from the RTC
  50. if(timeStatus()!= timeSet)
  51. Serial.println("Unable to sync with the RTC");
  52. else
  53. Serial.println("RTC has set the system time");
  54. // Button state cheking thread:
  55. pressButtonThread.onRun(pressButton);
  56. pressButtonThread.setInterval(buttonCheck); // Interval for checking button pressing
  57. delay (1000);
  58. display.off();
  59. serStr("...setup finished");
  60. }
  61. void loop() {
  62. // Threads init:
  63. if (pressButtonThread.shouldRun())
  64. pressButtonThread.run();
  65. if (timeStatus() == timeSet) { // If RTC works - call the checkTime function
  66. checkTime();
  67. } else {
  68. display.on();
  69. display.print("SET TIME");
  70. }
  71. }
  72. // Check button pressing thread
  73. void pressButton() {
  74. unsigned long currentMillis = millis();
  75. if (((currentMillis - previousButtonMillis) > 20000) && (displayWork == 1)) {
  76. display.off();
  77. displayWork = 0;
  78. }
  79. if (digitalRead(redButton) == HIGH || digitalRead(blackButton) == HIGH) {
  80. display.on();
  81. displayWork = 1;
  82. display.printTime(hour(), minute(), true);
  83. buttonPressed = buttonPressed + 200;
  84. if (buttonPressed > buttonShortPress) {
  85. if (digitalRead(redButton) == HIGH) buttonCommand = 1;
  86. if (digitalRead(blackButton) == HIGH) buttonCommand = 2;
  87. }
  88. if (buttonPressed > buttonLongPress) {
  89. buttonPressed = 0;
  90. buttonCommand = 0;
  91. if (digitalRead(redButton) == HIGH) serStr("Red button long press");
  92. if (digitalRead(redButton) == HIGH) openDoor();
  93. if (digitalRead(blackButton) == HIGH) serStr("Black button long press");
  94. if (digitalRead(blackButton) == HIGH) closeDoor();
  95. }
  96. previousButtonMillis = currentMillis;
  97. } else {
  98. buttonPressed = 0;
  99. }
  100. if (digitalRead(redButton) == LOW && digitalRead(blackButton) == LOW) {
  101. if (buttonCommand == 1) serStr("Red button short press");
  102. if (buttonCommand == 1) lightOn();
  103. if (buttonCommand == 2) serStr("Black button short press");
  104. if (buttonCommand == 2) lightOff();
  105. }
  106. }
  107. void lightOn() {
  108. buttonCommand = 0;
  109. digitalWrite(pinLight, LOW);
  110. serStr("Light on");
  111. }
  112. void lightOff() {
  113. buttonCommand = 0;
  114. digitalWrite(pinLight, HIGH);
  115. serStr("Light off");
  116. }
  117. void openDoor() {
  118. unsigned long openStart = millis();
  119. if (digitalRead(doorSwitch) == LOW) {
  120. serStr("Door opening started...");
  121. digitalWrite(pinRelay3, HIGH);
  122. digitalWrite(pinRelay4, HIGH);
  123. delay(1000);
  124. digitalWrite(pinDC, LOW); // DC on
  125. delay(3000);
  126. digitalWrite(pinRelay4, LOW);
  127. while (digitalRead(doorSwitch) == LOW) {
  128. if ((millis() - openStart) > maxOpenDoorVar) {
  129. break;
  130. }
  131. delay(55);
  132. }
  133. digitalWrite(pinRelay4, HIGH);
  134. delay(2000);
  135. digitalWrite(pinDC, HIGH); // DC off
  136. delay(1000);
  137. digitalWrite(pinRelay3, HIGH);
  138. digitalWrite(pinRelay4, HIGH);
  139. serStr("...door opening finished");
  140. } else {
  141. serStr("Can't open door, magnet shows that door is open");
  142. display.on();
  143. display.print("can't - door is open");
  144. display.off();
  145. }
  146. }
  147. void closeDoor() {
  148. if (digitalRead(doorSwitch) == HIGH) {
  149. serStr("Door closing started...");
  150. digitalWrite(pinRelay3, HIGH);
  151. digitalWrite(pinRelay4, HIGH);
  152. delay(1000);
  153. digitalWrite(pinDC, LOW); // DC on
  154. delay(3000);
  155. digitalWrite(pinRelay3, LOW);
  156. delay(closeDoorVar);
  157. digitalWrite(pinRelay3, HIGH);
  158. delay(2000);
  159. digitalWrite(pinDC, HIGH); // DC off
  160. delay(1000);
  161. digitalWrite(pinRelay3, HIGH);
  162. digitalWrite(pinRelay4, HIGH);
  163. serStr("...door closing finished");
  164. } else {
  165. serStr("Can't close door, magnet shows that door is closed");
  166. display.on();
  167. display.print("can't - door is closed");
  168. display.off();
  169. }
  170. }
  171. // Send string to serial monitor with millis() counter and date/time
  172. void serStr(const char* serString) {
  173. long currentTime = millis();
  174. String space = " ";
  175. String stringToPrint = currentTime + space + serString;
  176. Serial.println(stringToPrint);
  177. // RTC mark
  178. Serial.print("RTC time = ");
  179. Serial.print(hour());
  180. Serial.write(':');
  181. Serial.print(minute());
  182. Serial.write(':');
  183. Serial.print(second());
  184. Serial.print(", date (D/M/Y) = ");
  185. Serial.print(day());
  186. Serial.write('/');
  187. Serial.print(month());
  188. Serial.write('/');
  189. Serial.print(year());
  190. Serial.println();
  191. }
  192. void checkTime() {
  193. // January 08:06 08:50 16:27 17:11
  194. if (month() == 1) {
  195. if (hour() == 8 && minute() == 15) {
  196. openDoor();
  197. delay(60000);
  198. }
  199. if (hour() == 15 && minute() == 55) {
  200. lightOn();
  201. delay(60000);
  202. }
  203. if (hour() == 17 && minute() == 35) {
  204. lightOff();
  205. delay(60000);
  206. }
  207. if (hour() == 17 && minute() == 50) {
  208. closeDoor();
  209. delay(60000);
  210. }
  211. }
  212. // February 07:18 07:56 17:31 18:10
  213. if (month() == 2) {
  214. if (hour() == 7 && minute() == 20) {
  215. openDoor();
  216. delay(60000);
  217. }
  218. if (hour() == 16 && minute() == 55) {
  219. lightOn();
  220. delay(60000);
  221. }
  222. if (hour() == 18 && minute() == 30) {
  223. lightOff();
  224. delay(60000);
  225. }
  226. if (hour() == 18 && minute() == 45) {
  227. closeDoor();
  228. delay(60000);
  229. }
  230. }
  231. // March 06:11 06:47 18:30 19:07
  232. if (month() == 3) {
  233. if (hour() == 6 && minute() == 15) {
  234. openDoor();
  235. delay(60000);
  236. }
  237. if (hour() == 17 && minute() == 55) {
  238. lightOn();
  239. delay(60000);
  240. }
  241. if (hour() == 19 && minute() == 30) {
  242. lightOff();
  243. delay(60000);
  244. }
  245. if (hour() == 19 && minute() == 45) {
  246. closeDoor();
  247. delay(60000);
  248. }
  249. }
  250. // April 04:48 05:27 19:33 20:13
  251. if (month() == 4) {
  252. if (hour() == 4 && minute() == 55) {
  253. openDoor();
  254. delay(60000);
  255. }
  256. if (hour() == 20 && minute() == 50) {
  257. closeDoor();
  258. delay(60000);
  259. }
  260. }
  261. // May 03:31 04:20 20:32 21:21
  262. if (month() == 5) {
  263. if (hour() == 3 && minute() == 50) {
  264. openDoor();
  265. delay(60000);
  266. }
  267. if (hour() == 21 && minute() == 55) {
  268. closeDoor();
  269. delay(60000);
  270. }
  271. }
  272. // June 02:43 03:44 21:15 22:16
  273. if (month() == 6) {
  274. if (hour() == 3 && minute() == 15) {
  275. openDoor();
  276. delay(60000);
  277. }
  278. if (hour() == 22 && minute() == 50) {
  279. closeDoor();
  280. delay(60000);
  281. }
  282. }
  283. // July 03:08 04:04 21:05 22:00
  284. if (month() == 7) {
  285. if (hour() == 3 && minute() == 30) {
  286. openDoor();
  287. delay(60000);
  288. }
  289. if (hour() == 22 && minute() == 35) {
  290. closeDoor();
  291. delay(60000);
  292. }
  293. }
  294. // August 04:15 04:58 20:08 20:51
  295. if (month() == 8) {
  296. if (hour() == 4 && minute() == 15) {
  297. openDoor();
  298. delay(60000);
  299. }
  300. if (hour() == 21 && minute() == 30) {
  301. closeDoor();
  302. delay(60000);
  303. }
  304. }
  305. // September 05:21 05:58 18:50 19:27
  306. if (month() == 9) {
  307. if (hour() == 5 && minute() == 25) {
  308. openDoor();
  309. delay(60000);
  310. }
  311. if (hour() == 18 && minute() == 20) {
  312. lightOn();
  313. delay(60000);
  314. }
  315. if (hour() == 19 && minute() == 50) {
  316. lightOff();
  317. delay(60000);
  318. }
  319. if (hour() == 20 && minute() == 5) {
  320. closeDoor();
  321. delay(60000);
  322. }
  323. }
  324. // October 06:20 06:57 17:32 18:09
  325. if (month() == 10) {
  326. if (hour() == 6 && minute() == 25) {
  327. openDoor();
  328. delay(60000);
  329. }
  330. if (hour() == 16 && minute() == 55) {
  331. lightOn();
  332. delay(60000);
  333. }
  334. if (hour() == 18 && minute() == 30) {
  335. lightOff();
  336. delay(60000);
  337. }
  338. if (hour() == 18 && minute() == 45) {
  339. closeDoor();
  340. delay(60000);
  341. }
  342. }
  343. // November 07:20 08:02 16:24 17:06
  344. if (month() == 11) {
  345. if (hour() == 7 && minute() == 30) {
  346. openDoor();
  347. delay(60000);
  348. }
  349. if (hour() == 15 && minute() == 55) {
  350. lightOn();
  351. delay(60000);
  352. }
  353. if (hour() == 17 && minute() == 30) {
  354. lightOff();
  355. delay(60000);
  356. }
  357. if (hour() == 17 && minute() == 45) {
  358. closeDoor();
  359. delay(60000);
  360. }
  361. }
  362. // December 08:05 08:51 15:56 16:42
  363. if (month() == 12) {
  364. if (hour() == 8 && minute() == 20) {
  365. openDoor();
  366. delay(60000);
  367. }
  368. if (hour() == 15 && minute() == 25) {
  369. lightOn();
  370. delay(60000);
  371. }
  372. if (hour() == 17 && minute() == 5) {
  373. lightOff();
  374. delay(60000);
  375. }
  376. if (hour() == 17 && minute() == 25) {
  377. closeDoor();
  378. delay(60000);
  379. }
  380. }
  381. }