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

Нужна помощь RTC by Makuna

Vypra

Member
Нашел библиотеку RTC by Makuna, пишут что в ней решены проблемы с работой с ESP8266, хочется перейти на эти часы. Использовал RTC by jarzebski, но иногда подвисает все глухо, пока не передернешь питание (на часах в том числе).
Не могу разобраться в Makuna как установить часы вручную. В симплах устанавливают время компиляции RtcDateTime(__DATE__, __TIME__), а мне нужно или ручками ставить время или с NTP.
Кто работал, подскажите.
 

Vypra

Member
Еще одна проблема. Как сделать, чтоб будильник срабатывал каждый нужный мне час?
В библиотеке RTC by jarzebski это решалось так: clock.setAlarm1(0, my_Hour, 00, 00, DS3231_MATCH_H_M_S); Если я меняю my_Hour на нужное значение, в этот час 00 минут сработает будильник.

В библиотеке Makuna есть аналогичное описание:
DS3231AlarmOne alarm1(
alarmTime.Day(),
alarmTime.Hour(),
alarmTime.Minute(),
alarmTime.Second(),
DS3231AlarmOneControl_HoursMinutesSecondsMatch);
Rtc.SetAlarmOne(alarm1);

Но не пойму что вместо дня подставить? Чтоб, например, сегодня ровно в 5 часов сработал будильник:
DS3231AlarmOne alarm1(
????,
05,
00,
00,
DS3231AlarmOneControl_HoursMinutesSecondsMatch);
Rtc.SetAlarmOne(alarm1);
 

Vypra

Member
Да, я поменял. Спасибо. Но все же хочу перейти на библиотеку Makuna.
Странная штука. Когда компилирую пример из библиотеки - работает, но когда переношу все из примера в свой скетч, вылетает ошибка 'RtcDateTime' does not name a type в этом месте:

Код:
#define countof(a) (sizeof(a) / sizeof(a[0]))
void printDateTime(const RtcDateTime& dt)
{

  snprintf_P(datestring,
             countof(datestring),
             PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
             dt.Month(),
             dt.Day(),
             dt.Year(),
             dt.Hour(),
             dt.Minute(),
             dt.Second() );
}
Поиск в нете не дал результата. Много у кого такая ошибка, но решения пока не нашел.
 

Vypra

Member
Я не нашел выхода чтоб уйти от ошибки, поэтому попробовал сделать так (без отдельной функции, в основной цикл вставил):

Код:
#define countof(a) (sizeof(a) / sizeof(a[0])) 
RtcDateTime now_time = Rtc.GetDateTime();
  char datestring[20];
  snprintf_P(datestring,
             countof(datestring),
             PSTR("%02u-%02u-%04u %02u:%02u:%02u"),
             now_time.Day(),
             now_time.Month(),
             now_time.Year(),
             now_time.Hour(),
             now_time.Minute(),
             now_time.Second());
Serial.print(datestring);
Serial.println ();
Но как мне отсюда в int взять Day, Month .... ??? Это все в uint8_t. Перевести в int не получается.
 

enjoynering

Well-known member
почитайте про перечисления (enum) и (struct). вот так объявляются:
Код:
typedef struct
{
int16_t bmpAC1 = 0;
int16_t bmpAC2 = 0;
int16_t bmpAC3 = 0;
uint16_t bmpAC4 = 0;
uint16_t bmpAC5 = 0;
uint16_t bmpAC6 = 0;
int16_t bmpB1 = 0;
int16_t bmpB2 = 0;
int16_t bmpMB = 0;
int16_t bmpMC = 0;
int16_t bmpMD = 0;
}
BMP180_CAL_COEFF;
вот так наследуются:

Код:
BMP180_CAL_COEFF _calCoeff;
вот так вызываются:

Код:
_calCoeff.bmpAC1 = value;

return _calCoeff.bmpAC1;
подробности вBMP180.h и BMP180.cpp тут
 

Vypra

Member
перевод в int

Код:
int day;

