Расскажите как настроить будильник на модуле DS3231. Планируется сделать так, чтобы arduino uno просыпался один раз в сутки, выполнял необходимые действия и опять засыпал. Про будильник информации очень мало, а самому разобраться не получается.
Будильник нужен чтобы только разбудить arduino uno, будет опрос датчика один раз в сутки и запись данных на SD-карту.
Не работал с данным модулем, только предстоит его приобрести. Прежде всего открываем данный документ - http://datasheets.maximintegrated.com/en/ds/DS3231.pdf, на мой взгляд, это исчерпывающие описание чипа. И так, данный модуль имеет возможность устанавливать до 2 будильников в день. На данные будильники можно повесить прерывание, что нам и нужно. 1. Настраиваем текущее время, нас интересуют регистры 00h - 06h. (формат BCD) 2. Настраиваем регистры тревоги 1 (Alarm), нас интересуют регистры с 07h - 0Ah. (формат BCD) 3. Настраиваем модуль, нас интересует регистр 0Eh. 1. Настройка текущего времени, примеров достаточно много, как вариант этот - http://knodit.blogspot.ru/2014/05/arduino-ds3231-i2c-wire.html (данный вариант не использует библиотек, но и их огромное кол-во). 2. Настройка, происходит почти так же, лишь с небольшим исключением, старший бит регистров 07h - 0Ah (A1M1 - A1M4) и DY/DT. Настройка сравнений тревоги с текущем временем в таблице 2, документа выше, подробное описание. Раз Вам надо включать ардуину раз в день, настройка такая A1M4 = 1, остальные 0. 3. Настраиваем модуль. Регистр 0Eh. Биты A1IE = 1 (разрешаем прерывание, при совпадении с тревогой 1), INTCN = 1 (разрешаем прерывание на ноге INT/SQW). Теперь у нас есть прерывание по совпадению таймера, теперь осталось настроить сон или дрему контролера. Вроде ни чего не упустил, модуль очень интересный. UPD. Данная библиотека - https://github.com/JChristensen/DS3232RTC, позволяет не только работать с часами, но и задавать тревоги и прерывания. Не вникая в регистры, сам не пробовал, просто пробежался по методам.
Проблема в том что я еще не научился разбираться в подобных описаниях чипов. Нашел это https://github.com/jarzebski/Arduino-DS3231 , http://www.jarzebski.pl/arduino/komponenty/zegar-czasu-rzeczywistego-rtc-ds3231.html , работают все примеры кроме DS3231_intalarm. Никак не разберусь как правильно соединить модуль с ардуиной.
Мы все когда-то начинаем (я так вечный ученик). Просто Вы хотите реализовать спящий режим, поэтому предположил, что Вы умеете работать с I2C без библиотек, поэтому описывал регистры. Отлично, Вы нашли рабочую библиотеку. Предположу, что у Вас такой модуль Питание и I2C Вы подключили, раз есть рабочие примеры. Осталось соединить SQW c 2 пином на Ардуине. И запустить пример DS3231_intalarm. UPD. Судя по примеру, прерывание будет происходить каждый 10 сек. И каждые 10 сек., в мониторе порта Вы увидите - *** INT 0 *** и 4 пин будет дергаться, но Вы его не увидите.
Модуль точно такой. В мониторе порта непрерывно пишется *** INT 0 ***, светодиод подключенный к пину 4 не загорается. Светодиод подключенный к SQW (2 pin ардуино) отрицательным концом постоянно горит, а если изменить полярность то горит тускло. Может не хватает какой-нибудь команды или ошибка в библиотеке?
Что-то не так. Такое ощущение, что работает не прерывание, а он просто генерирует частоту на выходе. Надеюсь светодиоды был подключен не на прямую, а через резистор. Сейчас на работе, ближе к вечеру постараюсь разобраться. UPD. Появилась минутка, похоже дело в примере. Ни где не задается бит INTCN. Давайте его установим, после Код (C++): clock.begin(); добавим строчку Код (C++): clock.enableOutput(false); Если другие примеры работали, в частности DS3231_alarm.ino, то все должно заработать.
Спойлер: Код примера Код (C++): /* DS3231: Real-Time Clock. Alarm simple Read more: www.jarzebski.pl/arduino/komponenty/zegar-czasu-rzeczywistego-rtc-DS3231.html GIT: https://github.com/jarzebski/Arduino-DS3231 Web: http://www.jarzebski.pl (c) 2014 by Korneliusz Jarzebski */ #include <Wire.h> #include <DS3231.h> DS3231 clock; RTCDateTime dt; boolean isAlarm = false; boolean alarmState = false; int alarmLED = 4; void alarmFunction() { Serial.println("*** INT 0 ***"); isAlarm = true; } void setup() { Serial.begin(9600); // Initialize DS3231 Serial.println("Initialize DS3231");; clock.begin(); clock.enableOutput(false); // Disarm alarms and clear alarms for this example, because alarms is battery backed. // Under normal conditions, the settings should be reset after power and restart microcontroller. clock.armAlarm1(false); clock.armAlarm2(false); clock.clearAlarm1(); clock.clearAlarm2(); // Manual (Year, Month, Day, Hour, Minute, Second) clock.setDateTime(2014, 4, 25, 0, 0, 0); // Set Alarm1 - Every 20s in each minute // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true) clock.setAlarm1(0, 0, 0, 10, DS3231_MATCH_S); // Attach Interrput 0. In Arduino UNO connect DS3231 INT to Arduino Pin 2 attachInterrupt(0, alarmFunction, FALLING); // Setup LED Pin pinMode(alarmLED, OUTPUT); } void loop() { dt = clock.getDateTime(); Serial.println(clock.dateFormat("d-m-Y H:i:s - l", dt)); if (isAlarm) { digitalWrite(alarmLED, alarmState); alarmState = !alarmState; clock.clearAlarm1(); isAlarm = false; } delay(1000); } Добавил строку Код (C++): clock.enableOutput(false); и Код (C++): isAlarm = false; в конце скетча, без нее светодиод на 4 пине постоянно мигает. А с этой строкой меняет свое состояние при каждом срабатывании будильника. Скрин монитора порта:
Отлично. Бегло ознакомившись с библиотекой, понял, что сама библиотека написана нормально. Проблема только в примерах. Вам осталось, лишь задать текущее время, для этого можно воспользоватся примером DS3231_simple. Там время устанавливается автоматически __DATE__, __TIME__. И задать интервал прерываний раз в день, к примеру Код (C++): clock.setAlarm1(0, 1, 10, 30, DS3231_MATCH_H_M_S); в 1 ночи 10 минут 30 сек., каждый день. Если нужно задать интервал относительно текущего времени, то получаем значения часов и устанавливаем setAlarm1, примерно так. Код (C++): RTCDateTime dt = clock.getDateTime(); clock.setAlarm1(0, dt.hour, dt.minute, dt.second, DS3231_MATCH_H_M_S); Возможно потребуется либо дать задержу в 1 секунду, либо отнять секунду, чтобы прерывание не сработало сразу. С таймером пожалуй все. Тут к сожалению, знаний не хватает, ни когда не требовалось спать, но в сети полно примеров.