• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь RTC DS3231 by jarzebski + Node MCU v3

Vypra

Member
Пользовал библиотеку RTC DS3231 by jarzebski на Ардуине. Мне очень она нравится по причине вывода разных форматов даты и особенно удобных будильников.
Попытался использовать с Node MCU v3.
подключаем SCL - D1(GPIO5) // SDA - D2(GPIO4)
С питанием вопросов нет.
Скетч компилится, но после запуска вылетает ошибка rst cause: 2, boot mode: (1,6). Node MCU не стартует.
Опытным путем убирал часть кода в скетче и выяснил, что Node MCU не нравится строчка clock.begin(); в void setup(). Если часы не стартонуть, остальная часть скетча с разными датчиками работает. Значит трабл в этой библиотеке.
Кто пользовался этой библиотекой с Node MCU v3? Как запустить?
 

Vypra

Member
Да, от 5В. Через делитель на Node MCU для выравнивания уровня. Земля общая.
 

enjoynering

Well-known member
если не поможет попробуйте исправленный драйвер для i2c - enjoyneering/ESP8266-I2C-Driver

p.s. не очень понятно зачем на esp8266 использовать внешний rtc. можно ведь по wifi брать время с ntp сервера, а при потере сигнала использовать внутренний millis()
 

nikolz

Well-known member
если не поможет попробуйте исправленный драйвер для i2c - enjoyneering/ESP8266-I2C-Driver

p.s. не очень понятно зачем на esp8266 использовать внешний rtc. можно ведь по wifi брать время с ntp сервера, а при потере сигнала использовать внутренний millis()
полагаю есть как минимум три причины:
1) для более точной привязки по времени по сравнению с RTC ESP. По wiFi вы получите точность привязки не лучше 0.1 сек. Привязка точнее требует реализацию ФАПЧ
2) для автономной работы без доступа в интернет
3) для организации более экономичного режима sleep ESP
 

Vypra

Member
Бинго! Все 3 пункта. )))) Аппарат будет работать без доступа к интернету, но нужны будильники. WiFi нужен для RemoteXY чтоб мобильно со смарта смотреть датчики и некоторые настройки. На Ардуине памяти не хватило под все, поэтому перехожу на ESP.
Кстати, от 3,3В завелось. Странно, но с другими библиотеками и через делитель работало.
 

Vypra

Member
Еще вопрос.
RTC по идее может выводить Node MCU из режима DeepSleep. Хочеться SQW заточить на пин RST и при срабатывания будильника в RTC перезагружать Node MCU .
В даташите находил, что SQW RTC можно загнать в режим прерывания INTCN=1, он будет выдавать импульс при совпадении текущего времени и будильника. SQW пока выдает меандр. Как програмно сконфигурировать INTCN=1?
 

nikolz

Well-known member
Еще вопрос.
RTC по идее может выводить Node MCU из режима DeepSleep. Хочеться SQW заточить на пин RST и при срабатывания будильника в RTC перезагружать Node MCU .
В даташите находил, что SQW RTC можно загнать в режим прерывания INTCN=1, он будет выдавать импульс при совпадении текущего времени и будильника. SQW пока выдает меандр. Как програмно сконфигурировать INTCN=1?
Active-Low Interrupt or Square-Wave Output. This open-drain pin requires an external pullup resistor. It may be left open if not used. This multifunction pin is determined by the state of the INTCN bit in the Control Register (0Eh). When INTCN is set to logic 0, this pin outputs a square wave and its frequency is determined by RS2 and RS1 bits. When INTCN is set to logic 1, then a match between the timekeeping registers and either of the alarm registers activates the INT/SQW pin (if the alarm is enabled). Because the INTCN bit is set to logic 1 when power is first applied, the pin defaults to an interrupt output with alarms disabled.
-------------
Активно-низкий выход прерывания или прямоугольной волны.
Этот вывод с открытым стоком требует внешнего подтягивающего резистора. Он остается открытым, если не используются.
Этот многофункциональный пин определен Положением бита INTEN в регистре управления (0Eh).
Когда INTCN установлено к логике 0, этот пин выводит наружу прямоугольная волна частота определена RS2 и RS 1 бит.
Когда INTCN установлен в логику 1, то совпадение регистров хронометража с регистрами сигналов тревоги активируют вывод INT/SQW (если сигнал тревоги включен).
бит INTCN установлен в 1 по умолчанию.
 

Vypra

Member
Ага. Спасибо. Значит можно. Может я где-то протупил. Не думаю что китайский RTC как-то был изменен. Теперь нужно погуглить как организовать просыпание через SQW .
 

Vypra

