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

Большие часы на адресных светодиодах WS2812B
Всем привет, хочу рассказать о том как я попробовал повторить проект, но столкнулся с некоторыми проблемами.

Как-то раз на просторах зарубежного интернета я нашел вот такой проект часов на базе светодиодной ленты WS2812B: Big, Auto Dim, Room Clock, и мне захотелось его повторить. Часы устроены как семи сегментный циферблат и работают на RTC модуле DS3231 . Часы умеют показывать температуру, имеют кнопки для настройки и перевода на зимнее время и обратно, позже я добавил датчик влажности DHT11. Температура уже вместе с влажностью считывалась с этого датчика и выводилась раз в минуту. Хоть и в модуле часов есть температурный датчик, но похоже он показывал температуру не корректно из-за самонагрева (ИМХО).




Untitled Sketch_МП.png
И главное нанести много горячих соплей

IMG_20180907_120755.jpg


Когда все было собрано, повозившись с библиотеками, все заработало. И тут возникло одно большое НО: положения яркости в только в двух позициях меня не устраивало. Тем более на границе значений происходило мерцание. Установка яркости на статичном значении меня тоже не очень устраивала ибо днем при установленном тусклом свете ничего не было видно, а ночью даже со значениями близким к минимуму можно было осветить всю Москву. Поинтересовавшись как в других проектах с этим справляется Alex было решено заменить такой код настройки яркости.

C:
void BrightnessCheck(){
  const byte sensorPin = BRI_PIN; // light sensor pin
  const byte brightnessLow = 1; // Low brightness value
  const byte brightnessHigh = 50; // High brightness value
  int sensorValue = analogRead(sensorPin); // Read sensor
  Serial.print("Sensor is: ");Serial.println(sensorValue);
  sensorValue = map(sensorValue, 0, 255, 1, 100);
  LEDS.setBrightness(sensorValue);
  };
вот такими строчками:
C:
void BrightnessCheck() {

  if (auto_bright) {                         // если включена адаптивная яркость
    if (millis() - bright_timer > 100) {     // каждые 100 мс
      bright_timer = millis();               // сброить таймер
      new_bright = map(analogRead(BRI_PIN), 0, bright_constant, min_bright, max_bright);   // считать показания с фоторезистора, перевести диапазон
      new_bright = constrain(new_bright, min_bright, max_bright);
      new_bright_f = new_bright_f * coef + new_bright * (1 - coef);
      LEDS.setBrightness(new_bright_f);      // установить новую яркость
    }
  }
};

Тут стоит упомянуть что программистом я не являюсь и большинство проблем я пытаюсь решить методом тыка и перебора.

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

Что касается кода вот сылка на GitHub. Кое-что я перевел для лучшего понимания.

Давно хотел поделиться готовым и работоспособным проектом в кругах аудитории Алекса, но вышло так что собственно нормальной работоспособностью тут не пахнет. Буду благодарени, если у кто сможет помочь.
 
Изменено:

Комментарии

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
132
9
ну хорошо, раз пошла такая пьянка, может тогда хотя бы кто нибудь подскажет, как изменить последовательность отображения данных, к примеру поменять местами давление и влажность?
 

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
132
9
C++:
void loop()
{
  BrightnessCheck();                        // Проверяем датчик освещения
  DSTcheck();                               // Проверяем цветовые режимы
  TimeAdjust();                             // Проверяем время если сменилось на 1 цифру
  TimeToArray();                            // Проверяем часы если сменилось на 1 цифру
  //TempToDallasArray();                      // температура с DALLAS DS18B20
  TempToArray();                            // температура BME280
  HumidityToArray();                        // если будет влажность BME280
  PressureToArray();                        // давление BME280
  TempHomeToArray();                        // температура дома с RTC_DS3231
  DayMonthToArray() ;                       // Проверяем день и число
  FastLED.show();                           // Задаём массив светодиодов
// if (TempShowDallas == true) delay (4000); //время показа температуры с DALLAS DS18B20
  if (TempShow == true) delay (4000);       //время показа температуры с BME
  if (HumidityShow == true) delay (4000);   //время показа влажности
  if (PressureShow == true) delay (4000);   //время показа давления
  if (TempHomeShow == true) delay (4000);   //время показа температуры с RTC
  if (DayMonthShow == true) delay (4000);   //время показа даты
последовательность вывода не изменилась: температура, давление, влажность, температура дома, дата т.е. влажность с давлением местами всетаки не поменялись.
 
Изменено:

ASM

★★★★✩✩✩
26 Окт 2018
1,515
294
Код полностью перезаписывается...
Надо смотреть полностью код, залей его сюда с форматированием, неудобно в текстовом редакторе смотреть)
 
  • Лойс +1
Реакции: начинающий

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
132
9
так?:
C++:
//Основная работа по коду шла на форуме <a href="http://arduino.ru." rel="nofollow">http://arduino.ru.</a>
//Конкретно началось с поста №58.
//Много людей помогали и вносили свою лепту во всё это действо b707, bwn, GennOk.
//Данный проект подходит под определение метеостанция но основное предназначение это показ часов.
//Вывод данных о внутренней температуре, давлении и влажности с датчика BME280 и внешняя температура с DS18b20,
//есть внутренняя температура с RTC_DS3231, а также день и месяц.
//Очень много комментариев и росписей по конкретным блокам.
//Скетч универсальный, под любое количество LED-светодиодов, за это отдельное спасибо b707.
//переписана координатность символов, переназначение кнопок,
//отключение смены цветов либо смена по времени.
/*OdinochkA)))
http://arduino.ru/forum/programmirovanie/bolshie-nastennye-chasy-na-arduino
https://community.alexgyver.ru/threads/bolshie-chasy-na-adresnyx-svetodiodax-ws2812b.233/
*/

#include <Adafruit_BME280.h>
#include <DS3232RTC.h>
#include <Time.h>
#include <FastLED.h>
#include <OneWire.h>
//#include <DallasTemperature.h>

#define LEDS_IN_SEGMENT 1     // Задаём сколько у нас светодиодов в сегменте.
#define DOTS_NUM 2            // Задаём количество разделительных точек
#define COLOR_CHANGE 1        // ( 0 - НИКОГДА, 1 - каждую минуту, 2 - каждые 10 минут, 3 - каждый час, 4 - каждые 10 часов)
#define NUM_COLORS 26         // цветовая гамма
#define COLOR_ORDER BRG       // По умолчанию цвет стоит зелёный при выключенных режимах
#define DATA_PIN 13           // 6  подключение ленты
#define BRI_PIN A3            // А3 фоторезистор
#define auto_bright 1         // автоматическая подстройка яркости от уровня внешнего освещения (1 - включить, 0 - выключить)
#define max_bright 160        // максимальная яркость (0 - 255)
#define min_bright 60          // минимальная яркость (0 - 255)
#define bright_constant 1021  // константа усиления от внешнего света (0 - 1023), чем МЕНЬШЕ константа, тем "резче" будет прибавляться яркость
#define coef 0.8              // коэффициент фильтра (0.0 - 1.0), чем больше - тем медленнее меняется яркость
//#define ONE_WIRE_BUS 10       // пин температурного датчика DS18B20
int den;
int mes;

//OneWire oneWire(ONE_WIRE_BUS);          // настройка объекта oneWire для связи с любым устройством OneWire
//DallasTemperature sensors(&oneWire);    // передать ссылку на oneWire библиотеке DallasTemperature

int new_bright, new_bright_f;
unsigned long bright_timer, off_timer;

Adafruit_BME280 bme;            // BME280 давление, влажность, температура   I2C
//BME280 PINS       SCL -> SCL or A5     датчик подключается параллельно часам по I2C
//                  SDA -> SDA or A4
//DS3231RTC         SCL -> SCL or A5     датчик подключается параллельно BME280 по I2C
//                  SDA -> SDA or A4
//DS18b20               -> D10
//                         D2  ->       кнопка настройки часов
//                         D3  ->       кнопка настройки минут

// ======================================== Вычисляемые константы, НЕ РЕДАКТИРОВАТЬ!=========================================

#define NUM_LEDS (LEDS_IN_SEGMENT * 28 + DOTS_NUM)  //58 количество светодиодов в ленте

CRGB leds[NUM_LEDS]; //Задаём значение светодиодов, какой символ из чего состоит
uint8_t  digits[] = {
  0b00111111,     // Digit 0
  0b00100001,     // Digit 1
  0b01110110,     // Digit 2
  0b01110011,     // Digit 3
  0b01101001,     // Digit 4
  0b01011011,     // Digit 5
  0b01011111,     // Digit 6
  0b00110001,     // Digit 7
  0b01111111,     // Digit 8
  0b01111011,     // Digit 9
  0b01111000,     // Digit * градус  10
  0b01000000,     // Digit -         11
  0b01111100,     // Digit P         12
  0b01111000,     // Digit % знак % из двух частей 13
  0b01000111,     // Digit % знак % из двух частей 14
  0b00000000,     // Digit пусто 15
  0b00011110,     // Digit C  16
};

bool Dot = true;
bool DST = false;
bool TempShow = true;
bool PressureShow = true;
bool HumidityShow = true;
bool TempHomeShow = true;
bool TempShowDallas = true;
bool DayMonthShow = true;
int last_digit = 0;

//==================================================== Используемый цвет ============================================

long ledColor = CRGB::Aqua;     // Используемый цвет
long ColorTable[NUM_COLORS] = {
  CRGB::Amethyst,
  CRGB::Orange,
  CRGB::Aqua,
  CRGB::Blue,
  CRGB::Chartreuse,
  CRGB::DarkGreen,
  CRGB::DarkMagenta,
  CRGB::DarkOrange,
  CRGB::DeepPink,
  CRGB::Indigo,
  CRGB::Gold,
  CRGB::DarkBlue,
  CRGB::WhiteSmoke,
  CRGB::SkyBlue,
  CRGB::BlueViolet,
  CRGB::Red,
  CRGB::AliceBlue,
  CRGB::Crimson,
  CRGB::DarkRed,
  CRGB::OrangeRed,
  CRGB::SeaGreen,
  CRGB::SpringGreen,
  CRGB::Yellow,
  CRGB::Lime,
  CRGB::DarkCyan,
  CRGB::DodgerBlue
};

void setup() {
  Serial.begin(9600);
  LEDS.addLeds<WS2811, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  bme.begin(0x76);           //BME датчик, адрес 0x76 или 0x77
  pinMode(4, INPUT_PULLUP);  // Кнопка смены цветов 4
  pinMode(3, INPUT_PULLUP);  // Кнопка регулировки минут 3
  pinMode(2, INPUT_PULLUP);  // Кнопка регулировки часов 2
  pinMode(7, INPUT_PULLUP);  // Кнопка сброса секунд 7
//  sensors.begin();           // запустить библиотеку
}

//новые координаты точек
#define UPPER_DOT 0 //  добавлено: одна точка светится при выводе даты
#define LOWER_DOT 1 //

void BrightOneDot (uint8_t dot_num, boolean Dot_On) {
leds[(LEDS_IN_SEGMENT * 14)+ dot_num] = (Dot_On) ? ledColor : 0;
}

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

void BrightDigit (uint8_t digit, uint8_t cursor)
{
  for (uint8_t mask = 0b01000000; mask > 0; mask = mask >> 1)
  {
    for (uint8_t i = 0; i < LEDS_IN_SEGMENT; i++)
    {
      leds[cursor] = (digit & mask) ? ledColor : 0;
      cursor ++;
    }
  }
}

//========================================= Массив управляет яркостью ============================================

// Новый метод изменения яркости
void BrightnessCheck() {

  if (auto_bright) {                         // если включена адаптивная яркость
    if (millis() - bright_timer > 100) {     // каждые 100 мс
      bright_timer = millis();               // сбросить таймер
  //    Serial.print("Освещение: ");         // вывод инфы в сом порт
  //    Serial.println(sensorValue);         // вывод инфы в сом порт
     // new_bright = map(analogRead(BRI_PIN), 0, bright_constant, max_bright, min_bright);   // когда темно уменьшает яркость
      new_bright = map(analogRead(BRI_PIN), 0, bright_constant, min_bright, max_bright);   // когда темно увеличивает яркость
//  new_bright = map(analogRead(3), 0, bright_constant, max_bright, min_bright);   // считать показания с фоторезистора, перевести диапазон
// new_bright = map(analogRead(3), 0, bright_constant, min_bright, max_bright);   // считать показания с фоторезистора, перевести диапазон
      new_bright = constrain(new_bright, min_bright, max_bright);
      new_bright_f = new_bright_f * coef + new_bright * (1 - coef);
      LEDS.setBrightness(new_bright_f);      // установить новую яркость
    }
  }
};

//========================================  Получаем время ========================================

int GetTime()
{
  tmElements_t Now;
  RTC.read(Now);
  int hour = Now.Hour;
  int minute = Now.Minute;
  int second = Now.Second;

  if (second % 2 == 0) // было (2) 1 раз в секунду частота мигания точек, больше цифра медленнее
  {                    // если поставить 1 точки отключатся но часы будут идти
    Dot = false;
  }
  else {
    Dot = true;
  };
  return (hour * 100 + minute);
};

//======================================= Преобразуем время в массив для отображения =========================================

void TimeToArray() {
  int buttonH = digitalRead(2);
  int buttonM = digitalRead(3);
  int Now = GetTime(); // Получаем время
  BrightOneDot(UPPER_DOT, 0);
  BrightOneDot(LOWER_DOT, 1);
  BrightDots(Dot);

  for (int i = 1; i <= 4; i++) {
    int digit = Now % 10; // Получаем последнюю цифру в времени
    int cursor = NUM_LEDS - i * LEDS_IN_SEGMENT * 7;
    if (i > 2) {
      cursor -= 2;
    }
// =============== Убираем не значащий ноль,будет отображаться 1:55  вместо 01:55 ===============================

    if ( (i != 4) || (digit != 0)) BrightDigit(digits[digit], cursor); //  00:15 показывает 0:15
    else BrightDigit(0, cursor);
    if ( i == COLOR_CHANGE) {
      if (buttonH != LOW && buttonM != LOW)            // Если зажата кнопка час или мин, нет радуги и смены цвета
      if (digit != last_digit)
      {
       cylon ();                                     // Эффект "Радуга" при каждом изменении цвета, если нужно раскоментируйте
        ledColor =  ColorTable[random(NUM_COLORS)];    // цикличное изменение цветов
      }
      last_digit = digit;
    }
    Now /= 10;
  };
};

//=============================================== Блок функции вывода метеоданных ==========================================
/*
// ======================================== вывод температуры с DALLAS DS18B20 =============================================


// Температура
void TempToDallasArray(){                // вывод температуры с DALLAS DS18B20        
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 8) {                 //через какое время показывать температуру
  TempShowDallas = false;        
    return;                  
  }
TempShowDallas = true;            
  sensors.requestTemperatures();         // отправляем команду для получения показаний температуры
  int t = sensors.getTempCByIndex(0);
  int celsius = t;
  celsius = abs(t);

BrightOneDot(UPPER_DOT, 0);
BrightOneDot(LOWER_DOT, 0);

  BrightDots(0);  //разделительные мигающие точки выключены
  BrightDigit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                             // знак Градуса (*) 4й блок
   int digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                         // 3 блок единицы градуса
   celsius /= 10;
  digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));              //  2й блок десятки градусов
   if (digit == 0)BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); //Если впереди ноль, то выключаем его
    if(t<= -1)BrightDigit(digits[11], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));     // знак минус если ниже 0
   else
  BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));                 //иначе выключаем

};
*/
//=============================================== Вывод температуры с BME280  ==================================================

// Температура
void TempToArray() {               // вывод температуры с BME
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 16) {           //через какое время показывать температуру
    TempShow = false;
    return;
  }
  TempShow = true;
  int t = bme.readTemperature();
  int celsius = t;
  celsius = abs(t);

BrightOneDot(UPPER_DOT, 0);
BrightOneDot(LOWER_DOT, 0);

  BrightDots(0);  //разделительные мигающие точки выключены
  BrightDigit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                             // знак Градуса (*) 4й блок
   int digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                         // 3 блок единицы градуса
   celsius /= 10;
  digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));              //  2й блок десятки градусов
   if (digit == 0)BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); //Если впереди ноль, то выключаем его
    if(t<= -1)BrightDigit(digits[11], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));     // знак минус если ниже 0
   else
  BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));                 //иначе выключаем

};
//================================================== Вывод атмосферного давления с BME280 ====================================================

// Давление
void PressureToArray() {
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 24) {//через какое время показывать давление
    PressureShow = false;
    return;
  }
  PressureShow = true;
  int p = bme.readPressure() / 133.322;  //int p = bmp.readPressure() / 133.322;c
  int Pressure = p;