day = (int)now_time.Day();
Да, все работает. В int переводит. Спасибо.
Появилась еще одна проблема. Я все компилировал на плате версии 2.5.0 beta 1. После того, как Вы посоветовали обновить драйвер i2с, я обновил плату до версии 2.5.2. И у меня перестал общаться модуль SIM800 с NodeMCU через SoftwareSerial на GPIO15 , GPIO13.
В моем устройстве датчики навешаны так:


Я откатил плату до 2.4.2 и только на ней заработало снова. Оказалось, что на платах 2.5.0 beta2, 2.5.0, 2.5.1., 2.5.2 уже не работает. Почему так - не понимаю.
Весь код огромный, поэтому выложу только часть отправки емейла. История та же. На 2.4.2 модуль отвечает при таком подключении, на версиях выше - нет.
Код:
// БИБЛИОТЕКИ
#include <SoftwareSerial.h> // GSM sim800L

// SMS sim800L
SoftwareSerial SIM800(13, 15);
String _response    = "";                                     // Переменная для хранения ответа модуля
long lastUpdate = millis();                                   // Время последнего обновления
long updatePeriod   = 60000;                                  // Проверять каждую минуту
bool hasmsg = false;                                          // Флаг наличия сообщений к удалению


void setup()
{
  //SIM800
  Serial.begin(9600);
  pinMode(15, OUTPUT);
  pinMode(13, INPUT);

  sendATCommand("AT+CFUN=1,1", true);                // перезагрузка модуля при запуске
  sendATCommand("AT", true);                         // Отправили AT для настройки скорости обмена данными
  send_Email("5", "HELLO");                          // 1 - количество символов в теле сообщения, 2 - сообщение
}


void loop()
{}


void send_Email(String num, String message)
{
  //Настройки интернет соединения
  sendATCommand("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", true);                               // задаем команду выхода в интернет
  delay (2000);
  delay (2000);
  sendATCommand("AT+SAPBR=3,1,\"APN\",\"internet\"", true);                               // настройки APN Vodafone
  delay (2000); 
  delay (2000);
  sendATCommand("AT+SAPBR=1,1", true);                                                    // To open a GPRS context. установить GPRS соединение
  delay (2000); 
  delay (2000);

  //Настройки для отправки e-mail :
  sendATCommand("AT+EMAILCID=1", true);                                                    // Установка CID параметра для email сессии.
  delay (2000);
  sendATCommand("AT+EMAILTO=30", true);                                                    // Set EMAIL timeout Установка таймаута для SMTP и POP серверов.
  delay (2000);
  sendATCommand("AT+EMAILSSL=1", true);                                                    // Set EMAIL begin encrypt transmission with encrypt port
  delay (2000);
  sendATCommand("AT+SMTPSRV=\"SMTP.GMAIL.COM\"", true);                                    // Установка адреса и порта SMTP почтового сервера.
  delay (2000);
  sendATCommand("AT+SMTPAUTH=1,\"*********@gmail.com\",\"********\"", true);               // Аутентификация (e-mail адрес, и пароль от e-mail)
  delay (2000);
  sendATCommand("AT+SMTPFROM=\"*********@gmail.com\",\"*********\"", true);              //от кого письмо (почтовый адрес, имя отправителя)
  delay (2000);
  sendATCommand("AT+SMTPSUB=\"Test\"", true);                                              //тема письма
  delay (2000);
  sendATCommand("AT+SMTPRCPT=0,0,\"**********\",\"***********\"", true);                     // кому письмо (почтовый адрес, имя получателя)
  delay (2000);
  sendATCommand("AT+SMTPBODY=\"" + num + "\"", true);                                      // задаем сколько символов в письме
  delay (2000);
  sendATCommand(message + "\r\n" + (String)((char)26), true);                              //После получение ответа от модуля DOWNLOAD. вводим текст письма длиной 19 символов.
  //Для отправки в конце сообщения отправляем символ SUB ( (char)26 или Cntrl+Z)
  sendATCommand("AT+SMTPSEND", true);                                                      // Отправка Email
  delay (2000);
  sendATCommand("AT+SAPBR=0,1", true);                                                    //  разорвать GPRS соединение
}



