Advertisement
Guest User

Nixie Uhr Code

a guest
Oct 12th, 2020
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.52 KB | None | 0 0
  1. A/*
  2. Скетч к проекту "Часы на ГРИ"
  3. Страница проекта (схемы, описания): https://alexgyver.ru/nixieclock/
  4. Исходники на GitHub: https://github.com/AlexGyver/nixieclock/
  5. Нравится, как написан код? Поддержи автора! https://alexgyver.ru/support_alex/
  6. Автор: AlexGyver Technologies, 2018
  7. https://AlexGyver.ru/
  8.  
  9. 1.2 - Einstellung "Rückwärtsanzeigen" für Karte auf IN-12 hinzugefügt
  10. 1.3 - Einstellung zum Ausschalten der Temperaturanzeige hinzugefügt
  11. */
  12. /*
  13. SET
  14. - im Überwachungsmodus gehalten - ALARM einstellen
  15. - im Alarmeinstellungsmodus gehalten - UHR-Einstellung
  16. - Doppelklicken Sie im Alarmmodus - kehren Sie zur Uhr zurück
  17. - in den Uhreinstellungen beibehalten - mit einer neuen Uhrzeit zur Uhr zurückkehren
  18. - Klicken Sie während des Setups auf - ändern Sie die Stunden- / Minuteneinstellungen
  19. ALARM
  20. - Ein / Aus-Alarm
  21. */
  22. // ************************** DIE EINSTELLUNGEN **************************
  23.  
  24. #define BRIGHT 100 // Tageslichthelligkeit, %
  25. #define BRIGHT_N 100 // Nachthelligkeit, %
  26. #define NIGHT_START 23 // Stunde des Übergangs zur Nachtbeleuchtung (BRIGHT_N)
  27. #define NIGHT_END 7 // Stundenschaltung auf Tageslicht (BRIGHT)
  28. #define FREQ 900 // Alarmfrequenz
  29. #define REVERSE_TUBES 0 // 1 - "Spiegeln" Sie die Zeitanzeige (für IN-12-Karte), 0 - Nr
  30.  
  31. #define SHOW_TEMP_HUM 0 // 0 - Temperatur und vl. nicht anzeigen, 1 - anzeigen
  32. #define CLOCK_TIME 10 // Zeit (en), zu der die Uhr angezeigt wird
  33. #define TEMP_TIME 5 // Zeit (en), die Temperatur und Luftfeuchtigkeit anzeigt
  34. #define ALM_TIMEOUT 30 // Alarm-Timeout
  35.  
  36. // *********************** FÜR ENTWICKLER ***********************
  37.  
  38. #define BURN_TIME 200 // Bypass-Zeit im Reinigungsmodus
  39. #define REDRAW_TIME 3000 // einstellige Zykluszeit, ms
  40. #define ON_TIME 2200 // auf Zeit einer Ziffer, ms
  41.  
  42. // пины
  43. #define PIEZO 3
  44. #define DHT_PIN 2
  45. #define ALARM 11
  46.  
  47. #define DECODER0 A0
  48. #define DECODER1 A1
  49. #define DECODER2 A2
  50. #define DECODER3 A3
  51.  
  52. #define KEY0 4 // Punkt
  53. #define KEY1 10 // часы
  54. #define KEY2 9 // часы
  55. #define KEY3 5 // Minute
  56. #define KEY4 6 // Minute
  57. #define KEY5 7 // Sekunde
  58. #define KEY6 8 // Sekunde
  59. #include "DHT.h"
  60. DHT dht(DHT_PIN, DHT22);
  61.  
  62. #include "GyverTimer.h"
  63. GTimer_us redrawTimer(REDRAW_TIME);
  64. GTimer_ms modeTimer((long)CLOCK_TIME * 1000);
  65. GTimer_ms dotTimer(500);
  66. GTimer_ms blinkTimer(800);
  67. GTimer_ms almTimer((long)ALM_TIMEOUT * 1000);
  68.  
  69. #include "GyverButton.h"
  70. GButton btnSet(3, LOW_PULL, NORM_OPEN);
  71. GButton btnUp(3, LOW_PULL, NORM_OPEN);
  72. GButton btnDwn(3, LOW_PULL, NORM_OPEN);
  73.  
  74. #include <Wire.h>
  75. #include "RTClib.h"
  76. RTC_DS3231 rtc;
  77.  
  78. #include "EEPROMex.h"
  79.  
  80. #if (REVERSE_TUBES == 0)
  81. int opts[] = {KEY0, KEY1, KEY2, KEY3, KEY4, KEY5, KEY6};
  82. #else
  83. int opts[] = {KEY6, KEY5, KEY4, KEY3, KEY2, KEY1, KEY0};
  84. #endif
  85.  
  86. // ************************** DEFINIEREN DER WERTE **************************
  87.  
  88. byte counter;
  89. byte digitsDraw[7];
  90. boolean dotFlag;
  91. int8_t hrs = 10, mins = 10, secs;
  92. int8_t alm_hrs = 10, alm_mins = 10;
  93. boolean indState;
  94. int8_t mode = 0; // 0 Uhr, 1 Temperatur, 2 Weckerstellung, 3 Uhreinstellung, 4 Wecker
  95. boolean changeFlag;
  96. boolean blinkFlag;
  97. int on_time = ON_TIME;
  98. boolean alm_flag;
  99.  
  100. void setup() {
  101. Serial.begin(9600);
  102. almTimer.stop();
  103. btnSet.setTimeout(400);
  104. btnSet.setDebounce(90);
  105. dht.begin();
  106. rtc.begin();
  107. if (rtc.lostPower()) {
  108. rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  109. }
  110. DateTime now = rtc.now();
  111. secs = now.second();
  112. mins = now.minute();
  113. hrs = now.hour();
  114.  
  115. pinMode(DECODER0, OUTPUT);
  116. pinMode(DECODER1, OUTPUT);
  117. pinMode(DECODER2, OUTPUT);
  118. pinMode(DECODER3, OUTPUT);
  119. pinMode(KEY0, OUTPUT);
  120. pinMode(KEY1, OUTPUT);
  121. pinMode(KEY2, OUTPUT);
  122. pinMode(KEY3, OUTPUT);
  123. pinMode(KEY4, OUTPUT);
  124. pinMode(KEY5, OUTPUT);
  125. pinMode(KEY6, OUTPUT);
  126.  
  127. pinMode(PIEZO, OUTPUT);
  128. pinMode(ALARM, INPUT_PULLUP);
  129.  
  130. if (EEPROM.readByte(100) != 66) { // Überprüfen Sie den ersten Start
  131. EEPROM.writeByte(100, 66);
  132. EEPROM.writeByte(0, 0); // Wecker
  133. EEPROM.writeByte(1, 0); // Alarm
  134. }
  135. alm_hrs = EEPROM.readByte(0);
  136. alm_mins = EEPROM.readByte(1);
  137.  
  138. sendTime();
  139. changeBright();
  140. }
  141.  
  142. void sendTime() {
  143. digitsDraw[1] = (byte)hrs / 10;
  144. digitsDraw[2] = (byte)hrs % 10;
  145.  
  146. digitsDraw[3] = (byte)mins / 10;
  147. digitsDraw[4] = (byte)mins % 10;
  148.  
  149. digitsDraw[5] = (byte)secs / 10;
  150. digitsDraw[6] = (byte)secs % 10;
  151. }
  152.  
  153. // ************************** TAG/NACHT WECHSEL **************************
  154.  
  155. void changeBright() {
  156. // Helligkeit ab Tageszeit einstellen
  157. if ( (hrs >= NIGHT_START && hrs <= 23)
  158. || (hrs >= 0 && hrs <= NIGHT_END) ) on_time = (float)ON_TIME * BRIGHT_N / 100;
  159. else on_time = (float)ON_TIME * BRIGHT / 100;
  160. }
  161.  
  162. // ************************** UHRZEIT ANZEIGEN **************************
  163.  
  164. void loop() {
  165. if (redrawTimer.isReady()) showDigits();
  166. if (dotTimer.isReady() && (mode == 0 || mode == 1)) calculateTime();
  167. buttonsTick();
  168. if (SHOW_TEMP_HUM && !alm_flag) modeTick();
  169. }
  170.  
  171. // ************************** KNOPFBELEGUNG **************************
  172.  
  173. void buttonsTick() {
  174. int analog = analogRead(7);
  175.  
  176. btnSet.tick(analog <= 1023 && analog > 1000);
  177. btnUp.tick(analog <= 820 && analog > 690);
  178. btnDwn.tick(analog <= 280 && analog > 120);
  179.  
  180. if (mode == 2 || mode == 3) {
  181. if (btnUp.isClick()) {
  182. if (mode == 2) {
  183. if (!changeFlag) {
  184. alm_mins++;
  185. if (alm_mins > 59) {
  186. alm_mins = 0;
  187. alm_hrs++;
  188. }
  189. if (alm_hrs > 23) alm_hrs = 0;
  190. } else {
  191. alm_hrs++;
  192. if (alm_hrs > 23) alm_hrs = 0;
  193. }
  194. } else {
  195. if (!changeFlag) {
  196. mins++;
  197. if (mins > 59) {
  198. mins = 0;
  199. hrs++;
  200. }
  201. if (hrs > 23) hrs = 0;
  202. } else {
  203. hrs++;
  204. if (hrs > 23) hrs = 0;
  205. }
  206. }
  207. }
  208.  
  209. if (btnDwn.isClick()) {
  210. if (mode == 2) {
  211. if (!changeFlag) {
  212. alm_mins--;
  213. if (alm_mins < 0) {
  214. alm_mins = 59;
  215. alm_hrs--;
  216. }
  217. if (alm_hrs < 0) alm_hrs = 23;
  218. } else {
  219. alm_hrs--;
  220. if (alm_hrs < 0) alm_hrs = 23;
  221. }
  222. } else {
  223. if (!changeFlag) {
  224. mins--;
  225. if (mins < 0) {
  226. mins = 59;
  227. hrs--;
  228. }
  229. if (hrs < 0) hrs = 23;
  230. } else {
  231. hrs--;
  232. if (hrs < 0) hrs = 23;
  233. }
  234. }
  235. }
  236.  
  237. if (blinkTimer.isReady()) {
  238. if (blinkFlag) blinkTimer.setInterval(800);
  239. else blinkTimer.setInterval(200);
  240. blinkFlag = !blinkFlag;
  241. }
  242.  
  243. if (mode == 2) {
  244. digitsDraw[1] = alm_hrs / 10;
  245. digitsDraw[2] = alm_hrs % 10;
  246. digitsDraw[3] = alm_mins / 10;
  247. digitsDraw[4] = alm_mins % 10;
  248. } else {
  249. digitsDraw[1] = hrs / 10;
  250. digitsDraw[2] = hrs % 10;
  251. digitsDraw[3] = mins / 10;
  252. digitsDraw[4] = mins % 10;
  253. }
  254.  
  255. digitsDraw[5] = 0; // Sekunde
  256. digitsDraw[6] = 0; // Sekunde
  257.  
  258. if (blinkFlag) { // glühen
  259. if (changeFlag) {
  260. digitsDraw[1] = 10;
  261. digitsDraw[2] = 10;
  262. } else {
  263. digitsDraw[3] = 10;
  264. digitsDraw[4] = 10;
  265. }
  266. }
  267. }
  268.  
  269. if (mode == 1 && btnSet.isClick()) {
  270. mode = 0;
  271. modeTimer.setInterval((long)CLOCK_TIME * 1000);
  272. }
  273.  
  274. if (mode == 0 && btnSet.isHolded()) {
  275. mode = 2;
  276. }
  277.  
  278. if (mode == 2 && btnSet.isHolded()) {
  279. mode = 3;
  280. }
  281.  
  282. if (mode == 2 && btnSet.isDouble()) {
  283. sendTime();
  284.  
  285. EEPROM.updateByte(0, alm_hrs);
  286. EEPROM.updateByte(1, alm_mins);
  287. mode = 0;
  288. modeTimer.setInterval((long)CLOCK_TIME * 1000);
  289. }
  290.  
  291. if (mode == 3 && btnSet.isHolded()) {
  292. sendTime();
  293. mode = 0;
  294. secs = 0;
  295. EEPROM.updateByte(0, alm_hrs);
  296. EEPROM.updateByte(1, alm_mins);
  297. rtc.adjust(DateTime(2014, 1, 21, hrs, mins, 0));
  298.  
  299. changeBright();
  300. modeTimer.setInterval((long)CLOCK_TIME * 1000);
  301. }
  302.  
  303. if ((mode == 2 || mode == 3) && btnSet.isClick()) {
  304. changeFlag = !changeFlag;
  305. }
  306.  
  307. }
  308.  
  309. // ************************** TEMPERATUR UND LUFTFEUCHTIGKEIT MESSEN **************************
  310.  
  311. void modeTick() {
  312. if (modeTimer.isReady()) {
  313. if (mode == 0) {
  314. for (byte i = 1; i < 7; i++) digitsDraw[i] = 10;
  315. mode = 1;
  316. dotFlag = false;
  317. byte temp = dht.readTemperature();
  318. byte hum = dht.readHumidity();
  319. digitsDraw[1] = temp / 10;
  320. digitsDraw[2] = temp % 10;
  321. digitsDraw[3] = 10;
  322. digitsDraw[4] = 10;
  323. digitsDraw[5] = hum / 10;
  324. digitsDraw[6] = hum % 10;
  325. modeTimer.setInterval((long)TEMP_TIME * 1000);
  326. } else if (mode == 1) {
  327. for (byte i = 1; i < 7; i++) digitsDraw[i] = 10;
  328. mode = 0;
  329. modeTimer.setInterval((long)CLOCK_TIME * 1000);
  330. }
  331. }
  332. }
  333.  
  334. // ************************** UHRZEIT ERRECHNEN UND SYNCHRONISIEREN **************************
  335.  
  336. void calculateTime() {
  337. dotFlag = !dotFlag;
  338. if (dotFlag) {
  339. secs++;
  340.  
  341. if (secs > 59) {
  342. secs = 0;
  343. mins++;
  344.  
  345. if (mins == 1 || mins == 30) { // jede halbe Stunde
  346. burnIndicators(); // sauber sauber!
  347. DateTime now = rtc.now(); // Synchronisation mit RTC
  348. secs = now.second();
  349. mins = now.minute();
  350. hrs = now.hour();
  351. }
  352.  
  353. if (!alm_flag && alm_mins == mins && alm_hrs == hrs && !digitalRead(ALARM)) {
  354. mode = 0;
  355. alm_flag = true;
  356. almTimer.start();
  357. almTimer.reset();
  358. }
  359. }
  360. if (mins > 59) {
  361. mins = 0;
  362. hrs++;
  363. if (hrs > 23) hrs = 0;
  364. changeBright();
  365. }
  366.  
  367.  
  368. if (mode == 0) sendTime();
  369.  
  370. if (alm_flag) {
  371. if (almTimer.isReady() || digitalRead(ALARM)) {
  372. alm_flag = false;
  373. almTimer.stop();
  374. mode = 0;
  375. noTone(PIEZO);
  376. modeTimer.setInterval((long)CLOCK_TIME * 1000);
  377. }
  378. }
  379. }
  380.  
  381. // bei Alarm blinken
  382. if (alm_flag) {
  383. if (!dotFlag) {
  384. noTone(PIEZO);
  385. for (byte i = 1; i < 7; i++) digitsDraw[i] = 10;
  386. } else {
  387. tone(PIEZO, FREQ);
  388. sendTime();
  389. }
  390. }
  391.  
  392. }
  393.  
  394. void burnIndicators() {
  395. for (byte ind = 0; ind < 7; ind++) {
  396. digitalWrite(opts[ind], 1);
  397. }
  398. for (byte dig = 0; dig < 10; dig++) {
  399. setDigit(dig);
  400. delayMicroseconds(BURN_TIME);
  401. }
  402. }
  403.  
  404. void showDigits() {
  405. if (indState) {
  406. indState = false;
  407. redrawTimer.setInterval(on_time); // Ordnen Sie den Timer neu an, sodass viele Anzeigen leuchten
  408. counter++; // der Zähler läuft durch die Anzeigen (0 - 6)
  409. if (counter > 6) counter = 0;
  410.  
  411. if (counter != 0) { // wenn dies nicht der Punkt ist
  412. setDigit(digitsDraw[counter]); // Zeigen Sie die NUMMER in ihrer ANZEIGE an
  413. digitalWrite(opts[counter], 1); // Schalten Sie die aktuelle Anzeige ein
  414. } else { // wenn es ein Punkt ist
  415. if (dotFlag)
  416. if (mode != 1) digitalWrite(opts[counter], 1); // Schalten Sie den Punkt ein
  417. else
  418. digitalWrite(opts[counter], 0); // Schalten Sie den Punkt aus
  419. }
  420.  
  421. } else {
  422. indState = true;
  423. digitalWrite(opts[counter], 0); // Schalten Sie die aktuelle Anzeige aus
  424. //setDigit(10);
  425. redrawTimer.setInterval(REDRAW_TIME - on_time); // Ordnen Sie den Timer neu an, so dass viele Anzeigen ausgeschaltet sind
  426. }
  427. }
  428.  
  429. // konfigurieren den Decoder gemäß der angezeigten DIGIT
  430. void setDigit(byte digit) {
  431. switch (digit) {
  432. case 0: setDecoder(0, 0, 0, 0);
  433. break;
  434. case 1: setDecoder(1, 0, 0, 0);
  435. break;
  436. case 2: setDecoder(0, 0, 1, 0);
  437. break;
  438. case 3: setDecoder(1, 0, 1, 0);
  439. break;
  440. case 4: setDecoder(0, 0, 0, 1);
  441. break;
  442. case 5: setDecoder(1, 0, 0, 1);
  443. break;
  444. case 6: setDecoder(0, 0, 1, 1);
  445. break;
  446. case 7: setDecoder(1, 0, 1, 1);
  447. break;
  448. case 8: setDecoder(0, 1, 0, 0);
  449. break;
  450. case 9: setDecoder(1, 1, 0, 0);
  451. break;
  452. case 10: setDecoder(0, 1, 1, 1); // Ziffer ausschalten!
  453. break;
  454. }
  455. }
  456.  
  457. // Decoder-Setup-Funktion
  458. void setDecoder(boolean dec0, boolean dec1, boolean dec2, boolean dec3) {
  459. digitalWrite(DECODER0, dec0);
  460. digitalWrite(DECODER1, dec1);
  461. digitalWrite(DECODER2, dec2);
  462. digitalWrite(DECODER3, dec3);
  463. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement