Uptime

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

Не судите строго за детский вопрос. Как лучше посчитать аптайм в формате привычным человеческому глазу? А именно чч:мм:cc.

String uptime()
{
  uint32_t seconds = millis() / 1000ul;        // полное количество секунд
  uint32_t Hour = (seconds / 3600ul);          // часы
  uint32_t Min = (seconds % 3600ul) / 60ul;    // минуты
  uint32_t Sec = (seconds % 3600ul) % 60ul;    // секунды
  uint32_t time = (Hour, Mins Sec");           // чч:мм:сс
  Serial.println(time);
  return String(time);
}

Знаю что 7 строка не верно записана. Нужно как-то в нее переменные уложить через разделитель двоеточие.

b707
Offline
Зарегистрирован: 26.05.2017

" время в одну переменную через двоеточие" - это лютый бред.

Вам всего лишь надо вывести часы, минуты и секунды на печать. Вот и выводите - сначала одно, потом другое, потом третье. И двоеточия печатайте, где надо.

SergeiL
SergeiL аватар
Offline
Зарегистрирован: 05.11.2018

Adolf_Balalaykin пишет:

Не судите строго за детский вопрос. Как лучше посчитать аптайм в формате привычным человеческому глазу? А именно чч:мм:cc.

String uptime()
{
  uint32_t seconds = millis() / 1000ul;        // полное количество секунд
  uint32_t Hour = (seconds / 3600ul);          // часы
  uint32_t Min = (seconds % 3600ul) / 60ul;    // минуты
  uint32_t Sec = (seconds % 3600ul) % 60ul;    // секунды
  uint32_t time = (Hour, Mins Sec");           // чч:мм:сс
  Serial.println(time);
  return String(time);
}

Знаю что 7 строка не верно записана. Нужно как-то в нее переменные уложить через разделитель двоеточие.

А что будет после переполнения millis(), подумали ?

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

SergeiL пишет:

А что будет после переполнения millis(), подумали ?

Ну так это аж через 50 суток.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

sprintf(buf, "%02d:%02d:%02d", H,M,S);

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

SergeiL пишет:

А что будет после переполнения millis(), подумали ?

ему даже дни не надо

SergeiL
SergeiL аватар
Offline
Зарегистрирован: 05.11.2018

DetSimen пишет:

ему даже дни не надо

Дольше суток все равно не протянет?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

SergeiL пишет:

DetSimen пишет:

ему даже дни не надо

Дольше суток все равно не протянет?

почему нет, к примеру на ESP8266 имею чуток более 440 суток...

SergeiL
SergeiL аватар
Offline
Зарегистрирован: 05.11.2018

ua6em пишет:

SergeiL пишет:

DetSimen пишет:

ему даже дни не надо

Дольше суток все равно не протянет?

почему нет, к примеру на ESP8266 имею чуток более 440 суток...

Почему нет, у самого ESP работают без проблем и совсем без перезапусков, ну очень давно.

Я про ТС:

Adolf_Balalaykin пишет:

Ну так это аж через 50 суток.

Стало интересно на сколько millis() хватает с точностью до секунды:

0xFFFFFFFF =  ( Days = 49, + hours = 17, + min = 2, + sec = 47, + msec = 295 )
 
Так что раньше, не дотянет немного до 50 суток :-)
 
 

   

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

В строке 7 используйте тип String и просто сложите всё в кучу.

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

Дед Семён, спасибо за наводку!

Решил немного усложнить задачу. Вывести не аптайм, а остаток времени до включения таймера, так удобней. (Код самого таймера приводить не буду., что бы в глазах не рябило :)). Ну и пусть умеет работать с большими интервалами времени.

String time_on = "8"  // Включить таймер через 8 часов.

 String uptime()
{
  uint32_t sec = time_on.toFloat() * 3600ul - millis() / 1000ul;  // секунды до срабатывания.
  uint16_t H = (sec / 3600ul);                          // часы
  uint16_t M = (sec % 3600ul) / 60ul;                   // минуты
  uint16_t S = (sec % 3600ul) % 60ul;                   // секунды

  char szStr[9];
  sprintf(szStr, "%02d:%02d:%02d", H, M, S);
  Serial.println(szStr); 

// Пришло время включения? Вместо циферок, выведем статус "ON"!
  if (ledState)  // если таймер включен
  {
    return "ON"; // то отправляем статус "ON"
  }
  return String(szStr);
}

