ESP, IoT [BigClock] Большие часы на WS2812, ESP8266, Народный мониторинг

Какой вариант датчика используется у вас? Интересно, использует ли кто BME280, как у меня?)

  • BMP280

    Голосов: 26 26.8%
  • BME280

    Голосов: 71 73.2%

  • Всего проголосовало
    97

kym13

★★★✩✩✩✩
14 Ноя 2020
716
118
ASM )) Скетч проверил всё работает. Отлично часы идут секунда в секунду со временем компа. С помощью этого скетча можно устанавливать время в новых модулях 3231,1307 и т.д. Есть ещё пожелание как бы уменьшить частоту вывода показаний? Очень часто выводятся данные, прям мельтешат. Это же в первую очередь часы. Например 40 сек часы оставшиеся 20 сек на температуру, влажность и т. д. по 4 сек. или сделать чтобы можно было программно выставить вывод данных раз в минуту, в две, три...десять. по типу смены цвета. Датчик освещения работает адекватно.
 

ASM

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

@Старик Похабыч, у нас был разговор, как реализовать моргание в 500мс, а не по 1с.
Но так и не решили, ушли в другую тему, как грамотнее сделать?
Есть мысля запустить мигание в loop, а уже в функциях с датчиками они и так глушатся принудительно)
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
а как сейчас реализовано ?
C++:
  if (Dot == 0) Dots = false; else Dots = true;
  if (Dots) { // показ точек
    for (uint8_t i = 0; i < DOTS_NUM; i++) {
      leds[(LEDS_IN_SEGMENT * 14) + i] = ledColor;
    }
  }
  else {
    Dots_off(); // выключение точек
  }
void Dots_off()  { // отключаем точки принудительно, где не нужны
  for (uint8_t i = 0; i < DOTS_NUM; i++) {
    leds[(LEDS_IN_SEGMENT * 14) + i] = 0x000000;
  }
}
там где не нужны
Dots_off();
 

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