String sendATCommand(String cmd, bool waiting)                                             // Функция отправки комманд модулю
{
  String _resp = "";                                                                       // Переменная для хранения результата
  Serial.println(cmd);                                                                     // Дублируем команду в монитор порта
  SIM800.println(cmd);                                                                     // Отправляем команду модулю
  if (waiting) {                                                                           // Если необходимо дождаться ответа...
    _resp = waitResponse();                                                                // ... ждем, когда будет передан ответ
    // Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать
    if (_resp.startsWith(cmd)) {                                                           // Убираем из ответа дублирующуюся команду
      _resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2);
    }
    Serial.println(_resp);                                                                 // Дублируем ответ в монитор порта
  }
  return _resp;                                                                            // Возвращаем результат. Пусто, если проблема
}


String waitResponse()                                             // Функция ожидания ответа и возврата полученного результата
{
  String _resp = "";                                              // Переменная для хранения результата
  unsigned long _timeout = millis() + 10000;                      // Переменная для отслеживания таймаута (10 секунд)
  do
  { delay(0);

    if (millis() > _timeout )
    {
      Serial.println("Timeout...");
      break;
    }

    if (SIM800.available())
    { _resp = SIM800.readString();
      Serial.println(_resp);
      break;
    }
  }
  while (1) ;                               // Просто событие, которое не наступит
  return _resp;                                                                            // ... возвращаем результат. Пусто, если проблема
}
 

enjoynering

Well-known member
зачем вы используете медленный и жрущий ресурсы ногодрыг - SoftwareSerial.h? в этом и проблема arduino - один написал как умел с костылями, 1 000 000 остальных тупо скопировали и не читали документацию.

Можно ведь использовать hardware serial на GPIO15 (TX) и GPIO13 (RX) если сделаете так:

Код:
Serial.begin(9600);

//your briant code here

Serial.swap();  //GPIO15 (TX) and GPIO13 (RX)

//your briant code here

Serial.swap();  //swap back to GPIO1 (TX) and GPIO3 (RX)

//your briant code here
 

Vypra

Member
зачем вы используете медленный и жрущий ресурсы ногодрыг - SoftwareSerial.h?

Можно ведь использовать hardware serial на GPIO15 (TX) и GPIO13 (RX) если сделаете так:

Код:
Serial.begin(9600);

//your briant code here

Serial.swap();  //GPIO15 (TX) and GPIO13 (RX)

//your briant code here

Serial.swap();  //swap back to GPIO1 (TX) and GPIO3 (RX)

//your briant code here
Дело в том, что так я еще могу на компе смотреть процессы для отладки через Serial. Если я переключу RX/TX, в мониторе порта не получу сообщения. А так у меня есть и Hardware serial и SoftwareSerial. Если бы у меня не было Hardware serial сейчас, я бы не узнал, что SIM800 не отвечает.
 

Vypra

Member
Ну а все же. Что то все таки поменяли в ядре, что SoftwareSerial перестает работать. И причина однозначно в версии платы. Косяк появился с версии 2.5.0 beta 2. Ну я точно это не исправлю, так как нуб.
 

enjoynering

Well-known member
Если я переключу RX/TX, в мониторе порта не получу сообщения.
я же привел пример - пока работаем с sim800 переключаем на GPIO15 (TX) and GPIO13 (RX). как с ним закончили возвращаемся назад на GPIO1 (TX) and GPIO3 (RX) для отладки.

SoftwareSerial скорее всего не работает из-за interrupt. в новом фрейморке 2.5.0 все функции работающие по прерыванию надо объявлять так:
Код:
void ICACHE_RAM_ATTR encoderButtonISR()
подробности тут.
 

Vypra

Member
SoftwareSerial скорее всего не работает из-за interrupt. в новом фрейморке 2.5.0 все функции работающие по прерыванию надо объявлять так:
Код:
void ICACHE_RAM_ATTR encoderButtonISR()
подробности тут.
Спасибо что хотите мне помочь, но я не понял что к чему. ((( Буду выкручиваться по другому как-то.
 

CodeNameHawk

Moderator
Команда форума
После набора команд выхода в инет, диод часто не мигает. Значит команду не получил.
Накидайте в программу отладочных Serial.println и узнаете в каком месте затык.
Для начала - Зашел в Setup - вышел.
И так в каждую функцию, в той что подвисает, дополнительно после "важных" операторов.
 
Сверху Снизу