Не уверен правильные ли типы данных выбрал в строках 6-8 ? Хотелось бы сократить количество вычислений, но явно не получится. Насколько sprintf прожорлив?

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

А на кой ляд у тебя time_on стрингом, если ты потом ее к числу приводишь? Да еще к вещественному... Брррр....

В 06...08 строках тип uint32_t

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

BOOM пишет:

А на кой ляд у тебя time_on стрингом, если ты потом ее к числу приводишь? Да еще к вещественному... Брррр....

В 06...08 строках тип uint32_t

Клянусь, я не любитель стрингов! )))))

b707
Offline
Зарегистрирован: 26.05.2017

BOOM пишет:

В 06...08 строках тип uint32_t

нафига? число минут и секунд заведомо не более 59-ти.

тут и байта хватит - то исть uint8

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

b707 пишет:

нафига? число минут и секунд заведомо не более 59-ти.

тут и байта хватит - то исть uint8

А и верно. Что-то я с утра не проснувшийся видимо писал... ))

b707
Offline
Зарегистрирован: 26.05.2017

Adolf_Balalaykin пишет:

Не уверен правильные ли типы данных выбрал в строках 6-8 ?

замечание по коду. В выражениях

 uint16_t H = (sec / 3600ul);                          // часы
  uint16_t M = (sec % 3600ul) / 60ul;                   // минуты
  uint16_t S = (sec % 3600ul) % 60ul;                   // секунды

спецификатор "ul" избыточен. Переменная sec сама имеет размерность ulong, а значит все вычисления и без указания "ul" будут идти в этом размере.

SergeiL
SergeiL аватар
Offline
Зарегистрирован: 05.11.2018

b707 пишет:
замечание по коду. В выражениях

 uint16_t H = (sec / 3600ul);                          // часы
  uint16_t M = (sec % 3600ul) / 60ul;                   // минуты
  uint16_t S = (sec % 3600ul) % 60ul;                   // секунды

спецификатор "ul" избыточен. Переменная sec сама имеет размерность ulong, а значит все вычисления и без указания "ul" будут идти в этом размере.

А я всегда стараюсь использовать константы со спецификатором типа, если переменные в операции отличаются от int.

Может сейчас и не нужно, но осталась привычка с давних времен.

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

b707] </p> <p>[quote=BOOM пишет:

число минут и секунд заведомо не более 59-ти.

Минут - да, а секунд может быть и 60.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Минут - да, а секунд может быть и 60.

и даже 172800 секунд, если это DHCP к примеру )))

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

Открылась новая беда. Примерно через 12 минут происходит отваливание и реконнект. Убрал секунды, оставил только часы и минуты, время через которое происходит реконнект увеличилось. В монитор порта выдает это.

E (389472) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (389472) task_wdt:  - async_tcp (CPU 1)
E (389472) task_wdt: Tasks currently running:
E (389472) task_wdt: CPU 0: IDLE0
E (389472) task_wdt: CPU 1: IDLE1
E (389472) task_wdt: Aborting.
abort() was called at PC 0x40145198 on core 0

ELF file SHA256: 0000000000000000

Backtrace: 0x40089080:0x3ffbf8d0 0x400892fd:0x3ffbf8f0 0x40145198:0x3ffbf910 0x40087721:0x3ffbf930 0x4015e203:0x3ffbc280 0x40146a93:0x3ffbc2a0 0x4008bacd:0x3ffbc2c0 0x4008a30e:0x3ffbc2e0

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
Подключаемся к WiFi........
Подключился к сети MyWifi
ESP32 IP адрес: 192.168.0.2

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018
Task watchdog got triggered.
BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Отключи собаку)) Или обнуляй во время работы.

SergeiL
SergeiL аватар
Offline
Зарегистрирован: 05.11.2018

BOOM пишет:
Отключи собаку)) Или обнуляй во время работы.

Не, не нужно ни отключать, ни обнулять. Нужно управление ядру отдавать, не зависая на долго в loop().

Зачем отключать защитный механизм.

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

SergeiL пишет:

BOOM пишет:
Отключи собаку)) Или обнуляй во время работы.

Не, не нужно ни отключать, ни обнулять. Нужно управление ядру отдавать, не зависая на долго в loop().