★★★★★★★
14 Авг 2019
4,323
1,319
Москва
Тогда можно реально поменять:
C++:
if (Dot == 0) Dots = false; else Dots = true;
if (Dots) { // показ точек
на
C++:
//if (Dot == 0) Dots = false; else Dots = true;
 if (!Dot) { // показ точек
Покажи место где Dor вычисляектся
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@Старик Похабыч,
C++:
int GetTime() {
  DateTime now = rtc.now();
  int hour = now.hour();
  int minute = now.minute();
  int second = now.second();
  Serial.println((String)hour + ":" + minute + ":" + second);
  Dot = second % 2;
  return (hour * 100 + minute);
};
 

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

★★★★★★★
14 Авг 2019
4,323
1,319
Москва
В таком разрезе не выйдет без доп. ухищрений.
У тебя период изменения 1 секунда.
Тогда нужно что то типа:
C++:
if (old_sec!=second)
{
dot_timer=millis();
old_sec=second;
Dot=true;
}
if  (millis()-dot_timer>500) Dot=false;
old_sec статическая байтовая переменная
dot_timer статическая 32битная переменная

это все вместо
Dot = second % 2;
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
В таком разрезе не выйдет без доп. ухищрений.
так я и предлагал сделать в loop
C++:
Dots_on();
delay(500);
Dots_off();
delay(500);
это упрощенно, для понимания, а в датчиках уже указано Dots_off();
это все вместо
Dot = second % 2;
проверим...
 

kym13

★★★✩✩✩✩
14 Ноя 2020
716
118
foka44 )) Да Вы правы раз в 2 сек. моргают, проверил по другим часам.
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
Если так, то точек нет)
C++:
int GetTime() {
  DateTime now = rtc.now();
  int hour = now.hour();
  int minute = now.minute();
  int second = now.second();
  Serial.println((String)hour + ":" + minute + ":" + second);
  //  Dot = second % 2; // точки мигают раз в сек
  static byte old_sec;
  static uint32_t dot_timer;
  if (old_sec != second)
  {
    dot_timer = millis();
    old_sec = second;
    Dot = true;
  }
  if  (millis() - dot_timer > 500) Dot = false;
  return (hour * 100 + minute);
};
/////////////////////////////////////////////
void TimeToArray() { // вывод времени на экран
  int Now = GetTime(); // получаем время
  boolean Dots = true; // точки
  boolean color_change_flag = false;
  //  if (Dot == 0) Dots = false; else Dots = true;
  if (!Dot) { // показ точек
    for (uint8_t i = 0; i < DOTS_NUM; i++) {
      leds[(LEDS_IN_SEGMENT * 14) + i] = ledColor;
    }
  }
  else {
    Dots_off(); // выключение точек
  }
а если так, то горят)
C++:
int GetTime() {
  DateTime now = rtc.now();
  int hour = now.hour();
  int minute = now.minute();
  int second = now.second();
  Serial.println((String)hour + ":" + minute + ":" + second);
  //  Dot = second % 2; // точки мигают раз в сек
  static byte old_sec;
  static uint32_t dot_timer;
  if (old_sec != second)
  {
    dot_timer = millis();
    old_sec = second;
    Dot = true;
  }
  if  (millis() - dot_timer > 500) Dot = false;
  return (hour * 100 + minute);
};
/////////////////////////////////////////////
void TimeToArray() { // вывод времени на экран
  int Now = GetTime(); // получаем время
  boolean Dots = true; // точки
  boolean color_change_flag = false;
  //  if (Dot == 0) Dots = false; else Dots = true;
  if (Dot) { // показ точек
    for (uint8_t i = 0; i < DOTS_NUM; i++) {
      leds[(LEDS_IN_SEGMENT * 14) + i] = ledColor;
    }
  }
  else {
    Dots_off(); // выключение точек
  }

можно попробовать вынести из массива в запрос, объединить в одно место, может будет лучше...
 

foka44

✩✩✩✩✩✩✩
1 Мар 2021
10
0
Если так, то точек нет)
C++:
int GetTime() {
  DateTime now = rtc.now();
  int hour = now.hour();
  int minute = now.minute();
  int second = now.second();
  Serial.println((String)hour + ":" + minute + ":" + second);
  //  Dot = second % 2; // точки мигают раз в сек
  static byte old_sec;
  static uint32_t dot_timer;
  if (old_sec != second)
  {
    dot_timer = millis();
    old_sec = second;
    Dot = true;
  }
  if  (millis() - dot_timer > 500) Dot = false;
  return (hour * 100 + minute);
};
/////////////////////////////////////////////
void TimeToArray() { // вывод времени на экран
  int Now = GetTime(); // получаем время
  boolean Dots = true; // точки
  boolean color_change_flag = false;
  //  if (Dot == 0) Dots = false; else Dots = true;
  if (!Dot) { // показ точек
    for (uint8_t i = 0; i < DOTS_NUM; i++) {
      leds[(LEDS_IN_SEGMENT * 14) + i] = ledColor;
    }
  }
  else {
    Dots_off(); // выключение точек
  }
а если так, то горят)
C++:
int GetTime() {
  DateTime now = rtc.now();
  int hour = now.hour();
  int minute = now.minute();
  int second = now.second();
  Serial.println((String)hour + ":" + minute + ":" + second);
  //  Dot = second % 2; // точки мигают раз в сек
  static byte old_sec;
  static uint32_t dot_timer;
  if (old_sec != second)
  {
    dot_timer = millis();
    old_sec = second;
    Dot = true;
  }
  if  (millis() - dot_timer > 500) Dot = false;
  return (hour * 100 + minute);
};
/////////////////////////////////////////////
void TimeToArray() { // вывод времени на экран
  int Now = GetTime(); // получаем время
  boolean Dots = true; // точки
  boolean color_change_flag = false;
  //  if (Dot == 0) Dots = false; else Dots = true;
  if (Dot) { // показ точек
    for (uint8_t i = 0; i < DOTS_NUM; i++) {
      leds[(LEDS_IN_SEGMENT * 14) + i] = ledColor;
    }
  }
  else {
    Dots_off(); // выключение точек
  }

можно попробовать вынести из массива в запрос, объединить в одно место, может будет лучше...
Это то что надо, благодарю, моргают как надо
 

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

★★★★★★★
14 Авг 2019
4,323
1,319
Москва
Так выведи Dot в монитор порта.
GetTime() как часто вызывается ? Что бы работало должна как минимум 2 раза в секунду вызываться
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@Старик Похабыч, я сейчас переписываю функцию, сделаю проще)
C++:
void Dots (boolean Dot_On)  {
  for (uint8_t i = 0; i < DOTS_NUM; i++) {
    leds[(LEDS_IN_SEGMENT * 14) + i] = (Dot_On) ? ledColor : CRGB (0, 0, 0);
  }
}
  Dots(Dot);
  Dots(!Dot);
лучше?)
 

foka44