BrightOneDot(UPPER_DOT, 0);
BrightOneDot(LOWER_DOT, 0);

  BrightDots(0); //разделительные мигающие точки выключены
  BrightDigit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));      //0  начало знака Давления (Р) 1й блок
  int digit = Pressure % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 7 ));              //65  4й блок вывода третьей цифры значения
  Pressure /= 10;
  digit = Pressure % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));              //44  3й блок вывода второй цифры значения
  Pressure /= 10;
  digit = Pressure % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM ));  //21  2й блок вывода первой цифры значения

};
//=============================================== Вывод влажности с BME280 ============================================

//Влажность
void HumidityToArray() {
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 32) {          //через какое время показывать влажность
    HumidityShow = false;
    return;
  }
  HumidityShow = true;
  int h = bme.readHumidity();
  int humidity = h;

BrightOneDot(UPPER_DOT, 0);
BrightOneDot(LOWER_DOT, 0);

  BrightDots(0);  //разделительные мигающие точки выключены
  BrightDigit(digits[14], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                 //65  конец знака процентов (%) 4й блок
  BrightDigit(digits[13], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                //44  начало знака процентов (%) 3 блок
  int digit = humidity % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));  //21  2й блок вывода второго символа
  humidity /= 10;
  digit = humidity % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));  //0  1й блок вывода первого символа

};

//======================================== Вывод температуры с RTC DS3231 ===============================================

// Температура дома с RTC
void TempHomeToArray(){
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 40) {
    TempHomeShow = false;
    return;
  }
  TempHomeShow = true;
  int t = RTC.temperature();
  int celsius = (t / 4.0);

  BrightDots(0);  //разделительные мигающие точки выключены
  BrightDigit(digits[16], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                 // начало знака Цельсия (С) 4й блок
  BrightDigit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                // начало знака Градус (*) 3й блок
  int digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));  // 2й блок вывода второго символа
  celsius /= 10;
  digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));  // 1й блок вывода первого символа

};
//============================================ Вывод даты и месяца ============================================

//Функция вывода даты
// День Месяц
void DayMonthToArray(){
  tmElements_t tm;
  RTC.read(tm);
  int d = tm.Day;
  int m = tm.Month;
  if (tm.Second != 48) {
    DayMonthShow = false;
    return;
    }
  DayMonthShow = true;

  BrightOneDot(UPPER_DOT, 0);
  BrightOneDot(LOWER_DOT, 1);
//  BrightDots(1);  //разделительные точки включены   BrightDots(1);
  den = d;
  int  digit = den % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));              //  2й блок единицы дней
  den /= 10;
  digit = den % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));              //  1й блок десятки дней
//  if (digit == 0)BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); //Если впереди ноль, то выключаем его
  int mes = m;
  digit = mes % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                          //  4й блок вывода единиц месяца
  mes /= 10;
  digit = mes % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                         //  3й блок вывода десятка месяца
//  if (digit == 0)BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 14));            //Если впереди ноль, то выключаем его

}
//================================================ Смена цвета ленты кнопкой DST Pin 4 ==============================

//смена цвета ленты кнопкой DST Pin 4
void DSTcheck() {
  int buttonDST = digitalRead(4);
  if (buttonDST == LOW) {
    ledColor =  ColorTable[random(NUM_COLORS)];
  };
  delay(200);//время реакции на нажатие
};

//======================================= Массив управляет кнопками с часами и минутами ===============================

void SecondReset() {
  int buttonR = digitalRead(7);
  if (buttonR == LOW) {
    delay(100);
    tmElements_t Now;
    RTC.read(Now);
    int second = Now.Second;
if (buttonR == LOW) {
    Now.Second = 0;
}
    RTC.write(Now);
  }
} 
void TimeAdjust() {
  int buttonH = digitalRead(2);
  int buttonM = digitalRead(3);
  if (buttonH == LOW || buttonM == LOW) {
    delay(100);//время реакции на нажатие
    tmElements_t Now;
    RTC.read(Now);
    int hour = Now.Hour;
    int minutes = Now.Minute;
    int second = Now.Second;
    if (buttonH == LOW) {
      if (Now.Hour == 23) {
        Now.Hour = 0;
      }
      else {
        Now.Hour += 1;
      };
    }
    else
    {
      if (Now.Minute == 59) {
        Now.Minute = 0;
      }
      else {
        Now.Minute += 1;
      };
    };
    RTC.write(Now);
  }
}

//Меняем эффекты
void fadeall() {
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i].nscale8(250);
  }
}

//================================= массив отвечает за цикличное изменение цветов =======================================

void cylon () {
  static uint8_t hue = 0;
  //Serial.print("x");
  // Сдвигаем один светодиод в любом направлении
  for (int i = 0; i < NUM_LEDS; i++) {
  // Устанавливаем 1 светодиод на цвет красный
    leds[i] = CHSV(hue++, 255, 255);
  // Показываем светодиоды
    FastLED.show();
    fadeall();
  // Ждём немного и повторяем цикл
    delay(30);
  }
  //Serial.print("x");
  // Сдвигаем один светодиод в любом направлении
  for (int i = (NUM_LEDS) - 1; i >= 0; i--) {
  // Устанавливаем 1 светодиод на цвет красный
    leds[i] = CHSV(hue++, 255, 255);
  // Показываем светодиоды
    FastLED.show();
    fadeall();
  // Ждём немного и повторяем цикл
    delay(30);
  }
}



void loop()
{
  BrightnessCheck();                        // Проверяем датчик освещения
  DSTcheck();                               // Проверяем цветовые режимы
  TimeAdjust();                             // Проверяем время если сменилось на 1 цифру
  TimeToArray();                            // Проверяем часы если сменилось на 1 цифру
  //TempToDallasArray();                      // температура с DALLAS DS18B20
  TempToArray();                            // температура BME280
  HumidityToArray();                        // если будет влажность BME280
  PressureToArray();                        // давление BME280
  TempHomeToArray();                        // температура дома с RTC_DS3231
  DayMonthToArray() ;                       // Проверяем день и число
  FastLED.show();                           // Задаём массив светодиодов
// if (TempShowDallas == true) delay (4000); //время показа температуры с DALLAS DS18B20
  if (TempShow == true) delay (4000);       //время показа температуры с BME
  if (HumidityShow == true) delay (4000);   //время показа влажности
  if (PressureShow == true) delay (4000);   //время показа давления
  if (TempHomeShow == true) delay (4000);   //время показа температуры с RTC
  if (DayMonthShow == true) delay (4000);   //время показа даты

   
/*
//=================================== Вывод информации в сом порт =============================================

  // Раскомvентировать если нужно посмотреть в сом порте, маленько подтормаживает вся система если это открыто
    Serial.print("Tемпература = ");
    Serial.print(bme.readTemperature());  //Serial.print(bmp.readTemperature());
    Serial.println("*C");
   
    Serial.print ("Давление = ");
    Serial.print (bme.readPressure() / 133.322);  //Serial.print (bmp.readPressure() / 133.322); // Полученное значение в Па делим на 133,322 и получаем мм.рт.ст.
    Serial.println (" mm"); // и соответственно меняем "Pa" на "mm"

    Serial.print ("Влажность = ");
    Serial.print (bme.readHumidity() ); // Serial.print (dht.readHumidity() ); //
    Serial.println ("%\t"); //
    Serial.println();
    delay(5000);

    Serial.println (" *ПЕТРОВИЧ* "); //
*/  
}
 
Изменено:

ASM

★★★★✩✩✩
26 Окт 2018
1,515
294
Во, всё так.
Ничего в коде не вижу, на первый взгляд, что завязывает эти функции не вижу.
Порядок определяется в loop...
 
Изменено:
  • Лойс +1
Реакции: начинающий

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
132
9
Вот и я о том же, какой то пол литр гейст в коде поселился, отображение параметров не меняется, секунды не обнуляются, и помочь с этим горем некому.
 

ASM

★★★★✩✩✩
26 Окт 2018
1,515
294
Опять не вижу, где вызов функции SecondReset в loop?)
Функцию можно попробовать упростить, думаю будет работать)

void SecondReset() {
int buttonR = digitalRead(7);
if (buttonR == LOW) {
delay(100);
tmElements_t Now;
RTC.read(Now);
Now.Second = 0;
RTC.write(Now);
}
}
 
  • Лойс +1