Member
Друзья, теперь прошу помощи.
Перебрал много информации, но не нашел аналога реализации задуманного.
Про то, как работает RTC нашел хорошую статью здесь.
Задача - установить время будильника на RTC с NodeMCU, загнать NodeMCU в DeepSleep, разбудить NodeMCU по будильнику с RTC.
Что удалось собрать:
1. Если не задавать частоту прямоугольных импульсов на выходе SQW RTC, то по будильнику на этом выходе будет высокий сигнал. SQW нужно подтянуть к земле.
2. NodeMCU можно разбудить, подав на пин RST низкий уровень сигнала. Т.е. кратковременно соединить с землей. Во избежание выгорания RST нужно подключить через сопротивление 470 ом.

Подтвердите правильно ли я понял.
И еще, как инвертировать высокий уровень с SQW RTC по будильнику на низкий RST? Транзистор? Кто может помочь со схемой подключения?
 

nikolz

Well-known member
Друзья, теперь прошу помощи.
Перебрал много информации, но не нашел аналога реализации задуманного.
Про то, как работает RTC нашел хорошую статью здесь.
Задача - установить время будильника на RTC с NodeMCU, загнать NodeMCU в DeepSleep, разбудить NodeMCU по будильнику с RTC.
Что удалось собрать:
1. Если не задавать частоту прямоугольных импульсов на выходе SQW RTC, то по будильнику на этом выходе будет высокий сигнал. SQW нужно подтянуть к земле.
2. NodeMCU можно разбудить, подав на пин RST низкий уровень сигнала. Т.е. кратковременно соединить с землей. Во избежание выгорания RST нужно подключить через сопротивление 470 ом.

Подтвердите правильно ли я понял.
И еще, как инвертировать высокий уровень с SQW RTC по будильнику на низкий RST? Транзистор? Кто может помочь со схемой подключения?
1) выгорать ничего не будет.
2) Вы уверены, что пробуждение от DS3231 имеет смысл? Можете обосновать?
 

Vypra

Member
2) Вы уверены, что пробуждение от DS3231 имеет смысл? Можете обосновать?
Да. Мое устройство должно пробуждаться раз в 4-5 часов, отправлять данные и уходить в deepsleep. Если период больше получаса, реализация выхода из deepsleep на NodeMCU штука как по мне плохая. Нужно периодами выходить/уходить в deepsleep, и если в какой-то период совпадут звезды - отправить данные. А так - установил будильник, проснулись, поработали, уснули.
И еще, поскольку устройство будет установлено далеко, что-то внешнее в виде RTC будет перезагружать систему если NodeMCU сбойнет. Перезагрузка еще у меня будет по звонку на SIM800 на крайний случай (но это пока в планах, я не знаю как, но знаю, что можно).
 

enjoynering

Well-known member
Да. Мое устройство должно пробуждаться раз в 4-5 часов, отправлять данные и уходить в deepsleep.
а как же это?

Аппарат будет работать без доступа к интернету, но нужны будильники. WiFi нужен для RemoteXY чтоб мобильно со смарта смотреть датчики и некоторые настройки.
 

enjoynering

Well-known member
Теперь понятно. Но стало непонятно зачем отправлять. Логируй на флешку и потом по remoteXY. Неужели там больше 3мег текста наберется за 4 часа или даже за неделю?
 

nikolz

Well-known member
Теперь понятно. Но стало непонятно зачем отправлять. Логируй на флешку и потом по remoteXY. Неужели там больше 3мег текста наберется за 4 часа или даже за неделю?
Много может быть причин. В основном это бывает надо если надо как-то реагировать.
Например - сигнализатор пожара. Если все на флешку, то узнаете, когда приедут пожарники.
 

Vypra

Member
Парни, в чем суть спора? ))) Мне нужно дистанционно мониторить датчики через SIM800 (СМС, емейл) с определенной периодичностью, но когда я буду возле аппарата - заходить через RemoteXY и смотреть на том же смарте показания датчиков. Как минимум это удобно. Еще через RemoteXY настраиваются номер телефона, периодичность отправки данных, емейл адреса, явки, пароли... ))) Все написано и уже со вчера работает. Но вопрос открыт - будильник.
 

Vypra

Member
Вчера было время поиграться с будильником. Ну собственно я не ошибся. Если не заливать скетч, по умолчанию RTC генерирует меандр.
 

Vypra

