├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── examples
├── DS3231_demo
│ └── DS3231_demo.ino
└── DateTime
│ └── DateTime.ino
├── keywords.txt
├── library.properties
└── src
├── buildTime.h
├── microDS3231.cpp
└── microDS3231.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Alex
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/microDS3231/releases/latest/download/microDS3231.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/microDS3231)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/microDS3231?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | |⚠️⚠️⚠️
**Библиотека архивирована! Используйте [GyverDS3231](https://github.com/GyverLibs/GyverDS3231) - она гораздо удобнее и имеет больше возможностей**
⚠️⚠️⚠️|
10 | | --- |
11 |
12 | # microDS3231
13 | Лёгкая библиотека для работы с RTC DS3231 для Arduino
14 | - Чтение и запись времени
15 | - Вывод в char* и String
16 | - Чтение температуры датчика
17 |
18 | ### Совместимость
19 | Совместима со всеми Arduino платформами (используются Arduino-функции)
20 |
21 | ## Содержание
22 | - [Установка](#install)
23 | - [Инициализация](#init)
24 | - [Использование](#usage)
25 | - [Пример](#example)
26 | - [Версии](#versions)
27 | - [Баги и обратная связь](#feedback)
28 |
29 |
30 | ## Установка
31 | - Библиотеку можно найти по названию **microDS3231** и установить через менеджер библиотек в:
32 | - Arduino IDE
33 | - Arduino IDE v2
34 | - PlatformIO
35 | - [Скачать библиотеку](https://github.com/GyverLibs/microDS3231/archive/refs/heads/main.zip) .zip архивом для ручной установки:
36 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
37 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
38 | - Распаковать и положить в *Документы/Arduino/libraries/*
39 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
40 | - Читай более подробную инструкцию по установке библиотек [здесь](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)
41 | ### Обновление
42 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
43 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
44 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
45 |
46 |
47 |
48 | ## Инициализация
49 | ```cpp
50 | MicroDS3231 rtc; // адрес по умолчанию 0x68
51 | MicroDS3231 rtc(адрес); // указать свой адрес
52 | ```
53 |
54 |
55 | ## Использование
56 | ```cpp
57 | bool begin(); // инициализация, вернет true, если RTC найден
58 | void setTime(uint8_t param); // установка времени == времени компиляции
59 | void setTime(DateTime time); // установить из структуры DateTime
60 | void setTime(int8_t seconds, int8_t minutes, int8_t hours, int8_t date, int8_t month, int16_t year); // установка времени
61 | void setHMSDMY(int8_t hours, int8_t minutes, int8_t seconds, int8_t date, int8_t month, int16_t year); // установка времени тип 2
62 |
63 | // структура DateTime
64 | uint8_t second;
65 | uint8_t minute;
66 | uint8_t hour;
67 | uint8_t day; // день недели (пн.. вс = 1.. 7)
68 | uint8_t date;
69 | uint8_t month;
70 | uint16_t year;
71 |
72 | DateTime getTime(); // получить в структуру DateTime
73 | uint8_t getSeconds(); // получить секунды
74 | uint8_t getMinutes(); // получить минуты
75 | uint8_t getHours(); // получить часы
76 | uint8_t getDay(); // получить день недели
77 | uint8_t getDate(); // получить число
78 | uint16_t getYear(); // получить год
79 | uint8_t getMonth(); // получить месяц
80 | uint32_t getUnix(int16_t gmt); // получить unix время (указать свой часовой пояс в часах ИЛИ минутах)
81 |
82 | String getTimeString(); // получить время как строку вида HH:MM:SS
83 | String getDateString(); // получить дату как строку вида DD.MM.YYYY
84 | void getTimeChar(char* array); // получить время как char array [8] вида HH:MM:SS
85 | void getDateChar(char* array); // получить дату как char array [10] вида DD.MM.YYYY
86 |
87 | bool lostPower(); // проверка на сброс питания
88 | float getTemperatureFloat(); // получить температуру float
89 | int getTemperature(); // получить температуру int
90 | ```
91 |
92 |
93 | ## Пример
94 | Остальные примеры смотри в **examples**!
95 | ```cpp
96 | // демо возможностей библиотеки
97 | #include
98 | MicroDS3231 rtc;
99 |
100 | void setup() {
101 | Serial.begin(9600);
102 |
103 | // проверка наличия модуля на линии i2c
104 | // вызов rtc.begin() не обязателен для работы
105 | if (!rtc.begin()) {
106 | Serial.println("DS3231 not found");
107 | for(;;);
108 | }
109 |
110 | // ======== УСТАНОВКА ВРЕМЕНИ АВТОМАТИЧЕСКИ ========
111 | // rtc.setTime(COMPILE_TIME); // установить время == времени компиляции
112 |
113 | // визуально громоздкий, но более "лёгкий" с точки зрения памяти способ установить время компиляции
114 | rtc.setTime(BUILD_SEC, BUILD_MIN, BUILD_HOUR, BUILD_DAY, BUILD_MONTH, BUILD_YEAR);
115 |
116 | if (rtc.lostPower()) { // выполнится при сбросе батарейки
117 | Serial.println("lost power!");
118 | // тут можно однократно установить время == времени компиляции
119 | }
120 |
121 | // ======== УСТАНОВКА ВРЕМЕНИ ВРУЧНУЮ ========
122 | // установить время вручную можно двумя способами (подставить реальные числа)
123 | //rtc.setTime(SEC, MIN, HOUR, DAY, MONTH, YEAR);
124 | //rtc.setHMSDMY(HOUR, MIN, SEC, DAY, MONTH, YEAR);
125 |
126 | // также можно установить время через DateTime
127 | /*
128 | DateTime now;
129 | now.second = 0;
130 | now.minute = 10;
131 | now.hour = 50;
132 | now.date = 2;
133 | now.month = 9;
134 | now.year = 2021;
135 |
136 | rtc.setTime(now); // загружаем в RTC
137 | */
138 | }
139 |
140 | void loop() {
141 | // получение и вывод каждой компоненты
142 | Serial.print(rtc.getHours());
143 | Serial.print(":");
144 | Serial.print(rtc.getMinutes());
145 | Serial.print(":");
146 | Serial.print(rtc.getSeconds());
147 | Serial.print(" ");
148 | Serial.print(rtc.getDay());
149 | Serial.print(" ");
150 | Serial.print(rtc.getDate());
151 | Serial.print("/");
152 | Serial.print(rtc.getMonth());
153 | Serial.print("/");
154 | Serial.println(rtc.getYear());
155 |
156 | /*
157 | // можно через DateTime (более оптимально):
158 | DateTime now = rtc.getTime();
159 | Serial.print(now.hour);
160 | Serial.print(":");
161 | Serial.print(now.minute);
162 | Serial.print(":");
163 | Serial.print(now.second);
164 | Serial.print(" ");
165 | Serial.print(now.day);
166 | Serial.print(" ");
167 | Serial.print(now.date);
168 | Serial.print("/");
169 | Serial.print(now.month);
170 | Serial.print("/");
171 | Serial.println(now.year);
172 | */
173 |
174 | // вывод температуры чипа
175 | Serial.println(rtc.getTemperatureFloat());
176 | //Serial.println(rtc.getTemperature());
177 |
178 | // вывод времени готовой строкой String
179 | Serial.println(rtc.getTimeString());
180 |
181 | // вывод даты готовой строкой String
182 | Serial.println(rtc.getDateString());
183 |
184 | // вывод времени через char array
185 | char time[8];
186 | rtc.getTimeChar(time);
187 | Serial.println(time);
188 |
189 | // вывод даты через char array
190 | char date[10];
191 | rtc.getDateChar(date);
192 | Serial.println(date);
193 |
194 | Serial.println();
195 | delay(500);
196 | }
197 | ```
198 |
199 |
200 | ## Версии
201 | - v1.2 - добавлены ограничения на вводимые в setTime числа. Также нельзя ввести 29 февраля увы =)
202 | - v1.3 - пофикшено зависание, когда модуль отключен но опрашивается
203 | - v1.4 - незначительный фикс
204 | - v2.0 - новые возможности, оптимизация и облегчение
205 | - v2.1 - добавил вывод температуры, вывод в String и char
206 | - v2.2 - исправлены дни недели (пн-вс 1-7)
207 | - v2.3 - небольшие исправления, оптимизация, изменён порядок вывода даты
208 | - v2.4 - исправлена установка времени компиляции
209 | - v2.5 - добавлен begin для проверки наличия модуля на линии
210 | - v2.6 - исправлены отрицательные температуры
211 | - v2.7 - добавлен вывод unix
212 |
213 |
214 | ## Баги и обратная связь
215 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
216 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
217 |
218 |
219 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
220 | - Версия библиотеки
221 | - Какой используется МК
222 | - Версия SDK (для ESP)
223 | - Версия Arduino IDE
224 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
225 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
226 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
227 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # Microds3231
4 | Light library for working with RTC DS3231 for Arduino
5 | - Reading and recording time
6 | - Conclusion in Char* and String
7 | - Reading the sensor temperature
8 |
9 | ## compatibility
10 | Compatible with all arduino platforms (used arduino functions)
11 |
12 | ## Content
13 | - [installation] (# Install)
14 | - [initialization] (#init)
15 | - [use] (#usage)
16 | - [Example] (# Example)
17 | - [versions] (#varsions)
18 | - [bugs and feedback] (#fedback)
19 |
20 |
21 | ## Installation
22 | - The library can be found by the name ** Microds3231 ** and installed through the library manager in:
23 | - Arduino ide
24 | - Arduino ide v2
25 | - Platformio
26 | - [download library] (https://github.com/gyverlibs/microds3231/archive/refs/heads/main.zip). Zip archive for manual installation:
27 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64)
28 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32)
29 | - unpack and put in *documents/arduino/libraries/ *
30 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive
31 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
32 | ### Update
33 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
34 | - through the IDE library manager: find the library how to install and click "update"
35 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors!
36 |
37 |
38 |
39 | ## initialization
40 | `` `CPP
41 | Microds3231 RTC;// default address 0x68
42 | Microds3231 RTC (address);// specify your address
43 | `` `
44 |
45 |
46 | ## Usage
47 | `` `CPP
48 | Bool Begin ();// initialization, will return True if RTC is found
49 | VOID settime (uint8_t param);// Installation of time == compilation time
50 | VOID settime (Datetime Time);// Install from the DateTime structure
51 | VOID settime (Int8_t Seconds, Int8_t Minutes, Int8_T Hours, Int8_T DATE, Int8_T MONTH, Int16_T YEAR);// Installation of time
52 | VOID sethmsdmy (int8_t hours, int8_t minates, int8_t seconds, int8_t date, int8_t month, int16_t year);// Time 2 installation 2
53 |
54 | // DateTime structure
55 | uint8_t second;
56 | uint8_t minute;
57 | Uint8_t Hour;
58 | uint8_t day;// Day of the week (Mon .. BC = 1 .. 7)
59 | uint8_t date;
60 | uint8_t months;
61 | uint16_t year;
62 |
63 | Datetime Gettime ();// Get in the DATETIME structure
64 | uint8_t getSeconds ();// Get seconds
65 | uint8_t getminutes ();// Get minutes
66 | uint8_t gethours ();// Get a clock
67 | uint8_t getday ();// Get the day of the week
68 | uint8_t getdate ();// Get the number
69 | uint16_t getyear ();// Get a year
70 | uint8_t getmonth ();// Get a month
71 | uint32_t getunix (int16_t GMT);// Get unix time (specify your hourly belt in hours or minutes)
72 |
73 | String gettimestring ();// Get the time as a line of the type hh: mm: ssCranberry
74 | String getdatestring ();// get a date as a line of the type DD.mm.yyy
75 | VOID GettimeChar (Char* Array);// Get the time as Char Array [8] species hh: mm: ss
76 | VOID getdateChar (Char* Array);// get a date as a char array [10] species dd.mm.yyyyy
77 |
78 | Bool Lostpower ();// Checking for power discharge
79 | Float gettemperaturefloat ();// get the temperature float
80 | int Gettemperature ();// get the temperature int
81 | `` `
82 |
83 |
84 | ## Example
85 | The rest of the examples look at ** Examples **!
86 | `` `CPP
87 | // Demo of the library capabilities
88 | #include
89 | Microds3231 RTC;
90 |
91 | VOID setup () {
92 | Serial.Begin (9600);
93 |
94 | // Checking the presence of a module on the line i2c
95 | // Call rtc.begin () is not obligatory for work
96 | if (rtc.begin ()) {
97 | Serial.println ("DS3231 Not Found");
98 | for (;;);
99 | }
100 |
101 | // ======== Installation of time automatically ===========
102 | // rtc.settime (compile_time);// set time == compilation time
103 |
104 | // Visually cumbersome, but more "light" from the point of view of memory of the way to set the compilation time
105 | RTC.Settime (Build_Sec, Build_min, Build_hour, Build_day, Build_Month, Build_year);
106 |
107 | if (rtc.lostpower ()) {// will be performed when dumping the battery
108 | Serial.println ("Lost Power!");
109 | // Here you can once set the time == compilation time
110 | }
111 |
112 | // ======== Establishing time manually ============
113 | // You can manually set the time in two ways (substitute real numbers)
114 | //rtc.settime(Sec, min, hor, day, month, year);
115 | //rtc.sethmsdmy(Hour, min, sec, day, month, year);
116 |
117 | // You can also set the time through Datetime
118 | /*
119 | Datetime Now;
120 | Now.Second = 0;
121 | Now.minute = 10;
122 | Now.hour = 50;
123 | Now.Date = 2;
124 | Now.month = 9;
125 | Now.year = 2021;
126 |
127 | RTC.Settime (Now);// Download to RTC
128 | */
129 | }
130 |
131 | VOID loop () {
132 | // Receiving and withdrawal of each component
133 | Serial.print (rtc.gethours ());
134 | Serial.print (":");
135 | Serial.print (rtc.getminutes ());
136 | Serial.print (":");
137 | Serial.print (rtc.getseconds ());
138 | Serial.print ("");
139 | Serial.print (rtc.getday ());
140 | Serial.print ("");
141 | Serial.print (rtc.getdate ());
142 | Serial.print ("/");
143 | Serial.print (rtc.getmonth ());
144 | Serial.print ("/");
145 | Serial.println (rtc.getyear ());
146 |
147 | /*
148 | // you can via datetime (more optimal):
149 | DateTime Now = rtc.gettime ();
150 | Serial.print (Now.hour);
151 | Serial.print (":");
152 | Serial.print (Now.minute);
153 | Serial.print (":");
154 | Serial.print (Now.Second);
155 | Serial.print ("");
156 | Serial.print (Now.day);
157 | Serial.print ("");
158 | Serial.print (Now.Date);
159 | Serial.print ("/");
160 | Serial.print (Now.month);
161 | Serial.print ("/");
162 | Serial.println (Now.year);
163 | */
164 |
165 | // Chip temperature output
166 | Serial.println (rtc.gettemperaturefloat ());
167 | //Serial.println (rtc.gettemperature ());
168 |
169 | // output of time finished string string
170 | Serial.println (rtc.gettimestring ());
171 |
172 | // Date output of the finished line string
173 | Serial.println (rtc.getdatestestring ());
174 |
175 | // Time output through Charray
176 | Char Time [8];
177 | rtc.gettimechar (Time);
178 | Serial.println (Time);
179 |
180 | // Conclusion of the date through Charray
181 | char date [10];
182 | RTC.getDateChar (Date);
183 | Serial.println (Date);
184 |
185 | Serial.println ();
186 | Delay (500);
187 | }
188 | `` `
189 |
190 |
191 | ## versions
192 | - V1.2 - Added restrictions on the numbers entered in Settime.You can’t enter on February 29, alas =)
193 | - v1.3 - freezing is fifted when the module is disconnected but interviewed
194 | - V1.4 - Minor Fix
195 | - V2.0 - new opportunities, optimization and relief
196 | - V2.1 - added temperature output, output to String and Char
197 | - V2.2- Fixed days of the week (Mon-Sun 1-7)
198 | - V2.3 - small corrections, optimization, the procedure for output of the date is changed
199 | - V2.4 - Fixed setting the compilation time
200 | - v2.5 - added begin to check the presence of a module on the line
201 | - v2.6 - negative temperatures are fixed
202 | - V2.7 - Added conclusion unix
203 |
204 |
205 | ## bugs and feedback
206 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru)
207 | The library is open for refinement and your ** pull Request ** 'ow!Cranberry
208 |
209 |
210 | When reporting about bugs or incorrect work of the library, it is necessary to indicate:
211 | - The version of the library
212 | - What is MK used
213 | - SDK version (for ESP)
214 | - version of Arduino ide
215 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code
216 | - what code has been loaded, what work was expected from it and how it works in reality
217 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code
--------------------------------------------------------------------------------
/examples/DS3231_demo/DS3231_demo.ino:
--------------------------------------------------------------------------------
1 | // демо возможностей библиотеки
2 | #include
3 | MicroDS3231 rtc;
4 |
5 | void setup() {
6 | Serial.begin(9600);
7 |
8 | // проверка наличия модуля на линии i2c
9 | // вызов rtc.begin() не обязателен для работы
10 | if (!rtc.begin()) {
11 | Serial.println("DS3231 not found");
12 | for(;;);
13 | }
14 |
15 | // ======== УСТАНОВКА ВРЕМЕНИ АВТОМАТИЧЕСКИ ========
16 | // rtc.setTime(COMPILE_TIME); // установить время == времени компиляции
17 |
18 | // визуально громоздкий, но более "лёгкий" с точки зрения памяти способ установить время компиляции
19 | rtc.setTime(BUILD_SEC, BUILD_MIN, BUILD_HOUR, BUILD_DAY, BUILD_MONTH, BUILD_YEAR);
20 |
21 | if (rtc.lostPower()) { // выполнится при сбросе батарейки
22 | Serial.println("lost power!");
23 | // тут можно однократно установить время == времени компиляции
24 | }
25 |
26 | // ======== УСТАНОВКА ВРЕМЕНИ ВРУЧНУЮ ========
27 | // установить время вручную можно двумя способами (подставить реальные числа)
28 | //rtc.setTime(SEC, MIN, HOUR, DAY, MONTH, YEAR);
29 | //rtc.setHMSDMY(HOUR, MIN, SEC, DAY, MONTH, YEAR);
30 |
31 | // также можно установить время через DateTime
32 | /*
33 | DateTime now;
34 | now.second = 0;
35 | now.minute = 10;
36 | now.hour = 50;
37 | now.date = 2;
38 | now.month = 9;
39 | now.year = 2021;
40 |
41 | rtc.setTime(now); // загружаем в RTC
42 | */
43 | }
44 |
45 | void loop() {
46 | // получение и вывод каждой компоненты
47 | Serial.print(rtc.getHours());
48 | Serial.print(":");
49 | Serial.print(rtc.getMinutes());
50 | Serial.print(":");
51 | Serial.print(rtc.getSeconds());
52 | Serial.print(" ");
53 | Serial.print(rtc.getDay());
54 | Serial.print(" ");
55 | Serial.print(rtc.getDate());
56 | Serial.print("/");
57 | Serial.print(rtc.getMonth());
58 | Serial.print("/");
59 | Serial.println(rtc.getYear());
60 |
61 | /*
62 | // можно через DateTime (более оптимально):
63 | DateTime now = rtc.getTime();
64 | Serial.print(now.hour);
65 | Serial.print(":");
66 | Serial.print(now.minute);
67 | Serial.print(":");
68 | Serial.print(now.second);
69 | Serial.print(" ");
70 | Serial.print(now.day);
71 | Serial.print(" ");
72 | Serial.print(now.date);
73 | Serial.print("/");
74 | Serial.print(now.month);
75 | Serial.print("/");
76 | Serial.println(now.year);
77 | */
78 |
79 | // вывод температуры чипа
80 | Serial.println(rtc.getTemperatureFloat());
81 | //Serial.println(rtc.getTemperature());
82 |
83 | // вывод времени готовой строкой String
84 | Serial.println(rtc.getTimeString());
85 |
86 | // вывод даты готовой строкой String
87 | Serial.println(rtc.getDateString());
88 |
89 | // вывод времени через char array
90 | char time[9]; // буфер минимум на 9 символов (8 данные + 1 нулевой)
91 | rtc.getTimeChar(time);
92 | Serial.println(time);
93 |
94 | // вывод даты через char array
95 | char date[11]; // буфер минимум на 11 символов (10 данные + 1 нулевой)
96 | rtc.getDateChar(date);
97 | Serial.println(date);
98 |
99 | Serial.println();
100 | delay(500);
101 | }
102 |
--------------------------------------------------------------------------------
/examples/DateTime/DateTime.ino:
--------------------------------------------------------------------------------
1 | #include
2 | MicroDS3231 rtc;
3 |
4 | void setup() {
5 | Serial.begin(9600);
6 |
7 | // проверка наличия модуля на линии i2c
8 | if (!rtc.begin()) {
9 | Serial.println("DS3231 not found");
10 | for(;;);
11 | }
12 |
13 | // получаем все данные в структуру
14 | DateTime now = rtc.getTime();
15 |
16 | // меняем любой параметр
17 | now.year += 5;
18 | // now.second;
19 | // now.minute;
20 | // now.hour;
21 | // now.day;
22 | // now.date;
23 | // now.month;
24 |
25 | // отправляем в rtc
26 | rtc.setTime(now);
27 | }
28 |
29 | void loop() {
30 | printTime();
31 | delay(500);
32 | }
33 |
34 | void printTime() {
35 | // получаем все данные в структуру и используем их
36 | // этот способ быстрее и "легче" вызова отдельных get-функций
37 | DateTime now = rtc.getTime();
38 |
39 | Serial.print(now.hour);
40 | Serial.print(":");
41 | Serial.print(now.minute);
42 | Serial.print(":");
43 | Serial.print(now.second);
44 | Serial.print(" ");
45 | Serial.print(now.day);
46 | Serial.print(" ");
47 | Serial.print(now.date);
48 | Serial.print("/");
49 | Serial.print(now.month);
50 | Serial.print("/");
51 | Serial.println(now.year);
52 | }
53 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 |
2 | #######################################
3 | # Syntax Coloring Map For microDS3231
4 | #######################################
5 |
6 | #######################################
7 | # Datatypes (KEYWORD1)
8 | #######################################
9 |
10 | microDS3231 KEYWORD1
11 | MicroDS3231 KEYWORD1
12 | DateTime KEYWORD1
13 |
14 | #######################################
15 | # Methods and Functions (KEYWORD2)
16 | #######################################
17 | begin KEYWORD2
18 | setTime KEYWORD2
19 | setHMSDMY KEYWORD2
20 | getTime KEYWORD2
21 | lostPower KEYWORD2
22 | getSeconds KEYWORD2
23 | getMinutes KEYWORD2
24 | getHours KEYWORD2
25 | getDay KEYWORD2
26 | getDate KEYWORD2
27 | getYear KEYWORD2
28 | getMonth KEYWORD2
29 | getTemperatureFloat KEYWORD2
30 | getTemperature KEYWORD2
31 | getTimeString KEYWORD2
32 | getDateString KEYWORD2
33 | getTimeChar KEYWORD2
34 | getDateChar KEYWORD2
35 | getUnix KEYWORD2
36 |
37 | second KEYWORD2
38 | minute KEYWORD2
39 | hour KEYWORD2
40 | day KEYWORD2
41 | date KEYWORD2
42 | month KEYWORD2
43 | year KEYWORD2
44 |
45 | #######################################
46 | # Constants (LITERAL1)
47 | #######################################
48 | COMPILE_TIME LITERAL1
49 | BUILD_SEC LITERAL1
50 | BUILD_MIN LITERAL1
51 | BUILD_HOUR LITERAL1
52 | BUILD_DAY LITERAL1
53 | BUILD_MONTH LITERAL1
54 | BUILD_YEAR LITERAL1
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=microDS3231
2 | version=2.7
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Light library for DS3231 RTC module
6 | paragraph=Light library for DS3231 RTC module
7 | category=Device Control
8 | url=https://github.com/GyverLibs/microDS3231
9 | architectures=*
--------------------------------------------------------------------------------
/src/buildTime.h:
--------------------------------------------------------------------------------
1 | /*
2 | Парсинг и получение даты и времени компиляции из __DATE__ и __TIME__
3 | Документация:
4 | GitHub: https://github.com/GyverLibs/buildTime
5 | Константы времени компиляции:
6 | BUILD_YEAR - год
7 | BUILD_MONTH - месяц
8 | BUILD_DAY - день
9 | BUILD_HOUR - час
10 | BUILD_MIN - минута
11 | BUILD_SEC - секунда
12 |
13 | Исходник http://qaru.site/questions/186859/how-to-use-date-and-time-predefined-macros-in-as-two-integers-then-stringify
14 | AlexGyver, alex@alexgyver.ru
15 | https://alexgyver.ru/
16 | MIT License
17 |
18 | Версии:
19 | v1.0 - релиз
20 | */
21 |
22 |
23 | #ifndef buildTime_h
24 | #define buildTime_h
25 | // Example of __DATE__ string: "Jul 27 2012"
26 | // 01234567890
27 |
28 | #define BUILD_YEAR_CH0 (__DATE__[7]-'0')
29 | #define BUILD_YEAR_CH1 (__DATE__[8]-'0')
30 | #define BUILD_YEAR_CH2 (__DATE__[9]-'0')
31 | #define BUILD_YEAR_CH3 (__DATE__[10]-'0')
32 | #define BUILD_YEAR (BUILD_YEAR_CH0*1000+BUILD_YEAR_CH1*100 + BUILD_YEAR_CH2*10+BUILD_YEAR_CH3)
33 |
34 | #define BUILD_MONTH_IS_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n')
35 | #define BUILD_MONTH_IS_FEB (__DATE__[0] == 'F')
36 | #define BUILD_MONTH_IS_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r')
37 | #define BUILD_MONTH_IS_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p')
38 | #define BUILD_MONTH_IS_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y')
39 | #define BUILD_MONTH_IS_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n')
40 | #define BUILD_MONTH_IS_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l')
41 | #define BUILD_MONTH_IS_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u')
42 | #define BUILD_MONTH_IS_SEP (__DATE__[0] == 'S')
43 | #define BUILD_MONTH_IS_OCT (__DATE__[0] == 'O')
44 | #define BUILD_MONTH_IS_NOV (__DATE__[0] == 'N')
45 | #define BUILD_MONTH_IS_DEC (__DATE__[0] == 'D')
46 |
47 | #define BUILD_MONTH \
48 | ( \
49 | (BUILD_MONTH_IS_JAN) ? 1 : \
50 | (BUILD_MONTH_IS_FEB) ? 2 : \
51 | (BUILD_MONTH_IS_MAR) ? 3 : \
52 | (BUILD_MONTH_IS_APR) ? 4 : \
53 | (BUILD_MONTH_IS_MAY) ? 5 : \
54 | (BUILD_MONTH_IS_JUN) ? 6 : \
55 | (BUILD_MONTH_IS_JUL) ? 7 : \
56 | (BUILD_MONTH_IS_AUG) ? 8 : \
57 | (BUILD_MONTH_IS_SEP) ? 9 : \
58 | (BUILD_MONTH_IS_OCT) ? 10 : \
59 | (BUILD_MONTH_IS_NOV) ? 11 : \
60 | (BUILD_MONTH_IS_DEC) ? 12 : \
61 | /* error default */ '?' \
62 | )
63 |
64 | #define BUILD_DAY_CH0 (((__DATE__[4] >= '0') ? (__DATE__[4]) : '0')-'0')
65 | #define BUILD_DAY_CH1 (__DATE__[5]-'0')
66 | #define BUILD_DAY (BUILD_DAY_CH0*10+BUILD_DAY_CH1)
67 |
68 | // Example of __TIME__ string: "21:06:19"
69 | // 01234567
70 |
71 | #define BUILD_HOUR_CH0 (__TIME__[0]-'0')
72 | #define BUILD_HOUR_CH1 (__TIME__[1]-'0')
73 | #define BUILD_HOUR (BUILD_HOUR_CH0*10+BUILD_HOUR_CH1)
74 |
75 | #define BUILD_MIN_CH0 (__TIME__[3]-'0')
76 | #define BUILD_MIN_CH1 (__TIME__[4]-'0')
77 | #define BUILD_MIN (BUILD_MIN_CH0*10+BUILD_MIN_CH1)
78 |
79 | #define BUILD_SEC_CH0 (__TIME__[6]-'0')
80 | #define BUILD_SEC_CH1 (__TIME__[7]-'0')
81 | #define BUILD_SEC (BUILD_SEC_CH0*10+BUILD_SEC_CH1)
82 |
83 | #endif
--------------------------------------------------------------------------------
/src/microDS3231.cpp:
--------------------------------------------------------------------------------
1 | #include "microDS3231.h"
2 |
3 | //static const uint8_t _ds_daysInMonth[] PROGMEM = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
4 | static uint8_t DS_dim(uint8_t i) {
5 | return (i < 7) ? ((i == 1) ? 28 : ((i & 1) ? 30 : 31)) : ((i & 1) ? 31 : 30);
6 | }
7 |
8 | static uint16_t getWeekDay(uint16_t y, uint8_t m, uint8_t d) {
9 | if (y >= 2000)
10 | y -= 2000;
11 | uint16_t days = d;
12 | for (uint8_t i = 1; i < m; ++i)
13 | //days += pgm_read_byte(_ds_daysInMonth + i - 1);
14 | days += DS_dim(i - 1);
15 | if (m > 2 && y % 4 == 0) days++;
16 | return (days + 365 * y + (y + 3) / 4 + 4) % 7 + 1;
17 | }
18 |
19 | // поiхали
20 | MicroDS3231::MicroDS3231(uint8_t addr) : _addr(addr) {
21 | Wire.begin();
22 | }
23 |
24 | bool MicroDS3231::begin(void){
25 | Wire.begin(); // Инит шины
26 | Wire.beginTransmission(_addr); // Зовем DS3231 по адресу
27 | return (!Wire.endTransmission()); // если никто не откликнулся - возвращаем false
28 | }
29 |
30 | void MicroDS3231::setTime(int8_t seconds, int8_t minutes, int8_t hours, int8_t date, int8_t month, int16_t year) {
31 | // защиты от дурака
32 | month = constrain(month, 1, 12);
33 | //date = constrain(date, 0, pgm_read_byte(_ds_daysInMonth + month - 1));
34 | date = constrain(date, 0, DS_dim(month - 1));
35 | seconds = constrain(seconds, 0, 59);
36 | minutes = constrain(minutes, 0, 59);
37 | hours = constrain(hours, 0, 23);
38 |
39 | // отправляем
40 | uint8_t day = getWeekDay(year, month, date);
41 | year -= 2000;
42 | Wire.beginTransmission(_addr);
43 | Wire.write(0x00);
44 | Wire.write(encodeRegister(seconds));
45 | Wire.write(encodeRegister(minutes));
46 | if (hours > 19) Wire.write((0x2 << 4) | (hours % 20));
47 | else if (hours > 9) Wire.write((0x1 << 4) | (hours % 10));
48 | else Wire.write(hours);
49 | Wire.write(day);
50 | Wire.write(encodeRegister(date));
51 | Wire.write(encodeRegister(month));
52 | Wire.write(encodeRegister(year));
53 | Wire.endTransmission();
54 | }
55 |
56 | void MicroDS3231::setHMSDMY(int8_t hours, int8_t minutes, int8_t seconds, int8_t date, int8_t month, int16_t year) {
57 | setTime(seconds, minutes, hours, date, month, year);
58 | }
59 |
60 | void MicroDS3231::setTime(DateTime time) {
61 | setTime(time.second, time.minute, time.hour, time.date, time.month, time.year);
62 | }
63 |
64 | static int charToDec(const char* p) {
65 | return ((*p - '0') * 10 + (*(p + 1) - '0'));
66 | }
67 |
68 | void MicroDS3231::setTime(const __FlashStringHelper* stamp) {
69 | // Wed Jul 14 22:00:24 2021
70 | // 4 8 11 14 17 22
71 | // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
72 | char buff[25];
73 | memcpy_P(buff, stamp, 25);
74 | int h, m, s, d, mo, y;
75 | h = charToDec(buff + 11);
76 | m = charToDec(buff + 14);
77 | s = charToDec(buff + 17);
78 | d = charToDec(buff + 8);
79 | switch (buff[4]) {
80 | case 'J': mo = (buff[5] == 'a') ? 1 : ((buff[6] == 'n') ? 6 : 7); break;
81 | case 'F': mo = 2; break;
82 | case 'A': mo = (buff[6] == 'r') ? 4 : 8; break;
83 | case 'M': mo = (buff[6] == 'r') ? 3 : 5; break;
84 | case 'S': mo = 9; break;
85 | case 'O': mo = 10; break;
86 | case 'N': mo = 11; break;
87 | case 'D': mo = 12; break;
88 | }
89 | y = 2000 + charToDec(buff + 22);
90 | setTime(s, m, h, d, mo, y);
91 | }
92 |
93 | DateTime MicroDS3231::getTime() {
94 | DateTime now;
95 | Wire.beginTransmission(_addr);
96 | Wire.write(0x0);
97 | if (Wire.endTransmission() != 0) return now;
98 | Wire.requestFrom(_addr, (uint8_t)7);
99 | now.second = unpackRegister(Wire.read());
100 | now.minute = unpackRegister(Wire.read());
101 | now.hour = unpackHours(Wire.read());
102 | now.day = Wire.read();
103 | now.date = unpackRegister(Wire.read());
104 | now.month = unpackRegister(Wire.read());
105 | now.year = unpackRegister(Wire.read()) + 2000;
106 | return now;
107 | }
108 |
109 | uint32_t MicroDS3231::getUnix(int16_t gmt) {
110 | DateTime now = getTime();
111 | if (abs(gmt) <= 12) gmt *= 60;
112 | int8_t my = (now.month >= 3) ? 1 : 0;
113 | uint16_t y = now.year + my - 1970;
114 | uint16_t dm = 0;
115 | for (int i = 0; i < now.month - 1; i++) dm += DS_dim(i);
116 | return (((now.date-1+dm+((y+1)/4)-((y+69)/100)+((y+369)/100/4)+365*(y-my))*24ul+now.hour)*60ul+now.minute-gmt)*60ul+now.second;
117 | }
118 |
119 | String MicroDS3231::getTimeString() {
120 | DateTime now = getTime();
121 | String str; // HH:MM:SS
122 | str.reserve(8);
123 | if (now.hour < 10) str += '0';
124 | str += now.hour;
125 | str += ':';
126 | if (now.minute < 10) str += '0';
127 | str += now.minute;
128 | str += ':';
129 | if (now.second < 10) str += '0';
130 | str += now.second;
131 | return str;
132 | }
133 | String MicroDS3231::getDateString() {
134 | DateTime now = getTime();
135 | String str; // DD.MM.YYYY
136 | str.reserve(10);
137 | if (now.date < 10) str += '0';
138 | str += now.date;
139 | str += '.';
140 | if (now.month < 10) str += '0';
141 | str += now.month;
142 | str += '.';
143 | str += now.year;
144 | return str;
145 | }
146 | void MicroDS3231::getTimeChar(char* array) {
147 | DateTime now = getTime();
148 | array[0] = now.hour / 10 + '0';
149 | array[1] = now.hour % 10 + '0';
150 | array[2] = ':';
151 | array[3] = now.minute / 10 + '0';
152 | array[4] = now.minute % 10 + '0';
153 | array[5] = ':';
154 | array[6] = now.second / 10 + '0';
155 | array[7] = now.second % 10 + '0';
156 | array[8] = '\0';
157 | }
158 | void MicroDS3231::getDateChar(char* array) {
159 | DateTime now = getTime();
160 | array[0] = now.date / 10 + '0';
161 | array[1] = now.date % 10 + '0';
162 | array[2] = '.';
163 | array[3] = now.month / 10 + '0';
164 | array[4] = now.month % 10 + '0';
165 | array[5] = '.';
166 | itoa(now.year, array + 6, DEC);
167 | array[10] = '\0';
168 | }
169 | bool MicroDS3231::lostPower(void) { // возвращает true, если 1 января 2000
170 | return (getYear() == 2000 && getMonth() == 1 && getDate() == 1);
171 | }
172 |
173 | uint8_t MicroDS3231::getSeconds(void) {
174 | return (unpackRegister(readRegister(0x00)));
175 | }
176 |
177 | uint8_t MicroDS3231::getMinutes(void) {
178 | return (unpackRegister(readRegister(0x01)));
179 | }
180 |
181 | uint8_t MicroDS3231::getHours(void) {
182 | return (unpackHours(readRegister(0x02)));
183 | }
184 |
185 | uint8_t MicroDS3231::getDay(void) {
186 | return readRegister(0x03);
187 | }
188 |
189 | uint8_t MicroDS3231::getDate(void) {
190 | return (unpackRegister(readRegister(0x04)));
191 | }
192 |
193 | uint8_t MicroDS3231::getMonth(void) {
194 | return (unpackRegister(readRegister(0x05)));
195 | }
196 |
197 | uint16_t MicroDS3231::getYear(void) {
198 | return (unpackRegister(readRegister(0x06)) + 2000);
199 | }
200 |
201 | // сервис
202 | uint8_t MicroDS3231::readRegister(uint8_t addr) {
203 | Wire.beginTransmission(_addr);
204 | Wire.write(addr);
205 | if (Wire.endTransmission() != 0) return 0;
206 | Wire.requestFrom(_addr, (uint8_t)1);
207 | return Wire.read();
208 | }
209 |
210 | uint8_t MicroDS3231::unpackRegister(uint8_t data) {
211 | return ((data >> 4) * 10 + (data & 0xF));
212 | }
213 |
214 | uint8_t MicroDS3231::encodeRegister(int8_t data) {
215 | return (((data / 10) << 4) | (data % 10));
216 | }
217 |
218 | uint8_t MicroDS3231::unpackHours(uint8_t data) {
219 | if (data & 0x20) return ((data & 0xF) + 20);
220 | else if (data & 0x10) return ((data & 0xF) + 10);
221 | else return (data & 0xF);
222 | }
223 |
224 | float MicroDS3231::getTemperatureFloat(void) {
225 | return (getTemperatureRaw() * 0.25f);
226 | }
227 |
228 | int MicroDS3231::getTemperature(void) {
229 | return (getTemperatureRaw() >> 2);
230 | }
231 |
232 | int MicroDS3231::getTemperatureRaw(void) {
233 | Wire.beginTransmission(_addr);
234 | Wire.write(0x11);
235 | Wire.endTransmission();
236 | Wire.requestFrom(_addr, (uint8_t)2);
237 | return ((int8_t)Wire.read() << 2) + (Wire.read() >> 6);
238 | }
--------------------------------------------------------------------------------
/src/microDS3231.h:
--------------------------------------------------------------------------------
1 | /*
2 | Лёгкая библиотека для работы с RTC DS3231 для Arduino
3 | Документация:
4 | GitHub: https://github.com/GyverLibs/microDS3231
5 | Возможности:
6 | - Чтение и запись времени
7 | - Вывод в char* и String
8 | - Чтение температуры датчика
9 |
10 | Egor 'Nich1con' Zakharov & AlexGyver, alex@alexgyver.ru
11 | https://alexgyver.ru/
12 | MIT License
13 |
14 | Версии:
15 | v1.2 - добавлены ограничения на вводимые в setTime числа. Также нельзя ввести 29 февраля увы =)
16 | v1.3 - пофикшено зависание, когда модуль отключен но опрашивается
17 | v1.4 - незначительный фикс
18 | v2.0 - новые возможности, оптимизация и облегчение
19 | v2.1 - добавил вывод температуры, вывод в String и char
20 | v2.2 - исправлены дни недели (пн-вс 1-7)
21 | v2.3 - небольшие исправления, оптимизация, изменён порядок вывода даты
22 | v2.4 - исправлена установка времени компиляции
23 | v2.5 - добавлен begin для проверки наличия модуля на линии
24 | v2.6 - исправлены отрицательные температуры
25 | v2.7 - добавлен вывод unix
26 | */
27 |
28 | #ifndef microDS3231_h
29 | #define microDS3231_h
30 | //#include // выбор между библиотеками Wire и microWire
31 | #include
32 | #include "buildTime.h"
33 |
34 | #include
35 | #define COMPILE_TIME F(__TIMESTAMP__)
36 |
37 | struct DateTime {
38 | uint8_t second;
39 | uint8_t minute;
40 | uint8_t hour;
41 | uint8_t day;
42 | uint8_t date;
43 | uint8_t month;
44 | uint16_t year;
45 | };
46 |
47 | class MicroDS3231 {
48 | public:
49 | MicroDS3231(uint8_t addr = 0x68); // конструктор. Можно передать адрес
50 | bool begin(); // инициализация, вернет true, если RTC найден
51 | void setTime(const __FlashStringHelper* stamp); // установка времени == времени компиляции
52 | void setTime(DateTime time); // установить из структуры DateTime
53 | void setTime(int8_t seconds, int8_t minutes, int8_t hours, int8_t date, int8_t month, int16_t year); // установка времени
54 | void setHMSDMY(int8_t hours, int8_t minutes, int8_t seconds, int8_t date, int8_t month, int16_t year); // установка времени тип 2
55 |
56 | DateTime getTime(); // получить в структуру DateTime
57 | uint8_t getSeconds(); // получить секунды
58 | uint8_t getMinutes(); // получить минуты
59 | uint8_t getHours(); // получить часы
60 | uint8_t getDay(); // получить день недели
61 | uint8_t getDate(); // получить число
62 | uint16_t getYear(); // получить год
63 | uint8_t getMonth(); // получить месяц
64 |
65 | uint32_t getUnix(int16_t gmt); // получить unix время (указать свой часовой пояс в часах ИЛИ минутах)
66 |
67 | String getTimeString(); // получить время как строку вида HH:MM:SS
68 | String getDateString(); // получить дату как строку вида DD.MM.YYYY
69 | void getTimeChar(char* array); // получить время как char array [8] вида HH:MM:SS
70 | void getDateChar(char* array); // получить дату как char array [10] вида DD.MM.YYYY
71 |
72 | bool lostPower(); // проверка на сброс питания
73 | int getTemperature(); // получить температуру int
74 | float getTemperatureFloat(); // получить температуру float
75 |
76 | private:
77 | uint8_t encodeRegister(int8_t data);
78 | int getTemperatureRaw();
79 | uint8_t readRegister(uint8_t addr);
80 | uint8_t unpackRegister(uint8_t data);
81 | uint8_t unpackHours(uint8_t data);
82 | const uint8_t _addr;
83 | };
84 |
85 | #endif
--------------------------------------------------------------------------------