Реакции: начинающий

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
132
9
щас исправлю
Вот, правильно: ?
C++:
//Основная работа по коду шла на форуме <a href="http://arduino.ru." rel="nofollow">http://arduino.ru.</a>
//Конкретно началось с поста №58.
//Много людей помогали и вносили свою лепту во всё это действо b707, bwn, GennOk.
//Данный проект подходит под определение метеостанция но основное предназначение это показ часов.
//Вывод данных о внутренней температуре, давлении и влажности с датчика BME280 и внешняя температура с DS18b20,
//есть внутренняя температура с RTC_DS3231, а также день и месяц.
//Очень много комментариев и росписей по конкретным блокам.
//Скетч универсальный, под любое количество LED-светодиодов, за это отдельное спасибо b707.
//переписана координатность символов, переназначение кнопок,
//отключение смены цветов либо смена по времени.
/*OdinochkA)))
http://arduino.ru/forum/programmirovanie/bolshie-nastennye-chasy-na-arduino
https://community.alexgyver.ru/threads/bolshie-chasy-na-adresnyx-svetodiodax-ws2812b.233/
*/

#include <Adafruit_BME280.h>
#include <DS3232RTC.h>
#include <Time.h>
#include <FastLED.h>
#include <OneWire.h>
//#include <DallasTemperature.h>

#define LEDS_IN_SEGMENT 1     // Задаём сколько у нас светодиодов в сегменте.
#define DOTS_NUM 2            // Задаём количество разделительных точек
#define COLOR_CHANGE 1        // ( 0 - НИКОГДА, 1 - каждую минуту, 2 - каждые 10 минут, 3 - каждый час, 4 - каждые 10 часов)
#define NUM_COLORS 26         // цветовая гамма
#define COLOR_ORDER BRG       // По умолчанию цвет стоит зелёный при выключенных режимах
#define DATA_PIN 13           // 6  подключение ленты
#define BRI_PIN A3            // А3 фоторезистор
#define auto_bright 1         // автоматическая подстройка яркости от уровня внешнего освещения (1 - включить, 0 - выключить)
#define max_bright 160        // максимальная яркость (0 - 255)
#define min_bright 60          // минимальная яркость (0 - 255)
#define bright_constant 1021  // константа усиления от внешнего света (0 - 1023), чем МЕНЬШЕ константа, тем "резче" будет прибавляться яркость
#define coef 0.8              // коэффициент фильтра (0.0 - 1.0), чем больше - тем медленнее меняется яркость
//#define ONE_WIRE_BUS 10       // пин температурного датчика DS18B20
int den;
int mes;

//OneWire oneWire(ONE_WIRE_BUS);          // настройка объекта oneWire для связи с любым устройством OneWire
//DallasTemperature sensors(&oneWire);    // передать ссылку на oneWire библиотеке DallasTemperature

int new_bright, new_bright_f;
unsigned long bright_timer, off_timer;

Adafruit_BME280 bme;            // BME280 давление, влажность, температура   I2C
//BME280 PINS       SCL -> SCL or A5     датчик подключается параллельно часам по I2C
//                  SDA -> SDA or A4
//DS3231RTC         SCL -> SCL or A5     датчик подключается параллельно BME280 по I2C
//                  SDA -> SDA or A4
//DS18b20               -> D10
//                         D2  ->       кнопка настройки часов
//                         D3  ->       кнопка настройки минут

// ======================================== Вычисляемые константы, НЕ РЕДАКТИРОВАТЬ!=========================================

#define NUM_LEDS (LEDS_IN_SEGMENT * 28 + DOTS_NUM)  //58 количество светодиодов в ленте

CRGB leds[NUM_LEDS]; //Задаём значение светодиодов, какой символ из чего состоит
uint8_t  digits[] = {
  0b00111111,     // Digit 0
  0b00100001,     // Digit 1
  0b01110110,     // Digit 2
  0b01110011,     // Digit 3
  0b01101001,     // Digit 4
  0b01011011,     // Digit 5
  0b01011111,     // Digit 6
  0b00110001,     // Digit 7
  0b01111111,     // Digit 8
  0b01111011,     // Digit 9
  0b01111000,     // Digit * градус  10
  0b01000000,     // Digit -         11
  0b01111100,     // Digit P         12
  0b01111000,     // Digit % знак % из двух частей 13
  0b01000111,     // Digit % знак % из двух частей 14
  0b00000000,     // Digit пусто 15
  0b00011110,     // Digit C  16
};

bool Dot = true;
bool DST = false;
bool TempShow = true;
bool PressureShow = true;
bool HumidityShow = true;
bool TempHomeShow = true;
bool TempShowDallas = true;
bool DayMonthShow = true;
int last_digit = 0;

//==================================================== Используемый цвет ============================================

long ledColor = CRGB::Aqua;     // Используемый цвет
long ColorTable[NUM_COLORS] = {
  CRGB::Amethyst,
  CRGB::Orange,
  CRGB::Aqua,
  CRGB::Blue,
  CRGB::Chartreuse,
  CRGB::DarkGreen,
  CRGB::DarkMagenta,
  CRGB::DarkOrange,
  CRGB::DeepPink,
  CRGB::Indigo,
  CRGB::Gold,
  CRGB::DarkBlue,
  CRGB::WhiteSmoke,
  CRGB::SkyBlue,
  CRGB::BlueViolet,
  CRGB::Red,
  CRGB::AliceBlue,
  CRGB::Crimson,
  CRGB::DarkRed,
  CRGB::OrangeRed,
  CRGB::SeaGreen,
  CRGB::SpringGreen,
  CRGB::Yellow,
  CRGB::Lime,
  CRGB::DarkCyan,
  CRGB::DodgerBlue
};

void setup() {
  Serial.begin(9600);
  LEDS.addLeds<WS2811, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  bme.begin(0x76);           //BME датчик, адрес 0x76 или 0x77
  pinMode(4, INPUT_PULLUP);  // Кнопка смены цветов 4
  pinMode(3, INPUT_PULLUP);  // Кнопка регулировки минут 3
  pinMode(2, INPUT_PULLUP);  // Кнопка регулировки часов 2
  pinMode(7, INPUT_PULLUP);  // Кнопка обнуления секунд 7
//  sensors.begin();           // запустить библиотеку
}

//новые координаты точек
#define UPPER_DOT 0 //  добавлено: одна точка светится при выводе даты
#define LOWER_DOT 1 //

void BrightOneDot (uint8_t dot_num, boolean Dot_On) {
leds[(LEDS_IN_SEGMENT * 14)+ dot_num] = (Dot_On) ? ledColor : 0;
}

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

void BrightDigit (uint8_t digit, uint8_t cursor)
{
  for (uint8_t mask = 0b01000000; mask > 0; mask = mask >> 1)
  {
    for (uint8_t i = 0; i < LEDS_IN_SEGMENT; i++)
    {
      leds[cursor] = (digit & mask) ? ledColor : 0;
      cursor ++;
    }
  }
}

//========================================= Массив управляет яркостью ============================================

// Новый метод изменения яркости
void BrightnessCheck() {

  if (auto_bright) {                         // если включена адаптивная яркость
    if (millis() - bright_timer > 100) {     // каждые 100 мс
      bright_timer = millis();               // сбросить таймер
  //    Serial.print("Освещение: ");         // вывод инфы в сом порт
  //    Serial.println(sensorValue);         // вывод инфы в сом порт
     // new_bright = map(analogRead(BRI_PIN), 0, bright_constant, max_bright, min_bright);   // когда темно уменьшает яркость
      new_bright = map(analogRead(BRI_PIN), 0, bright_constant, min_bright, max_bright);   // когда темно увеличивает яркость
//  new_bright = map(analogRead(3), 0, bright_constant, max_bright, min_bright);   // считать показания с фоторезистора, перевести диапазон
// new_bright = map(analogRead(3), 0, bright_constant, min_bright, max_bright);   // считать показания с фоторезистора, перевести диапазон
      new_bright = constrain(new_bright, min_bright, max_bright);
      new_bright_f = new_bright_f * coef + new_bright * (1 - coef);
      LEDS.setBrightness(new_bright_f);      // установить новую яркость
    }
  }
};

//========================================  Получаем время ========================================

int GetTime()
{
  tmElements_t Now;
  RTC.read(Now);
  int hour = Now.Hour;
  int minute = Now.Minute;
  int second = Now.Second;

  if (second % 2 == 0) // было (2) 1 раз в секунду частота мигания точек, больше цифра медленнее
  {                    // если поставить 1 точки отключатся но часы будут идти
    Dot = false;
  }
  else {
    Dot = true;
  };
  return (hour * 100 + minute);
};

//======================================= Преобразуем время в массив для отображения =========================================