Member
Я залил скетч с примера библиотеки и понаблюдал за работой.
Код:
/*
  DS3231: Real-Time Clock. Simple example
  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

*****************************************************************************
*
* Автор Перевода: Обушенков Алексей Андреевич   
* Группа в ВК https://vk.com/engineer24
* Канал на YouTube https://www.youtube.com/channel/UCih0Gcl9IEdkR8deDJCiodg
* Инженерка Engineering room
*
*****************************************************************************
* Модули в составе проекта:
*  ESP8266 - 12E WIFI RobotDyn (3.68 $) https://goo.gl/k6TRUz
*  ESP8266 - 12E WIFI GREAT WALL (3.44 $) https://goo.gl/DcqYMg
* Модуль часов реального времени:
*  DS3231 Модуль RTC (1.95 $) https://goo.gl/3jMusY
*  RTC DS3231 (часы реального времени)RobotDyn + аккумулятор (2.90 $) https://goo.gl/gGMRak
*/

// Модуль DS3231 имеет напряжения питания 3,3В и 5В
// Батарейка типа CR2032
// подключается по I2C:
// Плата ESP-12E подключаем SCL - D1(GPIO5) // SDA - D2(GPIO4)
// Плата Arduino UNO (NANO) SCL - А5 // SDA - А4

#include <Wire.h>
#include <DS3231.h>

DS3231 clock;   // Создаем экземпляр класса DS3231 с именем clock
RTCDateTime dt; // Создаем структуру (объявленна в библиотеке) типа RTCDateTime с именем dt
RTCAlarmTime Alarm1; // Создаем структуру (объявленна в библиотеке) типа RTCDateTime с именем Alarm1
volatile boolean isAlarm = false; // Переменная для хранения сработал ли будильник
boolean alarmState = false; // Переменная для состояния будильника

#define alarmLED 16 // Номер вывода D0 (ESP8266)
#define PIN_SQW 14  // Номер вывода D5 прерывание (ESP8266)

int interval = 2; // Задаем интервал (В данном случае это 2 минуты, но то же самое может быть и для часов)
int count = 0;    // Переменная которая хранит значение для будильника (в данном случае минуты)

// Функция для прерывания
void alarmFunction()
{
  Serial.println("*** Interrupt ***");
  isAlarm = true;
}

void setup()
{
// Setup LED Pin
  pinMode(alarmLED, OUTPUT);
  digitalWrite(alarmLED, HIGH); // задаем состояние светодиода
//

 
  Serial.begin(9600);
 
  // Initialize DS3231
  Serial.println("Initialize DS3231");
  clock.begin();
  clock.enableOutput(false);        // Определяем назначение вывода SQW (INT) для генерации прерываний при сработке будильников
 
  // 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);

  // Задаем будильник 1 - Каждую 0-ю секунду в каждой минуте
  // Set Alarm1 - Every 10s in each minute
  // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  //clock.setAlarm1 (0, 0, 0, 10, DS3231_MATCH_S);

  count+=interval;
  clock.setAlarm2 (0, 0, count, DS3231_MATCH_M);

  // Attach Interrput 0. In Arduino UNO connect DS3231 INT to Arduino Pin 2 (Для Arduino)
  // Прикрепляем прерывание 0. Для Arduino UNO это PIN2
  //pinMode(2, INPUT_PULLUP);
  //attachInterrupt(0, alarmFunction, FALLING);
 
  // Прикрепляем прерывание Для ESP8266 это D5 (gpio 14)
  // У ESP8266 Прерывания могут быть назначены на любые контакты кроме GPIO16.
  pinMode(PIN_SQW, INPUT_PULLUP);
  //pinMode(PIN_SQW, INPUT);
  attachInterrupt(digitalPinToInterrupt(PIN_SQW), alarmFunction, FALLING);


}

void loop()
{
  dt = clock.getDateTime(); // Считываем в структуру dt дату и время из модуля DS3231
  Alarm1 = clock.getAlarm1();
 
  // Есть еще примеры вывода времени в примере из библиотеки DS3231_dateformat
  Serial.println(clock.dateFormat("d-m-Y H:i:s - l", dt)); // Выводим время в Сериал Монитор

  if (isAlarm) // это то же самое если написать if (isAlarm == true)
  {
     
      Serial.println("Alarm: " + String(clock.dateFormat("d-m-Y H:i:s - l", Alarm1)));     // Выводим настройки будильника                               
      Serial.println();
    digitalWrite(alarmLED, alarmState); // задаем состояние светодиода
    alarmState = !alarmState; // инвертируем значение состояния
    isAlarm = false;
    clock.clearAlarm1();  //  Сбросить Аварийный сигнал с Будильника 1 RTC
    clock.clearAlarm2();  //  Сбросить Аварийный сигнал с Будильника 2 RTC
    count+=interval;
    if (count >= 60){count-=60;}
    clock.setAlarm2 (0, 0, count, DS3231_MATCH_M);
   
  }
 
  delay(1000); // Ждет секунду
}
В момент включения NodeMCU с несработавшим будильником сигнал высокий. Я напрямую соединил с RST.


Когда будильник срабатывает, сигнал становится низким и NodeMCU вырубается.


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