Большие часы на адресных светодиодах WS2812B

Старик Похабыч

★★★★★★★
14 Авг 2019
4,324
1,319
Москва
Но лучше все равно сделать доп. проверку. Сейчас у тебя интервал идет по 1 секунде, а если сделаешь по 1 минуте ? Сколько раз за минуту будет сервер долбить ? А потом кто то с шаловливыми ручонками залезет в прошивку и поменяет значения... Забанят Россию на всех серверах времени перманентно
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
Но лучше все равно сделать доп. проверку
если делать доп. проверку, то не будет принудительного обновления при включении, сейчас при включении обновились принудительно и пошел цикл, который проверяет, прошли ли 12 часов, которые указаны в настройках, если нет, то работает как обычно, если прошли, то обновляем время и заново ждем интервала в 12 часов...
такой вариант лучше будет?
C++:
#include <ESP8266WiFi.h>
#include <EasyNTPClient.h>
#include <WiFiUdp.h>
#include <RTClib.h>
RTC_DS3231 rtc;

int UpdatePeriod = 12; //период в часах
int Period = UpdatePeriod * 3600; //вычисление секунд

const char *ssid = "";
const char *password = "";

WiFiUDP udp;
EasyNTPClient ntpClient(udp, "pool.ntp.org", (3 * 60 * 60));

void setup() {
  Serial.begin(115200);
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  Serial.println("Обновление");
  syncTime();
}

void syncTime() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  long ntpTime = ntpClient.getUnixTime();
  rtc.adjust(DateTime(ntpTime));
  Serial.println("Обновление...");

  // Выключаем WIFI после обновления
  WiFi.disconnect();
  WiFi.mode(WIFI_OFF);
  WiFi.forceSleepBegin();
  delay(1000);
}
int GetTime() {
  DateTime now = rtc.now();
  Serial.print(now.hour());   Serial.print(":"); 
  Serial.print(now.minute()); Serial.print(":"); 
  Serial.println(now.second()); 
  delay(1000);
};
void loop() {
  uint32_t newtime = millis()%1000;
  if (newtime < Period -1) {
    GetTime();
  }
  else {
    syncTime();
  }
}
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,324
1,319
Москва
На словах выглядит похоже. В коде тоже. Т.к. длительность подключения и к сети займет скорее всего больше 1 секунды, то должно сработать.

Вот это плохо:
C++:
while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
Тут , если не будет доступа к инету, будет зависон капитальный. Если 10 раз не вышло подключиться - надо выходить без обновления времени, а что делать. При этом можно сократить время до следующего обновления.

При получении даты лучше сравнить ее например с последней полученной, или еще с какой реально, но не прям сейчашной, должна быть больше скажем 2020-го года. На случай сбоя и получения даты 1970г
 
  • Лойс +1
Реакции: ASM

bort707

★★★★★★✩
21 Сен 2020
3,299
958
если делать доп. проверку, то не будет принудительного обновления при включении, сейчас при включении обновились принудительно и пошел цикл, который проверяет, прошли ли 12 часов, которые указаны в настройках, если нет, то работает как обычно, если прошли, то обновляем время и заново ждем интервала в 12 часов...
@ASM, все эти проблемы с периодами происходят от того, что вы выбрали, на мой взягляд, неудачный принцип отсчета интервалов. Логика деления миллис на период - If( millis() % period) - имхо, довольно-таки кривая. Я бы вместо этого пользовался традиционным вычитанием if ((millis() - old_millis) > period)
 
  • Лойс +1
Реакции: ASM

Старик Похабыч

★★★★★★★
14 Авг 2019
4,324
1,319
Москва
А вообще , если так жестко привязываться к вайфаю, то можно вообще без RTC обойтись.
Можно использовать модуль #
include <time.h>
После подключения вайфай периодически выравнивать часы по сетевому времени (3 это часовой пояс для МСК):
configTime(3600 * 3, 0, "pool.ntp.org");
А с периодичностью в 1 сек в монитор порта выводить:
tnow = time(nullptr);
Serial.print(String(ctime(&tnow)));

На ESP8266 работает.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,324
1,319
Москва
Тут если хотя бы раз считано время с сети, то какое то время часы будут идти, так же как RTC, по внутренним часам, если питание не пропадет. У RTC тут один плюс - встроенная батарейка, которая хранит время в случае потери питания. ESP так не сделает, для этого надо брать STM :D
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@Старик Похабыч, блин, я и хотел написать про сбой питания) поэтому и будем использовать rtc, тем более об этом просили))
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,324
1,319
Москва
Ну я написал МОЖНО, а не НУЖНО.
Можно используя define сделать разные версии, где то включать подключение к WIFI , где то отключать RTC и использовать только WIFI. а при отсутствии RTC и сигнала WIFI выдавать какое то сообщение на дисплее. Есть чем развлечься следующие пару месяцев :D
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@Старик Похабыч, не, этого пока не нужно) нам надо запустить ESP на наших часах чтобы работали) потом можно пилить различные фишечки связанные с WiFi))
if ((millis() - old_millis) > period)
не понимаю, old_millis тут откуда берется, к чему привязать?)
C++:
while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
так лучше?)
C++:
  if (WiFi.status() != WL_CONNECTED) {
    for (uint8_t i = 0; i > 10; i++) {
      delay(500);
      Serial.print(".");
    }
  }
  else {
    Serial.println("Connected!");
  }
}
 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