void TimeToArray() {
  int buttonH = digitalRead(2);
  int buttonM = digitalRead(3);
  int Now = GetTime(); // Получаем время
  BrightOneDot(UPPER_DOT, 0);
  BrightOneDot(LOWER_DOT, 1);
  BrightDots(Dot);

  for (int i = 1; i <= 4; i++) {
    int digit = Now % 10; // Получаем последнюю цифру в времени
    int cursor = NUM_LEDS - i * LEDS_IN_SEGMENT * 7;
    if (i > 2) {
      cursor -= 2;
    }
// =============== Убираем не значащий ноль,будет отображаться 1:55  вместо 01:55 ===============================

    if ( (i != 4) || (digit != 0)) BrightDigit(digits[digit], cursor); //  00:15 показывает 0:15
    else BrightDigit(0, cursor);
    if ( i == COLOR_CHANGE) {
      if (buttonH != LOW && buttonM != LOW)            // Если зажата кнопка час или мин, нет радуги и смены цвета
      if (digit != last_digit)
      {
       cylon ();                                     // Эффект "Радуга" при каждом изменении цвета, если нужно раскоментируйте
        ledColor =  ColorTable[random(NUM_COLORS)];    // цикличное изменение цветов
      }
      last_digit = digit;
    }
    Now /= 10;
  };
};

//=============================================== Блок функции вывода метеоданных ==========================================
/*
// ======================================== вывод температуры с DALLAS DS18B20 =============================================


// Температура
void TempToDallasArray(){                // вывод температуры с DALLAS DS18B20         
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 8) {                 //через какое время показывать температуру
  TempShowDallas = false;         
    return;                   
  }
 TempShowDallas = true;             
  sensors.requestTemperatures();         // отправляем команду для получения показаний температуры
  int t = sensors.getTempCByIndex(0);
  int celsius = t;
  celsius = abs(t);

BrightOneDot(UPPER_DOT, 0);
BrightOneDot(LOWER_DOT, 0);

  BrightDots(0);  //разделительные мигающие точки выключены
  BrightDigit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                             // знак Градуса (*) 4й блок
   int digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                         // 3 блок единицы градуса
   celsius /= 10;
  digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));              //  2й блок десятки градусов
   if (digit == 0)BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); //Если впереди ноль, то выключаем его
    if(t<= -1)BrightDigit(digits[11], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));     // знак минус если ниже 0
   else
  BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));                 //иначе выключаем
 
};
*/
//=============================================== Вывод температуры с BME280  ==================================================

// Температура
void TempToArray() {               // вывод температуры с BME
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 16) {           //через какое время показывать температуру
    TempShow = false;
    return;
  }
  TempShow = true;
  int t = bme.readTemperature();
  int celsius = t;
  celsius = abs(t);

BrightOneDot(UPPER_DOT, 0);
BrightOneDot(LOWER_DOT, 0);
 
  BrightDots(0);  //разделительные мигающие точки выключены
  BrightDigit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                             // знак Градуса (*) 4й блок
   int digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                         // 3 блок единицы градуса
   celsius /= 10;
  digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));              //  2й блок десятки градусов
   if (digit == 0)BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); //Если впереди ноль, то выключаем его
    if(t<= -1)BrightDigit(digits[11], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));     // знак минус если ниже 0
   else
  BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));                 //иначе выключаем
 
};
//================================================== Вывод атмосферного давления с BME280 ====================================================

// Давление
 void PressureToArray() {
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 24) {//через какое время показывать давление
    PressureShow = false;
    return;
  }
  PressureShow = true;
  int p = bme.readPressure() / 133.322;  //int p = bmp.readPressure() / 133.322;c
  int Pressure = p;

BrightOneDot(UPPER_DOT, 0);
BrightOneDot(LOWER_DOT, 0);
 
  BrightDots(0); //разделительные мигающие точки выключены
  BrightDigit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));      //0  начало знака Давления (Р) 1й блок
  int digit = Pressure % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 7 ));              //65  4й блок вывода третьей цифры значения
  Pressure /= 10;
  digit = Pressure % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));              //44  3й блок вывода второй цифры значения
  Pressure /= 10;
  digit = Pressure % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM ));  //21  2й блок вывода первой цифры значения
 
};
//=============================================== Вывод влажности с BME280 ============================================

 //Влажность
 void HumidityToArray() {
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 32) {          //через какое время показывать влажность
    HumidityShow = false;
    return; 
  }
  HumidityShow = true;
  int h = bme.readHumidity();
  int humidity = h;

BrightOneDot(UPPER_DOT, 0);
BrightOneDot(LOWER_DOT, 0);
 
  BrightDots(0);  //разделительные мигающие точки выключены
  BrightDigit(digits[14], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                 //65  конец знака процентов (%) 4й блок
  BrightDigit(digits[13], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                //44  начало знака процентов (%) 3 блок
  int digit = humidity % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));  //21  2й блок вывода второго символа
  humidity /= 10;
  digit = humidity % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));  //0  1й блок вывода первого символа
 
};

//======================================== Вывод температуры с RTC DS3231 ===============================================

// Температура дома с RTC
 void TempHomeToArray(){
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 40) {
    TempHomeShow = false;
    return;
  }
  TempHomeShow = true;
  int t = RTC.temperature();
  int celsius = (t / 4.0);
 
  BrightDots(0);  //разделительные мигающие точки выключены
  BrightDigit(digits[16], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                 // начало знака Цельсия (С) 4й блок
  BrightDigit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                // начало знака Градус (*) 3й блок
  int digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));  // 2й блок вывода второго символа
  celsius /= 10;
  digit = celsius % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));  // 1й блок вывода первого символа
 
};
//============================================ Вывод даты и месяца ============================================

//Функция вывода даты
// День Месяц
void DayMonthToArray(){
  tmElements_t tm;
  RTC.read(tm);
  int d = tm.Day;
  int m = tm.Month;
  if (tm.Second != 48) {
    DayMonthShow = false;
    return;
    }
  DayMonthShow = true;

  BrightOneDot(UPPER_DOT, 0);
  BrightOneDot(LOWER_DOT, 1);
//  BrightDots(1);  //разделительные точки включены   BrightDots(1);
  den = d;
  int  digit = den % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));              //  2й блок единицы дней
  den /= 10;
  digit = den % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));              //  1й блок десятки дней
 //  if (digit == 0)BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); //Если впереди ноль, то выключаем его
  int mes = m;
  digit = mes % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 7));                          //  4й блок вывода единиц месяца
  mes /= 10;
  digit = mes % 10;
  BrightDigit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));                         //  3й блок вывода десятка месяца
 //  if (digit == 0)BrightDigit(digits[15], (NUM_LEDS - LEDS_IN_SEGMENT * 14));            //Если впереди ноль, то выключаем его

 }
//================================================ Смена цвета ленты кнопкой DST Pin 4 ==============================

//смена цвета ленты кнопкой DST Pin 4
void DSTcheck() {
  int buttonDST = digitalRead(4);
  if (buttonDST == LOW) {
    ledColor =  ColorTable[random(NUM_COLORS)];
  };
  delay(200);//время реакции на нажатие
};

//======================================= Массив управляет кнопками с часами и минутами ===============================

void SecondReset() {
int buttonR = digitalRead(7);
if (buttonR == LOW) {
delay(100);
tmElements_t Now;
RTC.read(Now);
int second = Now.Second;
if (buttonR == LOW) {
Now.Second = 0;
}
RTC.write(Now);
}
}
void TimeAdjust() {
  int buttonH = digitalRead(2);
  int buttonM = digitalRead(3);
  if (buttonH == LOW || buttonM == LOW) {
    delay(100);//время реакции на нажатие
    tmElements_t Now;
    RTC.read(Now);
    int hour = Now.Hour;
    int minutes = Now.Minute;
    int second = Now.Second;
    if (buttonH == LOW) {
      if (Now.Hour == 23) {
        Now.Hour = 0;
      }
      else {
        Now.Hour += 1;
      };
    }
    else
    {
      if (Now.Minute == 59) {
        Now.Minute = 0;
      }
      else {
        Now.Minute += 1;
      };
    };
    RTC.write(Now);
  }
}

//Меняем эффекты
void fadeall() {
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i].nscale8(250);
  }
}

//================================= массив отвечает за цикличное изменение цветов =======================================

void cylon () {
  static uint8_t hue = 0;
  //Serial.print("x");
  // Сдвигаем один светодиод в любом направлении
  for (int i = 0; i < NUM_LEDS; i++) {
  // Устанавливаем 1 светодиод на цвет красный
    leds[i] = CHSV(hue++, 255, 255);
  // Показываем светодиоды
    FastLED.show();
    fadeall();
  // Ждём немного и повторяем цикл
    delay(30);
  }
  //Serial.print("x");
  // Сдвигаем один светодиод в любом направлении
  for (int i = (NUM_LEDS) - 1; i >= 0; i--) {
  // Устанавливаем 1 светодиод на цвет красный
    leds[i] = CHSV(hue++, 255, 255);
  // Показываем светодиоды
    FastLED.show();
    fadeall();
  // Ждём немного и повторяем цикл
    delay(30);
  }
}