Зачем отключать защитный механизм.

А про loop() я и не заикался. Про управление ядром можно ссылку для самообразования? А то Гугл меня ненавидит.

SergeiL
SergeiL аватар
Offline
Зарегистрирован: 05.11.2018

Adolf_Balalaykin пишет:
А про loop() я и не заикался.

Ну тогда выкладывайте свой код целиком, чтобы  общаться предметно.

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

Выкрутился, "Task watchdog got triggered" больше не беспокоит. Ушел от стринга и оформил отдельной функцией.

void Timeleft() {
  uint32_t msec = defTime5.toFloat() * 3600000ul - millis(); // остаток
  uint16_t H = (msec / 3600000);                              // часы
  uint16_t M = (msec % 3600000) / 60000;                      // минуты
  uint16_t S = (msec % 3600000) / 1000 % 60;                  // секунды

  char buffer[9];
  sprintf(buffer, "%02d:%02d:%02d", H, M, S);
  Serial.println(buffer);
}

void loop {
Timeleft();
}

Для быстродействия есть разница?

1. Производить все расчеты в миллисекундах, а результат выводить в секундах.

2. Сразу всё конвертировать в секунды, далее производить в них расчеты.

Какой варианты более предпочтительный? 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Adolf_Balalaykin пишет:

Ушел от стринга

А это что?

uint32_t msec = defTime5.toFloat()

Или тебе принципиально нужно в string время задавать?

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

BOOM пишет:

Adolf_Balalaykin пишет:

Ушел от стринга

А это что?

uint32_t msec = defTime5.toFloat()

Или тебе принципиально нужно в string время задавать?

Правильно заметил. Касательно этого куска (если рассматривать только его), то складывается впечатление что можно было бы обойтись переменной. Но этот фрагмент должен быть включен в большой код, вот там то и будет задействован стринг в функции processor. Ему придется работать с вэб страницей, без этого никак.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Так преобразуй значение сразу после получения с веб-страницы и парсинга, зачем каждый раз то его преобразовывать?

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

Осталось результат этой функции отправить на вэб страницу.

Adolf_Balalaykin пишет:

void Timeleft() {
  uint32_t msec = defTime5.toFloat() * 3600000ul - millis(); // остаток
  uint16_t H = (msec / 3600000);                              // часы
  uint16_t M = (msec % 3600000) / 60000;                      // минуты
  uint16_t S = (msec % 3600000) / 1000 % 60;                  // секунды

  char buffer[9];
  sprintf(buffer, "%02d:%02d:%02d", H, M, S);
  Serial.println(buffer);
}

void loop {
Timeleft();
}

Думал как то так, но не сращивается.

void Timeleft() {
  uint32_t msec = defTime5.toFloat() * 3600000ul - millis(); // остаток
  uint16_t H = (msec / 3600000);                              // часы
  uint16_t M = (msec % 3600000) / 60000;                      // минуты
  uint16_t S = (msec % 3600000) / 1000 % 60;                  // секунды

  char buffer[9];
  sprintf(buffer, "%02d:%02d:%02d", H, M, S);
  Serial.println(buffer);
}

void setup() {
  server.on("/id_web", HTTP_GET, [](AsyncWebServerRequest *request)
        { request->send(200, "text/plain", *****); });

void loop() {
Timeleft();
}

Наставьте на путь истинный плиз?

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Мы ж с тобой вот тут вроде как все выяснили. Или в чем вопрос то?

Adolf_Balalaykin
Offline
Зарегистрирован: 01.02.2021

BOOM пишет:

Мы ж с тобой вот тут вроде как все выяснили. Или в чем вопрос то?

Там не проканало, если только массив через split как вы там рекомендовали, то норм. Но у меня там "мешают" в onMessage(event) разные включалки на swith case. 

function onMessage(event) {
	switch (event.data) {
		case '0': document.getElementById("state1").innerHTML = "OFF"; break
		case '1': ....
                и.т.д...

 

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Чем мешают? Собери так же как и два значения все необходимые (хоть сотню) и через сплит на странице уже раздели в массив, дальше знаешь. Получишь все что нужно.

Sirocco
Offline
Зарегистрирован: 28.09.2013

Можете посмотреть это:

https://github.com/YiannisBourkelis/Uptime-Library