✩✩✩✩✩✩✩
1 Мар 2021
10
0
@foka44, да ладно?) у меня нет)
C++:
/////////////////////////////////////////////
int GetTime() {
  DateTime now = rtc.now();
  int hour = now.hour();
  int minute = now.minute();
  int second = now.second();
  Serial.println((String)hour + ":" + minute + ":" + second);
 // Dot = second % 2; // точки мигают раз в сек
  static byte old_sec;
  static uint32_t dot_timer;
  if (old_sec != second)
  {
    dot_timer = millis();
    old_sec = second;
    Dot = true;
  }
  if  (millis() - dot_timer > 500) Dot = false;
  return (hour * 100 + minute);
};
/////////////////////////////////////////////
void TimeToArray() { // вывод времени на экран
  int Now = GetTime(); // получаем время
  boolean color_change_flag = false;
 
 if (Dot) { // показ точек
  Dots_on();
 }
  else {
    Dots_off(); // выключение точек
  }
  for (int i = 1; i <= 4; i++) { // 4 сегмента
    int digit = Now % 10; // получаем последнюю цифру в времени
    int cursor = NUM_LEDS - i * LEDS_IN_SEGMENT * 7;
    if (i > 2) {
      cursor -= DOTS_NUM;
    }
    if ( i == 4 & digit == 0)Digit(digits[12], cursor); // если впереди ноль, то выключаем его, например 01:23 будет как 1:23
    else
      Digit(digits[digit], cursor);                     // иначе показываем символ

    if ( i == COLOR_CHANGE) {                           // как часто менять цвет
      if (digit != last_digit) {
          color_change_flag = true;
          last_digit = digit;
         }
      }
    Now /= 10;
  };
if (color_change_flag) ledColor =  ColorTable[random(NUM_COLORS)];     // случайный цвет из таблицы) 
};

/////////////////////////////////////////////
void Dots_on()  { // показ точек
   for (uint8_t i = 0; i < DOTS_NUM; i++) {
      leds[(LEDS_IN_SEGMENT * 14) + i] = ledColor;
    }
  }
/////////////////////////////////////////////
void Dots_off()  { // отключаем точки принудительно, где не нужны
  for (uint8_t i = 0; i < DOTS_NUM; i++) {
    leds[(LEDS_IN_SEGMENT * 14) + i] = 0x000000;
  }
}
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
Так выведи Dot в монитор порта.
Serial.println((String)"Dot " + Dot);
20:57:35
Dot 1
20:57:36
Dot 1
20:57:37
Dot 1
20:57:38
Dot 1
20:57:39
Dot 1
20:57:40
Dot 1
C++:
int GetTime() {
  DateTime now = rtc.now();
  int hour = now.hour();
  int minute = now.minute();
  int second = now.second();
  Serial.println((String)hour + ":" + minute + ":" + second);
  //  Dot = second % 2; // точки мигают раз в сек
  static byte old_sec;
  static uint32_t dot_timer;
  if (old_sec != second)
  {
    dot_timer = millis();
    old_sec = second;
    Dot = true;
  }
  if  (millis() - dot_timer > 500) Dot = false;
  return (hour * 100 + minute);
};

void Dots (boolean Dot_On)  {
  for (uint8_t i = 0; i < DOTS_NUM; i++) {
    leds[(LEDS_IN_SEGMENT * 14) + i] = (Dot_On) ? ledColor : CRGB (0, 0, 0);
  }
}

void TimeToArray() {
  int Now = GetTime();
  Dots(Dot);
 

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

★★★★★★★
14 Авг 2019
4,323
1,319
Москва
Все логично тебе надо вызывать функцию чаще. А раз в секунду вызывать у тебя смена состояния может быть только раз в секунду. А выключаться должно во вторую половину секунды.
Если делать отдельную процедуру смены точек, то мигание будет не совпадать со сменой секунд.
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
мигание будет не совпадать со сменой секунд
мигает себе и мигает) главное по 500мс, чтобы видно было глазу)
Все логично тебе надо вызывать функцию чаще
попробовал вставлять GetTime(); в разные места, приводит к беспорядку...

всегда выводит Dot 1, ни одной записи с Dot 0

на сегодня все, надо отдыхать)
 
Изменено:

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

★★★★★★★
14 Авг 2019
4,323
1,319
Москва
удаляй все к оленям. что внутри:
static byte old_sec;
static uint32_t dot_timer;
if (old_sec != second)
{
dot_timer = millis();
old_sec = second;
Dot = true;
}

в loop загоняй такой кусок

static uint32_t dot_timer=0;
if (millis()-dot_timer)>500
{
dot_timer = millis();
Dot=!Dot;
}