void loop()
{
  BrightnessCheck();                        // Проверяем датчик освещения
  DSTcheck();                               // Проверяем цветовые режимы
  SecondReset();                             // сброс секунд
  TimeAdjust();                             // Проверяем время если сменилось на 1 цифру
  TimeToArray();                            // Проверяем часы если сменилось на 1 цифру
  //TempToDallasArray();                      // температура с DALLAS DS18B20
  TempToArray();                            // температура BME280
  HumidityToArray();                        // если будет влажность BME280
  PressureToArray();                        // давление BME280
  TempHomeToArray();                        // температура дома с RTC_DS3231
  DayMonthToArray() ;                       // Проверяем день и число
  FastLED.show();                           // Задаём массив светодиодов
 // if (TempShowDallas == true) delay (4000); //время показа температуры с DALLAS DS18B20
  if (TempShow == true) delay (4000);       //время показа температуры с BME
  if (HumidityShow == true) delay (4000);   //время показа влажности
  if (PressureShow == true) delay (4000);   //время показа давления
  if (TempHomeShow == true) delay (4000);   //время показа температуры с RTC
  if (DayMonthShow == true) delay (4000);   //время показа даты

    
/* 
//=================================== Вывод информации в сом порт =============================================

  // Раскомvентировать если нужно посмотреть в сом порте, маленько подтормаживает вся система если это открыто
    Serial.print("Tемпература = ");
    Serial.print(bme.readTemperature());  //Serial.print(bmp.readTemperature());
    Serial.println("*C");
    
    Serial.print ("Давление = ");
    Serial.print (bme.readPressure() / 133.322);  //Serial.print (bmp.readPressure() / 133.322); // Полученное значение в Па делим на 133,322 и получаем мм.рт.ст.
    Serial.println (" mm"); // и соответственно меняем "Pa" на "mm"

    Serial.print ("Влажность = ");
    Serial.print (bme.readHumidity() ); // Serial.print (dht.readHumidity() ); //
    Serial.println ("%\t"); //
    Serial.println();
    delay(5000);

    Serial.println (" *ПЕТРОВИЧ* "); //
*/   
}
 

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
132
9
УРРРААА, получилось, спасибо ASM за его терпение!!!!
я не гонюсь за простотой, главное чтоб надежнее срабатывало. Функция обнуления насколько я понял работает не по фронту а по срезу импульса, т.е. секунды обнуляются не в момент нажатия на кнопку а в момент ее отжатия (размыкания) проверено зажимом кнопки на 2 секунды, в результате смена цета происходит не на 60 секунде а на второй, но это мелочи, можно привыкнуть. спасибо!!!