При получении даты лучше сравнить ее например с последней полученной, или еще с какой реально, но не прям сейчашной, должна быть больше скажем 2020-го года. На случай сбоя и получения даты 1970г
C++:
void syncTime() {
  WiFi.begin(ssid, password);
  /*
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    }*/
  if (WiFi.status() != WL_CONNECTED) {
    for (uint8_t i = 0; i > 10; i++) {
      delay(500);
      Serial.print(".");
    }
  }
  else {
    Serial.println("Connected!");
  }
    long ntpTime = ntpClient.getUnixTime();
    if (ntpTime > 1609459200){
    rtc.adjust(DateTime(ntpTime));
    Serial.println("Обновление...");
    // Выключаем WIFI после обновления
    WiFi.disconnect();
    WiFi.mode(WIFI_OFF);
    WiFi.forceSleepBegin();
    delay(1000);
  }
  else
  {
    Serial.print("Error Date");
    GetTime();
  }
}
вот)
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,324
1,319
Москва
Вот так я делаю на 10 попыток
C++:
byte trys=0;
  while (WiFi.status() != WL_CONNECTED) {
    trys++;
    delay(500);
    Serial.print(".");
    if (trys>10)
      {
      Serial.println("no connection!");
      return false;
      }
  }
 

bort707

★★★★★★✩
21 Сен 2020
3,299
958
тогда так сделаю)
C++:
 if (millis() % 1000 < Period - 1)
{GetTime();}
  else
{syncTime();}
Можете обьяснить, зачемтак делать?
это же безумно кривой код...
Вы хотя бы задумывались, как он работает?
Первая часть условия if - millis() % 1000 - означает что Период у вас не может быть длиннее секунды.
Предположим, период Period = 500
Тогда получается. что каждую миллисекунду первые 500мс вы читаете время с RTC - (зачем???)
А в вторую половину секунду - с максимально взможной частотой долбите запросами NTP сервер
Такое впечатление, что вы этот код где-то списали и не понимаете в нем ни буквы.

Вам что нужно - раз в period сделать синхронизацию времени с сервера? - так что мешает сделать это классически через миллис?
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,324
1,319
Москва
Объясню, ранее был вывод по 3 скеунды туда, 2 секунды сюда, 4 на это и 3 на то. Вот в воспоминания того вывода все и упирается. А задача да, другая
 

bort707

★★★★★★✩
21 Сен 2020
3,299
958
Объясню, ранее был вывод по 3 скеунды туда, 2 секунды сюда, 4 на это и 3 на то. Вот в воспоминания того вывода все и упирается. А задача да, другая
да. я помню, там с этими периодами тоже был откровенный г-код :) Но он хотя бы работал :) А теперь ребята "из того же материала" пытаются слепить конфетку. Так не бывает. Работу со временем надо переписать нормально
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@bort707, так напиши как надо, что тянешь то, есть замечание, напиши как надо)) я и так один пишу, не зная программирования)) такими темпами до лета будем делать))
Вопрос назревал давно перейти на ESP, но что-то на этом заглохло) вот я сел писать, помогайте))
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,324
1,319
Москва
Так ты учись! Разные задачи требуют разных методов. Можно так все сделать через хитрое очко, что люди языком будут цокать!
А как сделаешь ты, это только тебе решать
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@maksland, я местному продавцу написал, который продавал их по 250р, он очень удивился нынешней цене на Али))
@Старик Похабыч, так я же для всех делаю, а не какой-то платный заказ) вместе же проще)
готовые варианты подставляю, проверяю, подправляю...
Допиливаю, скоро бетку выложу)
 

bort707

★★★★★★✩
21 Сен 2020
3,299
958
я и так один пишу, не зная программирования
меня это и удивляет. нафига ты взялся писать, не зная программирования? :) А взялся - так изучай. иначе ничего хорошего не выйдет.
Вот этот урок Гайвера не читал? Уроки Ардуино Функции времени
Смотри внимательно раздел "Таймер на миллис", в конце даже пример есть на несколько таймеров разом

@Старик Похабыч, так я же для всех делаю, а не какой-то платный заказ) вместе же проще)
ну так и мы же тебе все время подсказываем, разве нет ? :)

Понимаешь, мы с Похабычем легко могли бы за вас все написать. Я даже сказал бы, что все что вы тут мучаете пару месяцев - любой из нас написал бы за один вечер. Но нафига??? смысл ведь не в том. чтобы часы сделать., смысл научиться чему-то новому. Научиться ты должен сам, а не мы тебе поднести на блюде
 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
смысл научиться чему-то новому
этим надо постоянно заниматься, через полгода все забудется, надо будет заново вспоминать...
В школе изучали Паскаль, у меня была пятерка)) Если сейчас сяду, то надо все заново изучать, ничего уже не помню)))
 

bort707

★★★★★★✩
21 Сен 2020
3,299
958
этим надо постоянно заниматься, через полгода все забудется, надо будет заново вспоминать...
понадобится - изучишь во второй раз . Еще раз забудешь - так и в третий.
Могу тебя порадовать на личном опыте - после третьего изучения в голове остается существенно больше, чем после первого :)))