From 53c36f9d0952c14d2b7cb8b14c186f1e46a57c53 Mon Sep 17 00:00:00 2001 From: egorguslyan <egorguslyan@gmail.com> Date: Tue, 4 Jan 2022 20:50:11 +0300 Subject: [PATCH] RTC, handlers --- .gitmodules | 6 +- Dashboard/Dashboard.ino | 119 ++++++++- Dashboard/config.h | 7 +- Dashboard/screens.h | 3 +- libraries/microDS3231/LICENSE | 21 ++ libraries/microDS3231/README.md | 200 +++++++++++++++ .../examples/DS3231_demo/DS3231_demo.ino | 101 ++++++++ .../examples/DateTime/DateTime.ino | 52 ++++ libraries/microDS3231/keywords.txt | 53 ++++ libraries/microDS3231/library.properties | 9 + libraries/microDS3231/src/buildTime.h | 83 +++++++ libraries/microDS3231/src/microDS3231.cpp | 229 ++++++++++++++++++ libraries/microDS3231/src/microDS3231.h | 82 +++++++ 13 files changed, 960 insertions(+), 5 deletions(-) create mode 100644 libraries/microDS3231/LICENSE create mode 100644 libraries/microDS3231/README.md create mode 100644 libraries/microDS3231/examples/DS3231_demo/DS3231_demo.ino create mode 100644 libraries/microDS3231/examples/DateTime/DateTime.ino create mode 100644 libraries/microDS3231/keywords.txt create mode 100644 libraries/microDS3231/library.properties create mode 100644 libraries/microDS3231/src/buildTime.h create mode 100644 libraries/microDS3231/src/microDS3231.cpp create mode 100644 libraries/microDS3231/src/microDS3231.h diff --git a/.gitmodules b/.gitmodules index ca8da7d..fd553b0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,4 +4,8 @@ [submodule "mhz19_uart"] path = libraries/mhz19_uart - url = https://github.com/piot-jp-Team/mhz19_uart \ No newline at end of file + url = https://github.com/piot-jp-Team/mhz19_uart + +[submodule "microDS3231"] + path = libraries/microDS3231 + url = https://github.com/GyverLibs/microDS3231 \ No newline at end of file diff --git a/Dashboard/Dashboard.ino b/Dashboard/Dashboard.ino index dc95587..8817614 100644 --- a/Dashboard/Dashboard.ino +++ b/Dashboard/Dashboard.ino @@ -27,6 +27,10 @@ #include <MHZ19_uart.h> /********************************/ +/**********RTC library***********/ +#include <microDS3231.h> +/********************************/ + #include <EEPROM.h> /*************Marcos*************/ @@ -104,17 +108,92 @@ microLED<NUMLEDS, LEDsPin, MLED_NO_CLOCK, LED_WS2812, ORDER_GRB, CLI_AVER, SAVE_ textbox tb; #include "configScreens.h" MHZ19_uart co2; +MicroDS3231 rtc; -extern volatile unsigned long timer0_millis; +extern volatile uint32_t timer0_overflow_count; +extern volatile uint32_t timer0_millis; + +// Spaghetti +void buttons() +{ + static uint32_t timer2_btnl = 0; + static uint32_t timer2_btnr = 0; + static uint8_t btn_flags = 0; + if(digitalRead(LBTN) || bitRead(btn_flags, 0)) + { + if(bitRead(btn_flags, 1)) + { + if(!bitRead(btn_flags, 0)) + { + bitWrite(btn_flags, 0, 1); + timer2_btnl = millis(); + } + if((millis() - timer2_btnl <= BOTH_DELAY) && digitalRead(RBTN)) + bitWrite(btn_flags, 1, 1); + else if((millis() - timer2_btnl <= SWIPE_DELAY) && digitalRead(RBTN)) + { + globalVars.swipeRight = 1; + bitWrite(btn_flags, 1, 1); + } + else if(digitalRead(RBTN)) + bitWrite(btn_flags, 1, 1); + else if(!(millis() - timer2_btnl <= SWIPE_DELAY) && !digitalRead(LBTN)) + { + globalVars.tapLeft = 1; + bitWrite(btn_flags, 1, 1); + } + else if(millis() - timer2_btnl > HOLD_DELAY) + { + globalVars.holdLeft = 1; + bitWrite(btn_flags, 1, 1); + } + } + else if(!digitalRead(LBTN) && !digitalRead(RBTN)) btn_flags = 0; + } + else if(digitalRead(RBTN) || bitRead(btn_flags, 0)) + { + if(bitRead(btn_flags, 1)) + { + if(!bitRead(btn_flags, 0)) + { + bitWrite(btn_flags, 0, 1); + timer2_btnl = millis(); + } + if((millis() - timer2_btnl <= BOTH_DELAY) && digitalRead(LBTN)) + bitWrite(btn_flags, 1, 1); + else if((millis() - timer2_btnl <= SWIPE_DELAY) && digitalRead(LBTN)) + { + globalVars.swipeLeft = 1; + bitWrite(btn_flags, 1, 1); + } + else if(digitalRead(LBTN)) + bitWrite(btn_flags, 1, 1); + else if(!(millis() - timer2_btnl <= SWIPE_DELAY) && !digitalRead(RBTN)) + { + globalVars.tapRight = 1; + bitWrite(btn_flags, 1, 1); + } + else if(millis() - timer2_btnl > HOLD_DELAY) + { + globalVars.holdRight = 1; + bitWrite(btn_flags, 1, 1); + } + } + else if(!digitalRead(LBTN) && !digitalRead(RBTN)) btn_flags = 0; + } +} void setup() { // Hardware init + pinMode(LBTN, INPUT); + pinMode(RBTN, INPUT); matrix.setBrightness(100); matrix.clear(); matrix.show(); co2.begin(CO2TX, CO2RX); co2.setAutoCalibration(false); + // Serial transmission Serial.begin(9600); // For safe debugging //while (!Serial.available()) {} @@ -126,6 +205,12 @@ void setup() if((eepromData & 0b11111100 == special_key) && (eepromData & 0b00000011 < 3)) globalVars.panelOrientation = eepromData & 0b00000011; else globalVars.panelOrientation = PANEL_UNKNOWN; + eepromData = EEPROM.read(1); + if(!(eepromData == special_key)) + { + EEPROM.write(1, special_key); + rtc.setTime(COMPILE_TIME); + } // Set start screen globalVars.currentScreen = startWith; @@ -152,6 +237,33 @@ void loop() Serial.end(); } + // Measure CO2 every 5 seconds + static uint32_t timer0 = 0; + TIMER(timer0, 5000) + { + globalVars.ppm = co2.getPPM(); + } + + // Update time every second + static uint32_t timer1 = 0; + static DateTime DTtmp; + TIMER(timer1, 999) + { + globalVars.hours = DTtmp.hour; + globalVars.minutes = DTtmp.minute; + if(globalVars.seconds != DTtmp.second) + DTtmp = rtc.getTime(); + globalVars.seconds = DTtmp.second; + } + + // Detect taps and swipes + static uint32_t timer2 = 0; + TIMER(timer2, 10) + { + buttons(); + } + + // Display switch(globalVars.prepare) { case 1: @@ -163,7 +275,6 @@ void loop() screens[globalVars.currentScreen].func(&screens[globalVars.currentScreen].arg); break; } - matrix.show(); // Monthly preventative safe reset of the millis() timer @@ -171,9 +282,13 @@ void loop() { noInterrupts(); timer0_millis = 0; + timer0_overflow_count = 0; interrupts(); globalVars.timer = 0; tb.resetTimers(); timer_debug0 = 0; + timer0 = 0; + timer1 = 0; + timer2 = 0; } } \ No newline at end of file diff --git a/Dashboard/config.h b/Dashboard/config.h index f8ffa54..99a356e 100644 --- a/Dashboard/config.h +++ b/Dashboard/config.h @@ -9,4 +9,9 @@ #define HEIGHT 9 #define COLOR1 mHEX(0x9aa100) -#define COLOR2 mHEX(0x000aa0) \ No newline at end of file +#define COLOR2 mHEX(0x000aa0) + +// Delay between button fronts _|¯ have to be greater than BOTH_DELAY and less than SWIPE_DELAY +#define BOTH_DELAY 30 +#define SWIPE_DELAY 700 +#define HOLD_DELAY 2000 \ No newline at end of file diff --git a/Dashboard/screens.h b/Dashboard/screens.h index 76eea57..5a8fc4f 100644 --- a/Dashboard/screens.h +++ b/Dashboard/screens.h @@ -97,7 +97,8 @@ void welcome(Arg *arg) void welcomePrepare() { - memset(globalVars.leds, mBlack, sizeof(mData) * NUMLEDS); + //memset(globalVars.leds, mBlack, sizeof(mData) * NUMLEDS); + return; } void dashboard(Arg *arg) diff --git a/libraries/microDS3231/LICENSE b/libraries/microDS3231/LICENSE new file mode 100644 index 0000000..353b7ee --- /dev/null +++ b/libraries/microDS3231/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Alex + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/microDS3231/README.md b/libraries/microDS3231/README.md new file mode 100644 index 0000000..781256f --- /dev/null +++ b/libraries/microDS3231/README.md @@ -0,0 +1,200 @@ + + +# microDS3231 +Ð›Ñ‘Ð³ÐºÐ°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ° Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ RTC DS3231 Ð´Ð»Ñ Arduino +- Чтение и запиÑÑŒ времени +- Вывод в char* и String +- Чтение температуры датчика + +### СовмеÑтимоÑÑ‚ÑŒ +СовмеÑтима Ñо вÑеми Arduino платформами (иÑпользуютÑÑ Arduino-функции) + +## Содержание +- [УÑтановка](#install) +- [ИнициализациÑ](#init) +- [ИÑпользование](#usage) +- [Пример](#example) +- [ВерÑии](#versions) +- [Баги и Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑвÑзь](#feedback) + +<a id="install"></a> +## УÑтановка +- Библиотеку можно найти по названию **microDS3231** и уÑтановить через менеджер библиотек в: + - Arduino IDE + - Arduino IDE v2 + - PlatformIO +- [Скачать библиотеку](https://github.com/GyverLibs/microDS3231/archive/refs/heads/main.zip) .zip архивом Ð´Ð»Ñ Ñ€ÑƒÑ‡Ð½Ð¾Ð¹ уÑтановки: + - РаÑпаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64) + - РаÑпаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32) + - РаÑпаковать и положить в *Документы/Arduino/libraries/* + - (Arduino IDE) автоматичеÑÐºÐ°Ñ ÑƒÑтановка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать Ñкачанный архив +- Читай более подробную инÑтрукцию по уÑтановке библиотек [здеÑÑŒ](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) + +<a id="init"></a> +## Ð˜Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ +```cpp +MicroDS3231 rtc; // Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾ умолчанию 0x68 +MicroDS3231 rtc(адреÑ); // указать Ñвой Ð°Ð´Ñ€ÐµÑ +``` + +<a id="usage"></a> +## ИÑпользование +```cpp +bool begin(); // инициализациÑ, вернет true, еÑли RTC найден +void setTime(uint8_t param); // уÑтановка времени == времени компилÑции +void setTime(DateTime time); // уÑтановить из Ñтруктуры DateTime +void setTime(int8_t seconds, int8_t minutes, int8_t hours, int8_t date, int8_t month, int16_t year); // уÑтановка времени +void setHMSDMY(int8_t hours, int8_t minutes, int8_t seconds, int8_t date, int8_t month, int16_t year); // уÑтановка времени тип 2 + +// Ñтруктура DateTime +uint8_t second; +uint8_t minute; +uint8_t hour; +uint8_t day; +uint8_t date; +uint8_t month; +uint16_t year; + +DateTime getTime(); // получить в Ñтруктуру DateTime +uint8_t getSeconds(); // получить Ñекунды +uint8_t getMinutes(); // получить минуты +uint8_t getHours(); // получить чаÑÑ‹ +uint8_t getDay(); // получить день недели +uint8_t getDate(); // получить чиÑло +uint16_t getYear(); // получить год +uint8_t getMonth(); // получить меÑÑц + +String getTimeString(); // получить Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº Ñтроку вида HH:MM:SS +String getDateString(); // получить дату как Ñтроку вида DD.MM.YYYY +void getTimeChar(char* array); // получить Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº char array [8] вида HH:MM:SS +void getDateChar(char* array); // получить дату как char array [10] вида DD.MM.YYYY + +bool lostPower(); // проверка на ÑÐ±Ñ€Ð¾Ñ Ð¿Ð¸Ñ‚Ð°Ð½Ð¸Ñ +float getTemperatureFloat();// получить температуру float +int getTemperature(); // получить температуру int +``` + +<a id="example"></a> +## Пример +ОÑтальные примеры Ñмотри в **examples**! +```cpp +// демо возможноÑтей библиотеки +#include <microDS3231.h> +MicroDS3231 rtc; + +void setup() { + Serial.begin(9600); + + // проверка Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð½Ð° линии i2c + // вызов rtc.begin() не обÑзателен Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ + if (!rtc.begin()) { + Serial.println("DS3231 not found"); + for(;;); + } + + // ======== УСТÐÐОВКРВРЕМЕÐИ ÐВТОМÐТИЧЕСКИ ======== + // rtc.setTime(COMPILE_TIME); // уÑтановить Ð²Ñ€ÐµÐ¼Ñ == времени компилÑции + + // визуально громоздкий, но более "лёгкий" Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ Ð·Ñ€ÐµÐ½Ð¸Ñ Ð¿Ð°Ð¼Ñти ÑпоÑоб уÑтановить Ð²Ñ€ÐµÐ¼Ñ ÐºÐ¾Ð¼Ð¿Ð¸Ð»Ñции + rtc.setTime(BUILD_SEC, BUILD_MIN, BUILD_HOUR, BUILD_DAY, BUILD_MONTH, BUILD_YEAR); + + if (rtc.lostPower()) { // выполнитÑÑ Ð¿Ñ€Ð¸ ÑброÑе батарейки + Serial.println("lost power!"); + // тут можно однократно уÑтановить Ð²Ñ€ÐµÐ¼Ñ == времени компилÑции + } + + // ======== УСТÐÐОВКРВРЕМЕÐИ ВРУЧÐУЮ ======== + // уÑтановить Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ можно Ð´Ð²ÑƒÐ¼Ñ ÑпоÑобами (подÑтавить реальные чиÑла) + //rtc.setTime(SEC, MIN, HOUR, DAY, MONTH, YEAR); + //rtc.setHMSDMY(HOUR, MIN, SEC, DAY, MONTH, YEAR); + + // также можно уÑтановить Ð²Ñ€ÐµÐ¼Ñ Ñ‡ÐµÑ€ÐµÐ· DateTime + /* + DateTime now; + now.second = 0; + now.minute = 10; + now.hour = 50; + now.date = 2; + now.month = 9; + now.year = 2021; + + rtc.setTime(now); // загружаем в RTC + */ +} + +void loop() { + // получение и вывод каждой компоненты + Serial.print(rtc.getHours()); + Serial.print(":"); + Serial.print(rtc.getMinutes()); + Serial.print(":"); + Serial.print(rtc.getSeconds()); + Serial.print(" "); + Serial.print(rtc.getDay()); + Serial.print(" "); + Serial.print(rtc.getDate()); + Serial.print("/"); + Serial.print(rtc.getMonth()); + Serial.print("/"); + Serial.println(rtc.getYear()); + + /* + // можно через DateTime (более оптимально): + DateTime now = rtc.getTime(); + Serial.print(now.hour); + Serial.print(":"); + Serial.print(now.minute); + Serial.print(":"); + Serial.print(now.second); + Serial.print(" "); + Serial.print(now.day); + Serial.print(" "); + Serial.print(now.date); + Serial.print("/"); + Serial.print(now.month); + Serial.print("/"); + Serial.println(now.year); + */ + + // вывод температуры чипа + Serial.println(rtc.getTemperatureFloat()); + //Serial.println(rtc.getTemperature()); + + // вывод времени готовой Ñтрокой String + Serial.println(rtc.getTimeString()); + + // вывод даты готовой Ñтрокой String + Serial.println(rtc.getDateString()); + + // вывод времени через char array + char time[8]; + rtc.getTimeChar(time); + Serial.println(time); + + // вывод даты через char array + char date[10]; + rtc.getDateChar(date); + Serial.println(date); + + Serial.println(); + delay(500); +} +``` + +<a id="versions"></a> +## ВерÑии +- v1.2 - добавлены Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° вводимые в setTime чиÑла. Также Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ð²ÐµÑти 29 Ñ„ÐµÐ²Ñ€Ð°Ð»Ñ ÑƒÐ²Ñ‹ =) +- v1.3 - пофикшено завиÑание, когда модуль отключен но опрашиваетÑÑ +- v1.4 - незначительный Ñ„Ð¸ÐºÑ +- v2.0 - новые возможноÑти, Ð¾Ð¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¸ облегчение +- v2.1 - добавил вывод температуры, вывод в String и char +- v2.2 - иÑправлены дни недели (пн-Ð²Ñ 1-7) +- v2.3 - небольшие иÑправлениÑ, оптимизациÑ, изменён порÑдок вывода даты +- v2.4 - иÑправлена уÑтановка времени компилÑции +- v2.5 - добавлен begin Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð½Ð° линии +- v2.6 - иÑправлены отрицательные температуры + +<a id="feedback"></a> +## Баги и Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑвÑзь +При нахождении багов Ñоздавайте **Issue**, а лучше Ñразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru) +Библиотека открыта Ð´Ð»Ñ Ð´Ð¾Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ и ваших **Pull Request**'ов! \ No newline at end of file diff --git a/libraries/microDS3231/examples/DS3231_demo/DS3231_demo.ino b/libraries/microDS3231/examples/DS3231_demo/DS3231_demo.ino new file mode 100644 index 0000000..95d51e7 --- /dev/null +++ b/libraries/microDS3231/examples/DS3231_demo/DS3231_demo.ino @@ -0,0 +1,101 @@ +// демо возможноÑтей библиотеки +#include <microDS3231.h> +MicroDS3231 rtc; + +void setup() { + Serial.begin(9600); + + // проверка Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð½Ð° линии i2c + // вызов rtc.begin() не обÑзателен Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ + if (!rtc.begin()) { + Serial.println("DS3231 not found"); + for(;;); + } + + // ======== УСТÐÐОВКРВРЕМЕÐИ ÐВТОМÐТИЧЕСКИ ======== + // rtc.setTime(COMPILE_TIME); // уÑтановить Ð²Ñ€ÐµÐ¼Ñ == времени компилÑции + + // визуально громоздкий, но более "лёгкий" Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ Ð·Ñ€ÐµÐ½Ð¸Ñ Ð¿Ð°Ð¼Ñти ÑпоÑоб уÑтановить Ð²Ñ€ÐµÐ¼Ñ ÐºÐ¾Ð¼Ð¿Ð¸Ð»Ñции + rtc.setTime(BUILD_SEC, BUILD_MIN, BUILD_HOUR, BUILD_DAY, BUILD_MONTH, BUILD_YEAR); + + if (rtc.lostPower()) { // выполнитÑÑ Ð¿Ñ€Ð¸ ÑброÑе батарейки + Serial.println("lost power!"); + // тут можно однократно уÑтановить Ð²Ñ€ÐµÐ¼Ñ == времени компилÑции + } + + // ======== УСТÐÐОВКРВРЕМЕÐИ ВРУЧÐУЮ ======== + // уÑтановить Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ можно Ð´Ð²ÑƒÐ¼Ñ ÑпоÑобами (подÑтавить реальные чиÑла) + //rtc.setTime(SEC, MIN, HOUR, DAY, MONTH, YEAR); + //rtc.setHMSDMY(HOUR, MIN, SEC, DAY, MONTH, YEAR); + + // также можно уÑтановить Ð²Ñ€ÐµÐ¼Ñ Ñ‡ÐµÑ€ÐµÐ· DateTime + /* + DateTime now; + now.second = 0; + now.minute = 10; + now.hour = 50; + now.date = 2; + now.month = 9; + now.year = 2021; + + rtc.setTime(now); // загружаем в RTC + */ +} + +void loop() { + // получение и вывод каждой компоненты + Serial.print(rtc.getHours()); + Serial.print(":"); + Serial.print(rtc.getMinutes()); + Serial.print(":"); + Serial.print(rtc.getSeconds()); + Serial.print(" "); + Serial.print(rtc.getDay()); + Serial.print(" "); + Serial.print(rtc.getDate()); + Serial.print("/"); + Serial.print(rtc.getMonth()); + Serial.print("/"); + Serial.println(rtc.getYear()); + + /* + // можно через DateTime (более оптимально): + DateTime now = rtc.getTime(); + Serial.print(now.hour); + Serial.print(":"); + Serial.print(now.minute); + Serial.print(":"); + Serial.print(now.second); + Serial.print(" "); + Serial.print(now.day); + Serial.print(" "); + Serial.print(now.date); + Serial.print("/"); + Serial.print(now.month); + Serial.print("/"); + Serial.println(now.year); + */ + + // вывод температуры чипа + Serial.println(rtc.getTemperatureFloat()); + //Serial.println(rtc.getTemperature()); + + // вывод времени готовой Ñтрокой String + Serial.println(rtc.getTimeString()); + + // вывод даты готовой Ñтрокой String + Serial.println(rtc.getDateString()); + + // вывод времени через char array + char time[9]; // буфер минимум на 9 Ñимволов (8 данные + 1 нулевой) + rtc.getTimeChar(time); + Serial.println(time); + + // вывод даты через char array + char date[11]; // буфер минимум на 11 Ñимволов (10 данные + 1 нулевой) + rtc.getDateChar(date); + Serial.println(date); + + Serial.println(); + delay(500); +} diff --git a/libraries/microDS3231/examples/DateTime/DateTime.ino b/libraries/microDS3231/examples/DateTime/DateTime.ino new file mode 100644 index 0000000..55f8c1e --- /dev/null +++ b/libraries/microDS3231/examples/DateTime/DateTime.ino @@ -0,0 +1,52 @@ +#include <microDS3231.h> +MicroDS3231 rtc; + +void setup() { + Serial.begin(9600); + + // проверка Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð½Ð° линии i2c + if (!rtc.begin()) { + Serial.println("DS3231 not found"); + for(;;); + } + + // получаем вÑе данные в Ñтруктуру + DateTime now = rtc.getTime(); + + // менÑем любой параметр + now.year += 5; + // now.second; + // now.minute; + // now.hour; + // now.day; + // now.date; + // now.month; + + // отправлÑем в rtc + rtc.setTime(now); +} + +void loop() { + printTime(); + delay(500); +} + +void printTime() { + // получаем вÑе данные в Ñтруктуру и иÑпользуем их + // Ñтот ÑпоÑоб быÑтрее и "легче" вызова отдельных get-функций + DateTime now = rtc.getTime(); + + Serial.print(now.hour); + Serial.print(":"); + Serial.print(now.minute); + Serial.print(":"); + Serial.print(now.second); + Serial.print(" "); + Serial.print(now.day); + Serial.print(" "); + Serial.print(now.date); + Serial.print("/"); + Serial.print(now.month); + Serial.print("/"); + Serial.println(now.year); +} diff --git a/libraries/microDS3231/keywords.txt b/libraries/microDS3231/keywords.txt new file mode 100644 index 0000000..299c063 --- /dev/null +++ b/libraries/microDS3231/keywords.txt @@ -0,0 +1,53 @@ + +####################################### +# Syntax Coloring Map For microDS3231 +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +microDS3231 KEYWORD1 +MicroDS3231 KEYWORD1 +DateTime KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +setTime KEYWORD2 +setHMSDMY KEYWORD2 +getTime KEYWORD2 +lostPower KEYWORD2 +getSeconds KEYWORD2 +getMinutes KEYWORD2 +getHours KEYWORD2 +getDay KEYWORD2 +getDate KEYWORD2 +getYear KEYWORD2 +getMonth KEYWORD2 +getTemperatureFloat KEYWORD2 +getTemperature KEYWORD2 +getTimeString KEYWORD2 +getDateString KEYWORD2 +getTimeChar KEYWORD2 +getDateChar KEYWORD2 + +second KEYWORD2 +minute KEYWORD2 +hour KEYWORD2 +day KEYWORD2 +date KEYWORD2 +month KEYWORD2 +year KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +COMPILE_TIME LITERAL1 +BUILD_SEC LITERAL1 +BUILD_MIN LITERAL1 +BUILD_HOUR LITERAL1 +BUILD_DAY LITERAL1 +BUILD_MONTH LITERAL1 +BUILD_YEAR LITERAL1 \ No newline at end of file diff --git a/libraries/microDS3231/library.properties b/libraries/microDS3231/library.properties new file mode 100644 index 0000000..bd028b2 --- /dev/null +++ b/libraries/microDS3231/library.properties @@ -0,0 +1,9 @@ +name=microDS3231 +version=2.6 +author=AlexGyver <alex@alexgyver.ru> +maintainer=AlexGyver <alex@alexgyver.ru> +sentence=Light library for DS3231 RTC module +paragraph=Light library for DS3231 RTC module +category=Device Control +url=https://github.com/GyverLibs/microDS3231 +architectures=* \ No newline at end of file diff --git a/libraries/microDS3231/src/buildTime.h b/libraries/microDS3231/src/buildTime.h new file mode 100644 index 0000000..9405b22 --- /dev/null +++ b/libraries/microDS3231/src/buildTime.h @@ -0,0 +1,83 @@ +/* + ПарÑинг и получение даты и времени компилÑции из __DATE__ и __TIME__ + ДокументациÑ: + GitHub: https://github.com/GyverLibs/buildTime + КонÑтанты времени компилÑции: + BUILD_YEAR - год + BUILD_MONTH - меÑÑц + BUILD_DAY - день + BUILD_HOUR - Ñ‡Ð°Ñ + BUILD_MIN - минута + BUILD_SEC - Ñекунда + + ИÑходник http://qaru.site/questions/186859/how-to-use-date-and-time-predefined-macros-in-as-two-integers-then-stringify + AlexGyver, alex@alexgyver.ru + https://alexgyver.ru/ + MIT License + + ВерÑии: + v1.0 - релиз +*/ + + +#ifndef buildTime_h +#define buildTime_h +// Example of __DATE__ string: "Jul 27 2012" +// 01234567890 + +#define BUILD_YEAR_CH0 (__DATE__[7]-'0') +#define BUILD_YEAR_CH1 (__DATE__[8]-'0') +#define BUILD_YEAR_CH2 (__DATE__[9]-'0') +#define BUILD_YEAR_CH3 (__DATE__[10]-'0') +#define BUILD_YEAR (BUILD_YEAR_CH0*1000+BUILD_YEAR_CH1*100 + BUILD_YEAR_CH2*10+BUILD_YEAR_CH3) + +#define BUILD_MONTH_IS_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n') +#define BUILD_MONTH_IS_FEB (__DATE__[0] == 'F') +#define BUILD_MONTH_IS_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r') +#define BUILD_MONTH_IS_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p') +#define BUILD_MONTH_IS_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y') +#define BUILD_MONTH_IS_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n') +#define BUILD_MONTH_IS_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l') +#define BUILD_MONTH_IS_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u') +#define BUILD_MONTH_IS_SEP (__DATE__[0] == 'S') +#define BUILD_MONTH_IS_OCT (__DATE__[0] == 'O') +#define BUILD_MONTH_IS_NOV (__DATE__[0] == 'N') +#define BUILD_MONTH_IS_DEC (__DATE__[0] == 'D') + +#define BUILD_MONTH \ + ( \ + (BUILD_MONTH_IS_JAN) ? 1 : \ + (BUILD_MONTH_IS_FEB) ? 2 : \ + (BUILD_MONTH_IS_MAR) ? 3 : \ + (BUILD_MONTH_IS_APR) ? 4 : \ + (BUILD_MONTH_IS_MAY) ? 5 : \ + (BUILD_MONTH_IS_JUN) ? 6 : \ + (BUILD_MONTH_IS_JUL) ? 7 : \ + (BUILD_MONTH_IS_AUG) ? 8 : \ + (BUILD_MONTH_IS_SEP) ? 9 : \ + (BUILD_MONTH_IS_OCT) ? 10 : \ + (BUILD_MONTH_IS_NOV) ? 11 : \ + (BUILD_MONTH_IS_DEC) ? 12 : \ + /* error default */ '?' \ + ) + +#define BUILD_DAY_CH0 (((__DATE__[4] >= '0') ? (__DATE__[4]) : '0')-'0') +#define BUILD_DAY_CH1 (__DATE__[5]-'0') +#define BUILD_DAY (BUILD_DAY_CH0*10+BUILD_DAY_CH1) + +// Example of __TIME__ string: "21:06:19" +// 01234567 + +#define BUILD_HOUR_CH0 (__TIME__[0]-'0') +#define BUILD_HOUR_CH1 (__TIME__[1]-'0') +#define BUILD_HOUR (BUILD_HOUR_CH0*10+BUILD_HOUR_CH1) + +#define BUILD_MIN_CH0 (__TIME__[3]-'0') +#define BUILD_MIN_CH1 (__TIME__[4]-'0') +#define BUILD_MIN (BUILD_MIN_CH0*10+BUILD_MIN_CH1) + +#define BUILD_SEC_CH0 (__TIME__[6]-'0') +#define BUILD_SEC_CH1 (__TIME__[7]-'0') +#define BUILD_SEC (BUILD_SEC_CH0*10+BUILD_SEC_CH1) + +#endif \ No newline at end of file diff --git a/libraries/microDS3231/src/microDS3231.cpp b/libraries/microDS3231/src/microDS3231.cpp new file mode 100644 index 0000000..cff389f --- /dev/null +++ b/libraries/microDS3231/src/microDS3231.cpp @@ -0,0 +1,229 @@ +#include "microDS3231.h" + +//static const uint8_t _ds_daysInMonth[] PROGMEM = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +static uint8_t _ds_DIM(uint8_t i) { + return (i < 7) ? ((i == 1) ? 28 : ((i & 1) ? 30 : 31)) : ((i & 1) ? 31 : 30); +} + +static uint16_t getWeekDay(uint16_t y, uint8_t m, uint8_t d) { + if (y >= 2000) + y -= 2000; + uint16_t days = d; + for (uint8_t i = 1; i < m; ++i) + //days += pgm_read_byte(_ds_daysInMonth + i - 1); + days += _ds_DIM(i - 1); + if (m > 2 && y % 4 == 0) + ++days; + return (days + 365 * y + (y + 3) / 4 + 4) % 7 + 1; +} + +// поiхали +MicroDS3231::MicroDS3231(uint8_t addr) : _addr(addr) { + Wire.begin(); +} + +bool MicroDS3231::begin(void){ + Wire.begin(); // Инит шины + Wire.beginTransmission(_addr); // Зовем DS3231 по адреÑу + return (!Wire.endTransmission()); // еÑли никто не откликнулÑÑ - возвращаем false +} + +void MicroDS3231::setTime(int8_t seconds, int8_t minutes, int8_t hours, int8_t date, int8_t month, int16_t year) { + // защиты от дурака + month = constrain(month, 1, 12); + //date = constrain(date, 0, pgm_read_byte(_ds_daysInMonth + month - 1)); + date = constrain(date, 0, _ds_DIM(month - 1)); + seconds = constrain(seconds, 0, 59); + minutes = constrain(minutes, 0, 59); + hours = constrain(hours, 0, 23); + + // отправлÑем + uint8_t day = getWeekDay(year, month, date); + year -= 2000; + Wire.beginTransmission(_addr); + Wire.write(0x00); + Wire.write(encodeRegister(seconds)); + Wire.write(encodeRegister(minutes)); + if (hours > 19) Wire.write((0x2 << 4) | (hours % 20)); + else if (hours > 9) Wire.write((0x1 << 4) | (hours % 10)); + else Wire.write(hours); + Wire.write(day); + Wire.write(encodeRegister(date)); + Wire.write(encodeRegister(month)); + Wire.write(encodeRegister(year)); + Wire.endTransmission(); +} + +void MicroDS3231::setHMSDMY(int8_t hours, int8_t minutes, int8_t seconds, int8_t date, int8_t month, int16_t year) { + setTime(seconds, minutes, hours, date, month, year); +} + +void MicroDS3231::setTime(DateTime time) { + setTime(time.second, time.minute, time.hour, time.date, time.month, time.year); +} + +static int charToDec(const char* p) { + return (10 * (*p - '0') + (*++p - '0')); +} + +void MicroDS3231::setTime(const __FlashStringHelper* stamp) { + char buff[25]; + memcpy_P(buff, stamp, 25); + + // Wed Jul 14 22:00:24 2021 + // 4 8 11 14 17 22 + // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec + int h, m, s, d, mo, y; + h = charToDec(buff + 11); + m = charToDec(buff + 14); + s = charToDec(buff + 17); + d = charToDec(buff + 8); + switch (buff[4]) { + case 'J': mo = (buff[5] == 'a') ? 1 : (mo = (buff[6] == 'n') ? 6 : 7); break; + case 'F': mo = 2; break; + case 'A': mo = (buff[6] == 'r') ? 4 : 8; break; + case 'M': mo = (buff[6] == 'r') ? 3 : 5; break; + case 'S': mo = 9; break; + case 'O': mo = 10; break; + case 'N': mo = 11; break; + case 'D': mo = 12; break; + } + y = 2000 + charToDec(buff + 22); + setTime(s, m, h, d, mo, y); +} + +DateTime MicroDS3231::getTime() { + DateTime now; + Wire.beginTransmission(_addr); + Wire.write(0x0); + if (Wire.endTransmission() != 0) return now; + Wire.requestFrom(_addr, (uint8_t)7); + now.second = unpackRegister(Wire.read()); + now.minute = unpackRegister(Wire.read()); + now.hour = unpackHours(Wire.read()); + now.day = Wire.read(); + now.date = unpackRegister(Wire.read()); + now.month = unpackRegister(Wire.read()); + now.year = unpackRegister(Wire.read()) + 2000; + return now; +} +String MicroDS3231::getTimeString() { + DateTime now = getTime(); + String str = ""; + if (now.hour < 10) str += '0'; + str += now.hour; + str += ':'; + if (now.minute < 10) str += '0'; + str += now.minute; + str += ':'; + if (now.second < 10) str += '0'; + str += now.second; + return str; +} +String MicroDS3231::getDateString() { + DateTime now = getTime(); + String str = ""; + if (now.date < 10) str += '0'; + str += now.date; + str += '.'; + if (now.month < 10) str += '0'; + str += now.month; + str += '.'; + str += now.year; + return str; +} +void MicroDS3231::getTimeChar(char* array) { + DateTime now = getTime(); + array[0] = now.hour / 10 + '0'; + array[1] = now.hour % 10 + '0'; + array[2] = ':'; + array[3] = now.minute / 10 + '0'; + array[4] = now.minute % 10 + '0'; + array[5] = ':'; + array[6] = now.second / 10 + '0'; + array[7] = now.second % 10 + '0'; + array[8] = '\0'; +} +void MicroDS3231::getDateChar(char* array) { + DateTime now = getTime(); + array[0] = now.date / 10 + '0'; + array[1] = now.date % 10 + '0'; + array[2] = '.'; + array[3] = now.month / 10 + '0'; + array[4] = now.month % 10 + '0'; + array[5] = '.'; + itoa(now.year, array + 6, DEC); + array[10] = '\0'; +} +bool MicroDS3231::lostPower(void) { // возвращает true, еÑли 1 ÑÐ½Ð²Ð°Ñ€Ñ 2000 + if (getYear() == 2000 && getMonth() == 1 && getDate() == 1) return true; + else return false; +} + +uint8_t MicroDS3231::getSeconds(void) { + return (unpackRegister(readRegister(0x00))); +} + +uint8_t MicroDS3231::getMinutes(void) { + return (unpackRegister(readRegister(0x01))); +} + +uint8_t MicroDS3231::getHours(void) { + return (unpackHours(readRegister(0x02))); +} + +uint8_t MicroDS3231::getDay(void) { + return readRegister(0x03); +} + +uint8_t MicroDS3231::getDate(void) { + return (unpackRegister(readRegister(0x04))); +} + +uint8_t MicroDS3231::getMonth(void) { + return (unpackRegister(readRegister(0x05))); +} + +uint16_t MicroDS3231::getYear(void) { + return (unpackRegister(readRegister(0x06)) + 2000); +} + +// ÑÐµÑ€Ð²Ð¸Ñ +uint8_t MicroDS3231::readRegister(uint8_t addr) { + Wire.beginTransmission(_addr); + Wire.write(addr); + if (Wire.endTransmission() != 0) return 0; + Wire.requestFrom(_addr, (uint8_t)1); + uint8_t data = Wire.read(); + return data; +} + +uint8_t MicroDS3231::unpackRegister(uint8_t data) { + return ((data >> 4) * 10 + (data & 0xF)); +} + +uint8_t MicroDS3231::encodeRegister(int8_t data) { + return (((data / 10) << 4) | (data % 10)); +} + +uint8_t MicroDS3231::unpackHours(uint8_t data) { + if (data & 0x20) return ((data & 0xF) + 20); + else if (data & 0x10) return ((data & 0xF) + 10); + else return (data & 0xF); +} + +float MicroDS3231::getTemperatureFloat(void) { + return (getTemperatureRaw() * 0.25f); +} + +int MicroDS3231::getTemperature(void) { + return (getTemperatureRaw() >> 2); +} + +int MicroDS3231::getTemperatureRaw(void) { + Wire.beginTransmission(_addr); + Wire.write(0x11); + Wire.endTransmission(); + Wire.requestFrom(_addr, (uint8_t)2); + return ((int8_t)Wire.read() << 2) + (Wire.read() >> 6); +} \ No newline at end of file diff --git a/libraries/microDS3231/src/microDS3231.h b/libraries/microDS3231/src/microDS3231.h new file mode 100644 index 0000000..b93f79c --- /dev/null +++ b/libraries/microDS3231/src/microDS3231.h @@ -0,0 +1,82 @@ +/* + Ð›Ñ‘Ð³ÐºÐ°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ° Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ RTC DS3231 Ð´Ð»Ñ Arduino + ДокументациÑ: + GitHub: https://github.com/GyverLibs/microDS3231 + ВозможноÑти: + - Чтение и запиÑÑŒ времени + - Вывод в char* и String + - Чтение температуры датчика + + Egor 'Nich1con' Zakharov & AlexGyver, alex@alexgyver.ru + https://alexgyver.ru/ + MIT License + + ВерÑии: + v1.2 - добавлены Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° вводимые в setTime чиÑла. Также Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ð²ÐµÑти 29 Ñ„ÐµÐ²Ñ€Ð°Ð»Ñ ÑƒÐ²Ñ‹ =) + v1.3 - пофикшено завиÑание, когда модуль отключен но опрашиваетÑÑ + v1.4 - незначительный Ñ„Ð¸ÐºÑ + v2.0 - новые возможноÑти, Ð¾Ð¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¸ облегчение + v2.1 - добавил вывод температуры, вывод в String и char + v2.2 - иÑправлены дни недели (пн-Ð²Ñ 1-7) + v2.3 - небольшие иÑправлениÑ, оптимизациÑ, изменён порÑдок вывода даты + v2.4 - иÑправлена уÑтановка времени компилÑции + v2.5 - добавлен begin Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð½Ð° линии + v2.6 - иÑправлены отрицательные температуры +*/ + +#ifndef microDS3231_h +#define microDS3231_h +//#include <microWire.h> // выбор между библиотеками Wire и microWire +#include <Wire.h> +#include "buildTime.h" + +#include <Arduino.h> +#define COMPILE_TIME F(__TIMESTAMP__) + +struct DateTime { + uint8_t second; + uint8_t minute; + uint8_t hour; + uint8_t day; + uint8_t date; + uint8_t month; + uint16_t year; +}; + +class MicroDS3231 { +public: + MicroDS3231(uint8_t addr = 0x68); // конÑтруктор. Можно передать Ð°Ð´Ñ€ÐµÑ + bool begin(void); // инициализациÑ, вернет true, еÑли RTC найден + void setTime(const __FlashStringHelper* stamp); // уÑтановка времени == времени компилÑции + void setTime(DateTime time); // уÑтановить из Ñтруктуры DateTime + void setTime(int8_t seconds, int8_t minutes, int8_t hours, int8_t date, int8_t month, int16_t year); // уÑтановка времени + void setHMSDMY(int8_t hours, int8_t minutes, int8_t seconds, int8_t date, int8_t month, int16_t year); // уÑтановка времени тип 2 + + DateTime getTime(void); // получить в Ñтруктуру DateTime + uint8_t getSeconds(void); // получить Ñекунды + uint8_t getMinutes(void); // получить минуты + uint8_t getHours(void); // получить чаÑÑ‹ + uint8_t getDay(void); // получить день недели + uint8_t getDate(void); // получить чиÑло + uint16_t getYear(void); // получить год + uint8_t getMonth(void); // получить меÑÑц + + String getTimeString(); // получить Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº Ñтроку вида HH:MM:SS + String getDateString(); // получить дату как Ñтроку вида DD.MM.YYYY + void getTimeChar(char* array); // получить Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº char array [8] вида HH:MM:SS + void getDateChar(char* array); // получить дату как char array [10] вида DD.MM.YYYY + + bool lostPower(void); // проверка на ÑÐ±Ñ€Ð¾Ñ Ð¿Ð¸Ñ‚Ð°Ð½Ð¸Ñ + float getTemperatureFloat(void);// получить температуру float + int getTemperature(void); // получить температуру int + +private: + uint8_t encodeRegister(int8_t data); + int getTemperatureRaw(void); + uint8_t readRegister(uint8_t addr); + uint8_t unpackRegister(uint8_t data); + uint8_t unpackHours(uint8_t data); + const uint8_t _addr; +}; + +#endif \ No newline at end of file -- GitLab