Перестановка отображаемых параметров осуществляется изменением значений "на какой секунде отображать"
C++:
if (tm.Second != 8) {
if (tm.Second != 16) {
if (tm.Second != 24) {
 
Изменено:

maksland

★★★✩✩✩✩
13 Янв 2019
463
105
Omsk
дико извиняюсь... это скетч для каких часов ? для какого расположения светодиодов ?
 

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
132
9
дико извиняюсь... это скетч для каких часов ? для какого расположения светодиодов ?
часы скетч из #482 код , ссылка , на тот момент времени уважаемый kym13 переделывал скетч (чей не скажу) на предмет гашения верхней точки двоеточия при отображении даты и отключил незначащие нули теперь в этот (уже переделанный) скетч добавлена кнопка обнуления секунд. В начале скетча назначение кнопки в комментариях еще не описано, кнопка подключается к pin D7 и GND схема расположения светодиодов
 
Изменено:

maksland

★★★✩✩✩✩
13 Янв 2019
463
105
Omsk
а.. понятно, а мы ждём Вячеслава :) когда ему датчик давления привезут. Я тоже два штуки заказал по 100 рублей но где то в недрах почты сгинули...надеюсь не на совсем
корпус наверное всё - буду печатать настенно-настольный вариант, продумать только где кнопки и провода вводить и выводить
 

Вложения

Изменено:

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
132
9
обратите внимание на строку 006 в коде
C++:
// Температура
void TempToArray() {               // вывод температуры с BME
  tmElements_t tm;
  RTC.read(tm);
  if (tm.Second != 16) {           //через какое время показывать температуру
    TempShow = false;
    return;
 

Александр Злюс

✩✩✩✩✩✩✩
10 Фев 2020
19
1
друзья помогите добавить белый цвет в прошивке последней от вячаслава на часы .




версия 1,8 часы:
// Часы на WS2812
// Версия 1.8
// Дата написания 23.04.2021
// Сборка проршивки [email protected]

/* Последоватеольность соединения сигментов индикатора 
   {G B A F E D C} {G B A F E D C} {верхняя точка} {нижняя точка} {G B A F E D C} {G B A F E D C}
   Количество светодиодов светодиодов выберается относительно количества светотдиодов на сегмент
   При первом запуске выбрать режим "----" для обнуления памяти
ВОЗМОЖНОСТИ
  Отображают время, температуру, дату, 255 цетов (смена каждую минуту)
  В режиме часов нажатие на "+" отображает температуру, а на "-" дату
  Цвет отображении температуры изменяется от температуры

/* ИЗМЕНЕНИЯ *поправил смену цвета
добавил настройку задержку анимации пока с ограничением в 30 миллисекунд


НАСТРОЙКИ в часах (листаются кнопкой "настройки" по кругу) менять кнопками "+" и "-":
1.  (H) установка часов 0...23
2.  (A) установка минут 0...59
3.  (S) сброс секунд на 0 кнопками ("+" - сбрасывает сек. на 0 добавляет 1 мин.) или ("-" - сбрасывает сек. на 0)
4.  (d) установка дня 1...31
5.  (b) установка месяца 1...12
6.  (отображается полностью) установка года
7.  (C) настройка цвета (если 00 то автоматическая) 0...25
8.  (L) настройка яркости (если 00 то автоматическая) 0...25
9.  (t) включение датчиков температуры (0 - комнатный, 1 - уличный, 2 - оба)
10. (tt) установка времени отображения температуры 0...5 сек.
11. (td) установка времени отображения даты 0...5 сек.
12. (SH) установка отображениея анимации при смене минут (0 - отк. 1 - вкл.)
13. (tH) установка количества отображения температуры и даты в минуту 1...6 раз (период 60,30,20,15,12,10 сек. соответственно)
14. (----) сброс настроек кнопками "+" или "-"
*/
#include <DS3232RTC.h>
#include <FastLED.h>
#include <EEPROMex.h>
#include <microDS18B20.h>

// Настройки пинов подключения к Ардуино +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define DATA_PIN 6                 // pin вывод данных на светодиоды
#define LIGHT_PIN A0               // pin датчика освещенности
#define TEMP_INSIDE_PIN 10         // pin комнатного датчика температуры DS18B20 только плюсовая до десятых
#define TEMP_OUTSIDE_PIN 11        // pin уличного датчика температуры DS18B20 плюсовая и минусовая до целых
#define PIN_UP 3                   // pin кнопки прибавить
#define PIN_ST 4                   // pin кнопки выбор
#define PIN_DW 5                   // pin кнопки убавить
// Настройки +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define LED_TYPE WS2812            // Тип светодиодов (WS2812, WS2811 и т.д.)
#define COLOR_ORDER GRB            // Порядок цветов (если при включении часы не красные менять буквы местами)
#define SEGMENT_LEDS 1             // Количество светодиодов на сегмент (точки по 1 светодиоду)
#define LIGHT_MIN 4                // Минимальный уровень яркости (0...255) должно быть меньше максимального
#define LIGHT_MAX 250              // Максимальный уровень яркости (0...255) должно быть больше минимального
#define TIME_EXIT 4                // Время выхода из меню после последнего нажатия кнопок (секунд)
#define ANIME_DELAY 20             // Замедление анимации при смемене цвета в миллисекундах (не более 30)
// Настройки отображения температуры ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define TEMP_INSIDE 10             // Знак градусов комнатной температуры  (10 - "0" 11 - "С")
#define TEMP_OUTSIDE 10            // Знак градусов уличной температуры  (10 - "0" 11 - "С")
#define TEMP_INSIDE_COLOR 1        // Вариант цвета комнатной (0 - как часы, 1 - кр-ор-ж-зел-гол-с, 2 - кр-роз-фиол-с)
#define TEMP_OUTSIDE_COLOR 1       // Вариант цвета уличной (0 - как часы, 1 - кр-ор-ж-зел-гол-с, 2 - кр-роз-фиол-с)
#define TEMP_INSIDE_MIN 20         // Минимальная комнатная температура (отображается синим)
#define TEMP_INSIDE_MAX 30         // Максимальная комнатная температура (отображается красным)
#define TEMP_OUTSIDE_MIN -20       // Минимальная уличная температура (отображается синим)
#define TEMP_OUTSIDE_MAX 35        // Максимальная уличная температура (отображается красным)
// Defauil настройки в часах устанавливаются режимом "----" +++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define TIME_TEMP 4                // Установка времени отображения температуры 0...5 секунд (0 - отк.)
#define TIME_DATE 0                // Установка времени отображения даты 0...5 секунд (0 - отк.)
#define SET_COLOR 0                // Настройка цвета (если 0 то автоматическая) 0...20
#define SET_LIGHT 0                // Настройка яркости (если 0 то автоматическая) 0...25
#define SET_TEMPS 2                // Включение отображения температуры (0 - комнатный, 1 - уличный, 2 - оба)
#define SET_SHOWS 1                // Включение отображения анимации при смене минут (0 - отк. 1 - вкл.)
#define TIME_TIME 3                // Установка количества отображения температуры и даты в минуту 1...6 раз
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

MicroDS18B20 sensor1(TEMP_INSIDE_PIN);
MicroDS18B20 sensor2(TEMP_OUTSIDE_PIN);
#define NUM_LEDS ((SEGMENT_LEDS * 28) + 2)
#define POINT_UP (14 * SEGMENT_LEDS)
#define POINT_DW ((14 * SEGMENT_LEDS) + 1)
CRGB leds[NUM_LEDS];
CRGB temp_color;
CRGB led_color;

byte digits[21] = {0b01111110,  // 0   
                   0b01000010,  // 1
                   0b00110111,  // 2
                   0b01100111,  // 3
                   0b01001011,  // 4
                   0b01101101,  // 5
                   0b01111101,  // 6
                   0b01000110,  // 7
                   0b01111111,  // 8
                   0b01101111,  // 9   
                   0b00001111,  // º 10
                   0b00111100,  // C 11
                   0b01011011,  // H 12
                   0b01011111,  // A 13
                   0b01101101,  // S 14
                   0b00000001,  // - 15
                   0b01110011,  // d 16
                   0b01111001,  // b 17
                   0b00000000,  //   18
                   0b00111001,  // t 19 
                   0b00111000}; // L 20 
 
boolean eeprom_flag;
boolean temp_flag = false;
boolean read_eeprom = true;
boolean mode_flag = true;
unsigned long key_pressed;
unsigned long t;
byte color;
byte old_color = 0;
byte mode = 55;     // Режим работы
byte brightness;    // Яркость
byte znak;          // Для вывода знака минуса
byte points = 0;    // Состотяние точек
byte figure[4];     // Цыфры часов
byte setups[8];     // 0, TIME_TEMP, TIME_DATE, SET_COLOR, SET_LIGHT, SET_TEMPS, SET_SHOWS, TIME_TIME
int temp1;          // Комнатная температура
int temp2;          // Уличная температура
int time_tp;        // Промежуточное время вывода температуры

class button {      // Работа с кнопками
  public:
    button (byte pin) {
    _pin = pin;
    pinMode(_pin, INPUT_PULLUP);}
    static byte key;
  boolean click() {
    boolean btnState = digitalRead(_pin);
    if (!btnState && !_flag && millis() - _tmr >= 100) {
       _flag = true;
       key = true;
       _tmr = millis();
       return true;}
    if (!btnState && _flag && millis() - _tmr >= 400) {
       _tmr = millis ();
       key = true;
       return true;}
    if (btnState && _flag) {
       _flag = false;
       key = false;
       _tmr = millis();}
    return false;}
  private:
    byte _pin;
    uint32_t _tmr;
    boolean _flag;};

button up(PIN_UP);
button st(PIN_ST);
button dw(PIN_DW);
byte button::key;

void setup(){
  LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); // Установить тип светодиодной ленты
  figure[0] = 0;
  figure[1] = 7 * SEGMENT_LEDS;
  figure[2] = (14 * SEGMENT_LEDS) + 2;
  figure[3] = (21 * SEGMENT_LEDS) + 2;
  t = millis();}
// END setup

void BrightnessCheck(){   // Установка яркости по датчику освещенности
  if (setups[4] == 0) brightness = map(analogRead(LIGHT_PIN), 0, 1023, LIGHT_MIN, LIGHT_MAX);
  else brightness = setups[4] * 10;
  LEDS.setBrightness(brightness);} 

void TempColor(byte set_sh, int temp_x, int temp_min, int temp_max){ // Функция изменения цвета от температуры
  byte sum_color;
  if (set_sh == 0) temp_color = led_color;
  if (temp_x < temp_min * 10) temp_x = temp_min * 10;
  if (temp_x > temp_max * 10) temp_x = temp_max * 10;
  if (set_sh == 1) sum_color = map(temp_x, temp_min * 10, temp_max * 10, 170, 0);
  if (set_sh == 2) sum_color = map(temp_x, temp_min * 10, temp_max * 10, 170, 255);
    temp_color = CHSV(sum_color, 255, 255);}

void DigitOut(byte digit_1, byte digit_2, byte digit_3, byte digit_4, byte point, CRGB d_color){  // Функция вывода на диоды
  byte digit[4] = {digit_1, digit_2, digit_3, digit_4};
  for (byte s = 0; s <= 3; s++){
  byte cursor = figure[s];
  for(byte k = 0; k <= 6; k++){
    for(byte i = 1; i <= SEGMENT_LEDS; i++){
    if ((digits[digit[s]] & 1 << k) == 1 << k)
           leds[cursor] = d_color;
      else leds[cursor] = 0x000000;
      cursor++;}}}
         if (point == 0){leds[POINT_DW] = 0x000000; leds[POINT_UP] = 0x000000;}
    else if (point == 1){leds[POINT_DW] = d_color; leds[POINT_UP] = 0x000000;}
    else if (point == 2){leds[POINT_DW] = d_color; leds[POINT_UP] = d_color;}}

int PressingButton(byte variable, byte var_min, byte var_max){  // Функция работы кнопок + и -
  if (up.click())   { //увеличиваем
     if (variable == var_max) variable = var_min; else variable += 1;}
  if (dw.click())   { //уменьшаем
     if (variable == var_min) variable = var_max; else variable -= 1;}
  return variable;}

void Animate(int v) {    // Функция анимации
  static uint8_t hue = 0;
  leds[v] = CHSV(hue++, 255, 255);
  FastLED.show();
  for(byte m = 0; m < NUM_LEDS; m++) {
  leds[m].nscale8(250);}
  delay(ANIME_DELAY / SEGMENT_LEDS);}

void Animation() {  // Фунция анимации при смене минуты
  for(int i = 0; i < NUM_LEDS; i++) Animate(i);
  for(int i = NUM_LEDS - 1; i >= 0; i--) Animate(i);}

// Работа с памятью ===============================================================================================

void ReadEEPROM() {      // Чтение
  for (byte i = 1; i <= 7; i++) setups[i] = EEPROM.readByte(i);
  read_eeprom = false;}

void UpdateEEPROM() {    // Запись
  for (byte i = 1; i <= 7; i++) EEPROM.updateByte(i, setups[i]);}

void EepromTick() {      // Проверка
  if (eeprom_flag && mode_flag){
   for (byte i = 1; i <= 7; i++){
   if (setups[i] != EEPROM.readByte(i)){
     UpdateEEPROM();
     break;}}
     eeprom_flag = false;}}
    
void(* resetFunc) (void) = 0; // Функция перезагрузкки МК.

void ResetClock(){       // Сброс на настройки по умолчанию
  byte def_setup[8] = {0, TIME_TEMP, TIME_DATE, SET_COLOR, SET_LIGHT, SET_TEMPS, SET_SHOWS, TIME_TIME};
   // setups[i]  i  =  _      1          2         3          4          5          6           7
  for (byte i = 1; i <= 7; i++) EEPROM.updateByte(i, def_setup[i]);
  delay(100);
  resetFunc();}

// ==================================================================================================================

void loop(){         // Основной цикл -------------------------------------------------------------------------------
if (read_eeprom) ReadEEPROM();
BrightnessCheck();      // Проверка яркости
time_t tm = RTC.get();  // Получение времени
tmElements_t Now;

 if (mode == 0){   
    Now.Hour = hour(tm);
    Now.Minute = minute(tm);
    Now.Second = second(tm);
    Now.Day = day(tm);
    Now.Month = month(tm);
    Now.Year = year(tm) - 1970;}
 
  if (mode < 20 && mode != 0 && (millis() - key_pressed) > (TIME_EXIT * 1000)) mode = 0; // Переход в режим часов
    
  if ((mode == 0 && up.click()) || (setups[1] != 0 && mode == 0 && (second(tm) % (60 / setups[7]) == 0))) { // Переход в режим запроса температуры
    sensor1.requestTemp();
    sensor2.requestTemp();
    temp_flag = true;   
    t = millis();
     if (setups[1] == 0) time_tp = 2000;
     else if (setups[5] == 2) time_tp = setups[1] * 500;
     else time_tp = setups[1] * 1000;}
 
  if (temp_flag && mode == 0 && millis() - t > 2000) {  // Запрос температуры
    temp_flag = false;
    t = millis();
    temp1 = 10 * sensor1.getTemp();
    temp2 = 10 * sensor2.getTemp();
    if (setups[5] == 0 || setups[5] == 2) mode = 20;
    else if (setups[5] == 1) mode = 21;}
    
  if ((mode == 0 && dw.click()) || (setups[1] == 0 && setups[2] != 0 && mode == 0 && (second(tm) % (60 / setups[7]) == 0))) { // Переход в режим даты
    t = millis();
    mode = 25;}
    
  if (mode < 20 && st.click()){                   // если нажата кнопка 2, то гоняем меню по кругу
    if (mode == 14) mode = 0; else mode++;}   
 
  if (mode < 20 && button::key) {           // Отслеживание нажатия любой кнопки
      key_pressed = millis();
    if (mode >= 7 && mode <= 14) {
      eeprom_flag = true;
      mode_flag = false;}}
   if (second(tm) == 2) old_color = color;   
// ------------------------------------------   switch   -----------------------------------
  switch (mode) {
    case 0: {             // Нормальный режим отображение времени
           if (second(tm) == 0) {
            if (setups[3] == 0) {
            while (abs(color - old_color) < 25) color = random8();
            led_color = CHSV(color, 255, 255);}
            else led_color = CHSV(setups[3] * 10, 255, 255);
            if (setups[6] == 1) Animation();}
          if (second(tm) % 2 == 0) points = 2; else points = 0;
        DigitOut(hour(tm) / 10, hour(tm) % 10, minute(tm) / 10, minute(tm) % 10, points, led_color);
        mode_flag = true;
        break;}                                           
    
    case 1: {             // Режим установки часов
        Now.Hour = PressingButton(Now.Hour, 0, 23);
          if (Now.Hour != hour(tm)) RTC.write(Now);
        DigitOut(12, 15, Now.Hour / 10, Now.Hour % 10, 0, led_color);
        break;}
    
    case 2: {             // Режим установки минут
        Now.Minute = PressingButton(Now.Minute, 0, 59);
          if (Now.Minute != minute(tm)) RTC.write(Now);
        DigitOut(13, 15, Now.Minute / 10, Now.Minute % 10, 0, led_color);
        break;}
    
    case 3: {             // Режим установки секунд
        if (up.click())   { //обнуляем секунды + 1 минута
         Now.Second = 0;
         Now.Minute = Now.Minute + 1;
         RTC.write(Now);}
        if (dw.click())   { //обнуляем секунды
         Now.Second = 0;
         RTC.write(Now);}
         key_pressed = millis();     
         DigitOut(14, 15, second(tm) / 10, second(tm) % 10, 0, led_color);
       break;}

    case 4: {             // Режим установки дня
        Now.Day = PressingButton(Now.Day, 1, 31);
          if (Now.Day != day(tm)) RTC.write(Now);
        DigitOut(16, 15, Now.Day / 10, Now.Day % 10, 0, led_color);
        break;}
    
    case 5: {             // Режим установки месяца
        Now.Month = PressingButton(Now.Month, 1, 12);
         if (Now.Month != month(tm)) RTC.write(Now);
        DigitOut(17, 15, Now.Month / 10, Now.Month % 10, 0, led_color);
        break;}

    case 6: {             // Режим установки года
        Now.Year = PressingButton(Now.Year, 50, 99);
          if (Now.Year != year(tm)) RTC.write(Now);
        DigitOut(2, 0, ((Now.Year - 30) / 10) % 100, ((Now.Year - 30) % 10), 0, led_color);
        break;}
        
    case 7: {             // Режим установки цвета
        setups[3] = PressingButton(setups[3], 0, 25);
          if (setups[3] > 0) led_color = CHSV(setups[3] * 10, 255, 255);
        DigitOut(11, 15, setups[3] / 10, setups[3] % 10, 0, led_color);
        break;}

    case 8: {             // Режим установки яркости
        setups[4] = PressingButton(setups[4], 0, 25);
        DigitOut(20, 15, setups[4] / 10, setups[4] % 10, 0, led_color);
        break;}
        
    case 9: {             // Режим установки датчиков температуры
        setups[5] = PressingButton(setups[5], 0, 2);
        DigitOut(18, 19, 15, setups[5], 0, led_color);
        break;}
          
    case 10: {             // Режим установки времени отображения температуры
        setups[1] = PressingButton(setups[1], 0, 5);
        DigitOut(19, 19, 15, setups[1], 0, led_color);
        break;}

    case 11: {            // Режим установки времени отображения даты
        setups[2] = PressingButton(setups[2], 0, 5);
        DigitOut(19, 16, 15, setups[2], 0, led_color);
        break;}

    case 12: {             // Режим установки отображения анимации при смене минут
        setups[6] = PressingButton(setups[6], 0, 1);
        DigitOut(14, 12, 15, setups[6], 0, led_color);
        break;}

    case 13: {            // Режим установки количества отображения часов
        setups[7] = PressingButton(setups[7], 1, 6);
        DigitOut(19, 12, 15, setups[7], 0, led_color);
        break;}
    
    case 14: {            // Режим сброса
        if (up.click() || dw.click())   {
          ResetClock();}
          DigitOut(15, 15, 15, 15, 0, led_color);
        break;}
          
    case 20: {            // Режим вывода температуры внутри
      TempColor(TEMP_INSIDE_COLOR, temp1, TEMP_INSIDE_MIN, TEMP_INSIDE_MAX);
      if (temp1 < 100) DigitOut(18, (temp1 % 100) / 10, temp1 % 10, TEMP_INSIDE, 1, temp_color);
      else DigitOut(temp1 / 100, (temp1 % 100) / 10, temp1 % 10, TEMP_INSIDE, 1, temp_color);
        if (millis() - t > time_tp) {
          if (setups[5] == 2) {
            mode = 21;
            t = millis();}
          else if (setups[2] != 0) mode = 25;
          else mode = 0;}
      break;}

    case 21: {            // Режим вывода температуры без десятых уличной
       if (temp2 < 0) znak = 15;
       else znak = 18;   
       TempColor(TEMP_OUTSIDE_COLOR, temp2, TEMP_OUTSIDE_MIN, TEMP_OUTSIDE_MAX);
       if (abs(temp2) < 100) DigitOut(18, znak, (abs(temp2) % 100) / 10, TEMP_OUTSIDE, 0, temp_color);
       else DigitOut(znak, abs(temp2) / 100, (abs(temp2) % 100) / 10, TEMP_OUTSIDE, 0, temp_color);
     if (millis() - t > time_tp) {
       if (setups[2] != 0) {
          mode = 25;
          t = millis();}
       else mode = 0;}
      break;}

    case 25: {            // Режим вывода даты
          DigitOut(day(tm) / 10, day(tm) % 10, month(tm) / 10, month(tm) % 10, 1, led_color);
        if (setups[2] == 0 && millis() - t > 2000) mode = 0;
        else if (setups[2] != 0 && millis() - t > (setups[2] * 1000)) mode = 0;
      break;}

    case 55: {            // Режим вывода версии проошивки
          led_color = 0xFF0000;
          DigitOut(15, 1, 8, 15, 1, led_color);
        if (millis() - t > 3000) mode = 0;
      break;}
  }                       // Конец switch
EepromTick();     // Проверка на сохранение в пямать
FastLED.show();   // Вывод на диоды
}
// END. -----------------------------------------------------------------------------------------------------------
 

maksland

★★★✩✩✩✩
13 Янв 2019
463
105
Omsk
ну ... в меню можно выбрать фиксированный цвет
7. (C) настройка цвета (если 00 то автоматическая) 0...25
один из них точно белый