Как перепрограммировать вывод SQW у модуля RTC ZS-042 (построен на DS3231)

sdfpro
Offline
Зарегистрирован: 09.04.2017

Всем привет. Давно у меня витала мысль сделать простейшую, автоматизированую кормушку для кота на ардуинке, сейчас повилась нужда. Простую механическую консрукцию вроде придумал, вкачестве исполнительного механизма буду крутить шаговый двигатель, выдаваться будет сух корм.

Собственно, есть модуль ZS-042, у которого есть выход SQW, на выходе там сейчас меандр (проверял осцилом и мультиметром, мультиметр просто кажет напряжение 2.2В, на осциле меандр).

Узнал что этот выход можно переключить в режим прерывания, что мне и нужно. Хочу по срабатыванию каждого из двух будильников, которые можно установить на этом модуле, с помощью прерывания, выводить ардуинку из режима экономии энергии. Собсвенно вопрос, как перепрограммировать этот выход?

 

P.S. Изначально, хотел сделать проект про красоте, максимально экономя энергию. Планировал использовать гораздо более экономный чем NE555 таймер (находил такой), и запускать ардуину допустим раз в час, попутно читая, а затем записывая из/в пзу (которая как бесплатная опция есть на модуле ZS-042) сколько раз кормушка включалась за день, чтобы избежать той ситуации когда таймер запустил ардуинку позднее чем прописанная в программе константа, сравнение которой происходило бы с показаниями RTC.

Лень и отсутсвие времени пока что победили, учитывая тот факт что пары акб 18650 принципе хватит и в режиме работы при достаточно слабой экономии, если кормушка будет работать дня 3-4.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы даташит на DS3231 читали и там непоянтно, или не читали?

Если не читали - почитайте. А если останутся вопросы, то обязательно давайте код и ссылку на именно Вашу библиотеку, а то их 100500 и очень неприятно человеку челый день что-то писать, чтобы потом выяснить, что у него бибилотека другая, потому никакие советы и не пашут.

sdfpro
Offline
Зарегистрирован: 09.04.2017

Библиотека : https://github.com/jarzebski/Arduino-DS3231

В даташите нашёл такую инфу: 

Bit 7: Enable Oscillator (EOSC). When set to logic 0, the oscillator is started. When set to logic 1, the oscillator is stopped when the DS3231 switches to VBAT. This bit is clear (logic 0) when power is first applied. When the DS3231 is powered by VCC, the oscillator is always on regardless of the status of the EOSC bit. When EOSC is disabled, all register data is static.

Bit 6: Battery-Backed Square-Wave Enable (BBSQW). When set to logic 1 with INTCN = 0 and VCC < VPF, this bit enables the square wave. When BBSQW is logic 0, the INT/SQW pin goes high impedance when VCC < VPF. This bit is disabled (logic 0) when power is first applied.

 

Кроме 6 и 7, я так понимаю 2, 1 и 0 биты нам ещё интересны.

Т.е как я понимаю, 7 бит нужно установить в 1, а 6-ой поставить в 0, а бит 2 в 1, при этом 1-ый и 2-ой биты установлены в 1, тогда при питании от батареи, когда сработают оба будильника, на SQW должен возникнуть импульс, верно?

Т.е должно быть что то в роде 10000111 ? Как через библиотеку передать эти значения?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не, Вы чего-то не того начитали.  EOSC - это внутренний осциллятор часов (идут / стоят).

Вы скажите толком чего Вам надо. Читсо по будильнику в любое время или там типа раз в минуту (чтобы время при переходе минуты обновить).

sdfpro
Offline
Зарегистрирован: 09.04.2017

Хочу что бы при срабатвании одного из двух доступных будильников, на выходе появлялся сигнал, и я этим сигналом делал прерывание по входу на ардуине. Хочу таким образом будить ардуину из режима энергосбереждения. Потом когда код выполнится (исполнительное устройство отработает), опять она должна засыпать до следующего срабатывания будильника. Из первого сообщения вроде всё и так ясно...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Тогда я вообще ничего не понимаю. Это всегда так происходит. Что по Вашему означает выражение "сработал будильник"? Зазвенел что ли? Сигнал и появляется.

Цитата из даташита:
When the RTC register values match alarm register settings, the corresponding Alarm Flag ‘A1F’ or ‘A2F’ bit is set to logic 1. If the corresponding Alarm Interrupt Enable ‘A1IE’ or ‘A2IE’ is also set to logic 1 and the INTCN bit is set to logic 1, the alarm condition will activate the INT/SQW signal.