А далее все будет зависеть от частоты перерисовки часов. Они тоже должны рисоваться минимум 2 раза в секунду
 
  • Лойс +1
Реакции: ASM

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@Старик Похабыч, точки лезут везде, и в датчиках даже) в часах не мигают)
Код:
..
Время записано!
15:10:41
Dot 0
15:10:41
Dot 1
24 | 24.32
6 | 6.88
746 | 746.70
15:10:48
Dot 0
15:10:49
Dot 0
15:10:50
Dot 0
15:10:51
Dot 0
15:10:52
Dot 0
15:10:53
Dot 0
24 | 24.34
6 | 6.69
746 | 746.76
15:11:0
Dot 1
15:11:1
Dot 1
15:11:2
Dot 1
15:11:3
Dot 1
15:11:4
Dot 1
15:11:5
Dot 1
24 | 24.33
6 | 6.75
746 | 746.77
15:11:12
Dot 0
надо переделывать нашу елочку с выводом датчиков, на возможность в настройках включать, сколько по времени выводить каждый датчик.
я так думаю, текущий код не позволяет это сделать)
C++:
  static bool TempShow = true; // флаг для температуры в помещении
  static bool TempSShow = true; // флаг для температуры на улице
  static bool PressShow = true; // флаг для давления
  uint32_t tmrall = millis() % 12000 / 1000; //берем интервал в 12сек
  static uint32_t tmrall_old = 10000;        //в расчет берутся 10сек, в исключение 2 сек, ниже будет понятно:)
  if (tmrall_old != tmrall)
  {
    tmrall_old = tmrall;
    if (tmrall < 6) //6 сек показывают часы
    {
      TimeToArray();
      TempShow = true;
      TempSShow = true;
      PressShow = true;
    }
    else if (tmrall < 8) //2 секунды показывается температура, добавляем +2
    {
      if (TempShow)
      {
        TempToArray();
        TempShow = false;
      }
    }
    else if (tmrall < 10) //2 секунды показывается температура, добавляем +2
    {
      if (TempSShow)
      {
        TempStreetToArray();
        TempSShow = false;
      }
    }
    else
    {
      if (PressShow) // остальное время показывается давление
      {
        PressToArray();
        PressShow = false;
      }
    }
ты же что-то с case показывал пример, думаю стоит его разобрать) =>
 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
разобрался с кодом, но сразу возникают вопросы, если сделать чаще опросы, или как некоторые просят время 54 сек, датчик 2, датчик 2, датчик 2, то получается очень много case?)
C++:
void loop_test() {
  uint32_t tmrall = millis() % t_summ * 1000 / 1000; //
  switch (tmrall)
  {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
      {
        TimeToArray();
      }
      break;
    case 6:
    case 7:
      {
        TempToArray();
      }
      break;
    case 8:
    case 9:
      {
        TempStreetToArray();
      }
      break;

    case 10:
    case 11:
      {
        PressToArray();
      }
      break;
    case 12:
    case 13:
      break;

  }
  uint32_t last_show;
  if (millis() - last_show > 100)
  {
    FastLED.show();
    last_show = millis();
  }
}
 

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

★★★★★★★
14 Авг 2019
4,323
1,319
Москва
Да, тогда такое на фиг не надо.
Теперь делаем по взрослому.
Считай что у тебя 4 режима работы: 0- время, 1 датчик 1, 2 датчик 2, 3 датчики 3.

Изначально у тебя режим 0. Запоминаешь время начала режима. оно будет ВРЕМЯ (так для всех режимов), устанавливаешь ОТРЕЗОК_ВРЕМНИЕ для текущего режима, оно будет 54.

И далее делаешь так:

если (миллис()-ВРЕМЯ > ОТРЕЗОК_ВРЕМЕНИ )то
{
если (РЕЖИМ ==3), то режим будет 0, иначе РЕЖИМ++;
ОТРЕЗОКВРЕМЕНИ=сколькодлиться_режим (РЕЖИМ)
}

Это все было о выборе режима по интервалам.
Теперь надо выводить данные.
Выводить их можно 2-мя способоами: по времени и по изменению содержимого. Давай по времени
если (millis()-ВРЕМЯПОСЛЕДНЕГОВЫВОДА> ИНТЕРВАЛА ВЫВОДА)
{
ВРЕМЯПОСЛЕДНЕГОВЫВОДА=millis();
выводим данные исходя из режима
}
 
  • Лойс +1
Реакции: ASM