Что у Вас не работает-то? Где код?

sdfpro
Offline
Зарегистрирован: 09.04.2017

Не работает то что на ноге SQW всегда мандр. Если отрубить питания с платы RTC т.е запустить их в режим "от батареи", то нефига на выходе SQW нету.

Будильник заведён, код взят из вышеуказанной библиотеки: https://github.com/jarzebski/Arduino-DS3231/tree/master/DS3231_alarm 

В любом случае, из того фрагмента даташита что я выше приводил, надо, как я понимаю настраивать контроллер, что бы при срабатывании будильника отдавался сигнал с этого выхода.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sdfpro пишет:
надо, как я понимаю настраивать контроллер, что бы при срабатывании будильника отдавался сигнал с этого выхода.

Разумеется, надо. Вернее надо перенастраивать, потому, что на меандр его зачем-то библиотека настроила. Я же Вас спрашивал, Вы читали даташит или нет. Читайте!

За Ваш меандр отвечает бит INTCN регистра 0Eh. Если в нём 0, то меандр, если 1, то будильник. Читайте сами.

Bit 2: Interrupt Control (INTCN). This bit controls the INT/SQW signal. When the INTCN bit is set to logic 0, a square wave is output on the INT/SQW pin. When the INTCN bit is set to logic 1, then a match between the timekeeping registers and either of the alarm registers activates the INT/SQW output (if the alarm is also enabled). The corresponding alarm flag is always set regardless of the state of the INTCN bit. The INTCN bit is set to logic 1 when power is first applied.

sdfpro
Offline
Зарегистрирован: 09.04.2017

Это я понял, выше писал об этом, вопрос в том как настройку провести? мб тогда нормальную библиотеку посоветуете под мою задачу?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Залезьте в файл .h библиотоеки. Там найдите строчки (они в конце)

void writeRegister8(uint8_t reg, uint8_t value);
uint8_t readRegister8(uint8_t reg);
 
Перенесите их обе повыше - выше строчки 
 
 private:
 
Вам нужен регистр 0Eh. В библиотеке он называется DS3231_REG_CONTROL
 
Теперь, чтобы прочитать регистр, Вам нужно в скетче вызвать readRegister8 с параметром DS3231_REG_CONTROL
 
uint8_t reg0Eh = myRTC.readRegister8(DS3231_REG_CONTROL);
 
Только вместо myRTC вставьте как там у Вас часы называются в скетче.
 
Вы получите в перемнной reg0Eh содержимое регистра. Поменяйте в нём то, что хотите (битовыми операциями)  и запишите обратно 
 
myRTC.writeRegister8(DS3231_REG_CONTROL, reg0Eh );
 
И всего делов.
 
(конечно, грамотнее добавить метод и библиотеку - если умеете, но работать будет и так)
 
 
sdfpro
Offline
Зарегистрирован: 09.04.2017

Благодарю за ответ. Не совсем понимаю один момент, как мне вывести значение reg0Eh, например в монитор порта? Мне же надо понять что там, изменить ручками и снова записать в регистр...

И ещё, поковырял тут файл cpp, по сути это же основной файл библиотеки, h  как я понимаю заголовочный (мало знаний по c++ у меня, увы), вижу фрагмент на 894 строке (и др):

void DS3231::armAlarm2(bool armed)
{
    uint8_t value;
    value = readRegister8(DS3231_REG_CONTROL);

    if (armed)
    {
        value |= 0b00000010;
    } else
    {
        value &= 0b11111101;
    }

    writeRegister8(DS3231_REG_CONTROL, value);
}

Это не то что мне нужно править, тут я так понимаю по второму будильнику...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sdfpro пишет:

как мне вывести значение reg0Eh, например в монитор порта? 

Ну, это самая обыкновенная переменная. Как Вы вообще что-то выводите? Так и её выводите. Лучше в 16-ричном виде, чтобы биты были лучше видны. 

sdfpro пишет:

Мне же надо понять что там, изменить ручками и снова записать в регистр...

Ну, посмотреть полезно, а при нормальной работе зачем Вам руками править? Программа всё должна делать.

sdfpro пишет:

Это не то что мне нужно править, тут я так понимаю по второму будильнику...

Я Вам по пунктам написал, что Вам нужно делать и в каком файле. В файл .cpp вам лезть не надо вообще. Разве что посмотреть, почитать, поразбираться.