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

navangel

✩✩✩✩✩✩✩
11 Янв 2022
13
1
@Leon111_09,у меня 3 на сегмент. Я планировал себе на гараж напротив окна повесить, поэтому нужно что-то влаго-снего-защищенное. Буду экспериментировать с фанерой, стеклом и металлом.
 

lafrof

✩✩✩✩✩✩✩
19 Янв 2022
18
2
ДОБРЫЙ ДЕНЬ!!! Люди добрые подскажите пожалуйста, собираю часы уже задалбался . Во всех скетчах используются другие датчики (у меня имеется nano/DHT11/ds1307/DS18B20) не осталось ли у кого ни будь старых скетчей для этих датчиков, всю бошку себе сломал. Скачал пару десятков скетчей и они все идут на новых датчиках, ковырялся в них ни чего не работает. Или подскажите как переделать (не нужны не какие свистоперделки) часы, температура, снаружи внутри и всё. Заранее ОГРОМНОЕ СПАСИБО!!!!!!!!!!!
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@lafrof, библиотеки нужно заменить, примеров с ds1307 в Гугл полно, немного подкорректировать код только) скетчи с ним должны быть в теме)
 

lafrof

✩✩✩✩✩✩✩
19 Янв 2022
18
2
@ASM, мне ваши часики понравились которые на ардуино на yotube увидел, хотел их воплотить ни чего не получается куча библиотек скачано компилятор постаянно на что то ругается.
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
Examples→RTClib→ds1307
Пример там описан, остальное по аналогии.
Думаю немного упорства и всё заработает.
Также необходимо определиться с прошивкой.
Хотели на все прошивки добавить ссылки в шапку, администрация мне ответила, что не может этого сделать) Обращайтесь к автору... Которого походу давно на форуме нет... Проще создать новую тему)

@lafrof, смотря на что ругается, надо на это смотреть
 

lafrof

✩✩✩✩✩✩✩
19 Янв 2022
18
2
я делал на кухню большие часы года 4 назад, неделю с ними ковырялся но победил. Единственое что меня в них не устроило что минус не показывают +1 или -1 не понятно, а так всё норм с ними
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@lafrof, значит надо подправить код, сложности с минусом нет. В скетчах пример есть. Если температура минус, показать символ минус) В последнем скетче моём точно должно быть это. Чуть выше была ссылка, там всё расписано в коде.
 

lafrof

✩✩✩✩✩✩✩
19 Янв 2022
18
2
@ASM, это было давно, скетч уже не найду, там тоже люди много помогали. в вашем скетче я пробовал менять там тоже ругается то на 1307 то на BMP
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@lafrof, вот пример с ds1302 и с минусом температуры)
C++:
/////////////////////////////////////////////
//#include <DS3232RTC.h> // библиотека часов из менеджера библиотек
#include <iarduino_RTC.h>                                   // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC Now(RTC_DS1302, 10, 12, 11);
#include <FastLED.h>   // библиотека светодиодов из менеджера библиотек
#include <microDS18B20.h> // библиотека уличного датчика https://github.com/AlexGyver/GyverLibs/releases/download/microDS18B20/microDS18B20.zip
MicroDS18B20 sensors(2);  // присваиваем уличному датчику переменную sensors на 2 PIN
#include <iarduino_Pressure_BMP.h>  // библиотека Adafruit_BMP280_Library датчика BMP280 из менеджера библиотек
iarduino_Pressure_BMP sensor(0x76); // присваиваем датчику BMP280 переменную sensor на адресе (0x76)
/////////////////////////////////////////////
#define LEDS_IN_SEGMENT 4     // задаём сколько у нас светодиодов в сегменте
#define DOTS_NUM 2            // задаём сколько у нас разделительных точек
#define NUM_LEDS (LEDS_IN_SEGMENT * 28 + DOTS_NUM) // вычисляем кол-во светодиодов
#define NUM_COLORS 16         // количество цветов
#define COLOR_CHANGE 0        // смена цвета ( 0 - никогда, 1 - раз в минуту, 2 - каждые десять минут, 3 - каждый час, 4 - каждые десять часов)
#define max_bright 255        // максимальная яркость (0 - 255)
#define min_bright 10         // минимальная яркость (0 - 255)
#define bright_constant 1023  // константа усиления от внешнего света (0 - 1023), чем МЕНЬШЕ константа, тем "резче" будет прибавляться яркость
#define coef 0.4              // коэффициент фильтра (0.0 - 1.0), чем больше - тем медленнее меняется яркость
#define auto_bright 1         // автоматическая подстройка яркости от уровня внешнего освещения (1 - включить, 0 - выключить)
/////////////////////////////////////////////
#define COLOR_ORDER GRB  // тип ленты
#define LED_PIN 6  // пин дата от ленты
#define MIN_PIN 5  // пин минутной кнопки
#define HUR_PIN 4  // пин часовой кнопки
#define BRI_PIN A0 // PIN фоторезистора
/////////////////////////////////////////////
CRGB leds[NUM_LEDS];  // определение СД ленты
uint8_t  digits[] = { // определяем символы для отображения
// код начинается с 0b0, далее идут 7 цифр, каждая цифра это номер фрагмента, 1 - включен, 0- отключен
// далее указан получающийся символ и порядковый номер в массиве
  0b00111111,     // Символ 0          0
  0b00100001,     // Символ 1          1
  0b01110110,     // Символ 2          2
  0b01110011,     // Символ 3          3
  0b01101001,     // Символ 4          4
  0b01011011,     // Символ 5          5
  0b01011111,     // Символ 6          6
  0b00110001,     // Символ 7          7
  0b01111111,     // Символ 8          8
  0b01111011,     // Символ 9          9
  0b01111000,     // Символ * градус  10
  0b00011110,     // Символ C         11
  0b00000000,     // Без символа      12
  0b01000000      // Символ -         13
};
/////////////////////////////////////////////
bool Dot = true;    // переменная для точек
int last_digit = 0; // последний символ равен нулю
byte set_light;     // переменная для освещенности
byte brightness;    // переменная для освещенности
int new_bright, new_bright_f; // переменная для освещенности
unsigned long bright_timer, off_timer; // переменная для освещенности
/////////////////////////////////////////////
//управление цветом
//int ledColor = 0x00FFFF;    // цвет в hex
//long ledColor = CRGB::Blue; // цвет в hex
CRGB ledColor = CRGB::Blue;   // цвет в hex
// массив цветов, для рандом при включенном режиме cylon(); ledColor =  ColorTable[random(16)];
CRGB ColorTable[NUM_COLORS] = { // Таблица цветов
  CRGB::Amethyst,
  CRGB::Aqua,
  CRGB::Blue,
  CRGB::Chartreuse,
  CRGB::DarkGreen,
  CRGB::DarkMagenta,
  CRGB::DarkOrange,
  CRGB::DeepPink,
  CRGB::Fuchsia,
  CRGB::Gold,
  CRGB::GreenYellow,
  CRGB::LightCoral,
  CRGB::Tomato,
  CRGB::Salmon,
  CRGB::Red,
  CRGB::Orchid
};
/////////////////////////////////////////////
void setup() { // настройки
  Serial.begin(9600);
  Now.begin();
//  Now.settime(0,45,15,13,3,21,6);
  FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS); // подключение ленты
  pinMode(MIN_PIN, INPUT_PULLUP); // кнопка минутная
  pinMode(HUR_PIN, INPUT_PULLUP); // кнопка часовая
  //ниже я вывел питание на отдельные пины, вы можете питать напрямую от источника питания :)
  pinMode(A3, OUTPUT);   // контакт GND барометра
  digitalWrite(A3, LOW); // подача земли на барометр
  pinMode(9, OUTPUT);    // контакт VCC датчика осв
  digitalWrite(9, HIGH); // подача питания на датчик осв
  pinMode(8, OUTPUT);    // контакт VCC DS1302
  digitalWrite(8, HIGH); // подача питания на DS1302
}
/////////////////////////////////////////////
int GetTime() { // функция времени
//  tmElements_t Now;
Now.gettime();
//  RTC.read(Now);
  int hour = Now.Hours;
  int minute = Now.minutes;
  int second = Now.seconds;
  Serial.print(hour);   Serial.print(":");  // вывод часов
  Serial.print(minute); Serial.print(":");  // вывод минут
  Serial.print(second); Serial.println(""); // вывод секунд
  Dot = second % 2; // точки мигают раз в сек
  return (hour * 100 + minute);
};
/////////////////////////////////////////////
void BrightnessCheck() { // функция освещенности
  static uint32_t last_br = millis();
  if ((millis() - last_br) < 10000) return;
  last_br = millis();
  if (auto_bright) {                         // если включена адаптивная яркость
    if (millis() - bright_timer > 100) {     // каждые 100 мс
      bright_timer = millis();               // сбросить таймер
      new_bright = map(analogRead(BRI_PIN), 0, bright_constant, max_bright, min_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);      // установить новую яркость
    }
  }
};
/////////////////////////////////////////////
void TimeToArray() { // вывод времени на экран
  int Now = GetTime(); // получаем время
  boolean Dots = true; // точки
  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(); // выключение точек
    }
  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) {
        ledColor =  ColorTable[random(NUM_COLORS)];     // случайный цвет из таблицы
      }
      last_digit = digit;
    }
    Now /= 10;
  };
};
/////////////////////////////////////////////
void Dots_off()  { // отключаем точки принудительно, где не нужны
  for (uint8_t i = 0; i < DOTS_NUM; i++) {
leds[(LEDS_IN_SEGMENT * 14)+ i] = 0x000000;
}
}
/////////////////////////////////////////////
void TempStreetToArray() { // вывод уличной температуры на экран
  sensors.requestTemp(); // опрос датчика уличной температуры
  int celsius = sensors.getTemp(); // чтение уличной температуры
  Serial.println (celsius);

  Dots_off(); // выключаем точки

  Digit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7)); // символ градуса

  int digit = abs (celsius % 10);
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));

  digit = abs (celsius / 10);
  if (digit == 0)Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // если впереди ноль, то выключаем его
  else
    Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // иначе показываем как есть

  if (sensors.getTemp() <= -1)Digit(digits[13], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // если < или = -1, то показываем -
  else
    Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // иначе выключаем 1 сегмент
};
/////////////////////////////////////////////
void TempToArray() { // вывод температуры с датчика BMP280 на экран
  sensor.begin();
  int celsius = sensor.temperature - 1; // считываем датчик, датчик за часами, часы на стене, там температура чуть выше, корректировка минус 1
  Serial.println (celsius);

  Dots_off(); // выключаем точки
  Digit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7)); // символ градуса
 
  int digit = abs (celsius % 10);
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));
 
  digit = celsius / 10;
  if (digit == 0)Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // если впереди ноль, то выключаем его
  else
    Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // иначе показываем как есть
    
  Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // отключаем 1 сегмент
};
/////////////////////////////////////////////
void PressToArray() { // вывод давления на экран
  sensor.begin();
  int davlenie = sensor.pressure;
  Serial.println (davlenie);

  Dots_off(); // выключаем точки
 
  int digit = davlenie % 10;
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 7));
 
  digit = davlenie % 100 / 10;
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));
 
  digit = davlenie / 100;
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));
 
  Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // отключаем первый сегмент
};
/////////////////////////////////////////////
void TimeAdjust() { // подстройка времени
  int buttonH = digitalRead(HUR_PIN); // кнопка часы
  int buttonM = digitalRead(MIN_PIN); // кнопка минуты
  if (buttonH == LOW || buttonM == LOW) {
    delay(200);
//    tmElements_t Now;
Now.gettime();
//    RTC.read(Now);
    int hour = Now.Hours;
    int minutes = Now.minutes;
    int second = Now.seconds;
    if (buttonH == LOW) {
      if (Now.Hours == 23) {
        Now.Hours = 0;
      }
      else {
        Now.Hours += 1;
      };
    } else {
      if (Now.minutes == 59) {
        Now.minutes = 0;
      }
      else {
        Now.minutes += 1;
      };
    };
    //RTC.write(Now);
    Now.settime(0, minutes, hour);
  }
}
/////////////////////////////////////////////
void Digit (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 : CRGB (0, 0, 0);
      cursor ++;
    }
  }
}
/////////////////////////////////////////////
void loop() {
  BrightnessCheck();
  TimeAdjust();
  static bool TempShow = true; // флаг для температуры в помещении
  static bool TempSShow = true; // флаг для температуры на улице
  static bool PressShow = true; // флаг для давления
  uint32_t tmrall = millis() % 12000 / 1000;
  static uint32_t tmrall_old = 10000;
  if (tmrall_old != tmrall)
  {
    tmrall_old = tmrall;
    if (tmrall < 6)
    {
      TimeToArray();
      TempShow = true;
      TempSShow = true;
      PressShow = true;
    }
    else if (tmrall < 8)
    {
      if (TempShow)
      {
        TempToArray();
        TempShow = false;
      }
    }
    else if (tmrall < 10)
    {
      if (TempSShow)
      {
        TempStreetToArray();
        TempSShow = false;
      }
    }
    else
    {
      if (PressShow)
      {
        PressToArray();
        PressShow = false;
      }
    }
    FastLED.show(); // команда для включения светодиодов
  };
}
/////////////////////////////////////////////
 
  • Лойс +1
Реакции: lafrof

lafrof

✩✩✩✩✩✩✩
19 Янв 2022
18
2
@lafrof, @ASM, я уже готов плюнуть на комнатную температуру, уличная с минусом и часы ВСЁ. я помню с прошлыми часами переписывал весь масив с количеством светиков мне тогда разжевали как это сделать, сейчас честно уже ни чего не помню. Думал сделаю ха выходные, не тут то было.
 

bort707

★★★★★★✩
21 Сен 2020
3,295
958
@lafrof, раз первая "двойка" показывается верно, значит с этими массивами все ОК и искать ошибку надо в другом месте.

А вообще, выкладывать код фоткой с телефона - этоиздевательство над отвечающим.
 
Изменено:

lafrof

✩✩✩✩✩✩✩
19 Янв 2022
18
2
@bort707,
C++:
#include <DS1307.h>

#include <iarduino_RTC.h>

/////////////////////////////////////////////
#include <DS1307.h> // библиотека часов из менеджера библиотек
#include <iarduino_RTC.h>                                   // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC Now(RTC_DS1307);
#include <FastLED.h>   // библиотека светодиодов из менеджера библиотек
#include <microDS18B20.h> // библиотека уличного датчика https://github.com/AlexGyver/GyverLibs/releases/download/microDS18B20/microDS18B20.zip
MicroDS18B20 sensors(2);  // присваиваем уличному датчику переменную sensors на 2 PIN
#include <iarduino_Pressure_BMP.h>  // библиотека Adafruit_BMP280_Library датчика BMP280 из менеджера библиотек
iarduino_Pressure_BMP sensor(0x76); // присваиваем датчику BMP280 переменную sensor на адресе (0x76)
/////////////////////////////////////////////
#define LEDS_IN_SEGMENT 1     // задаём сколько у нас светодиодов в сегменте
#define DOTS_NUM 2            // задаём сколько у нас разделительных точек
#define NUM_LEDS (LEDS_IN_SEGMENT * 28 + DOTS_NUM) // вычисляем кол-во светодиодов
#define NUM_COLORS 16         // количество цветов
#define COLOR_CHANGE 0        // смена цвета ( 0 - никогда, 1 - раз в минуту, 2 - каждые десять минут, 3 - каждый час, 4 - каждые десять часов)
#define max_bright 255        // максимальная яркость (0 - 255)
#define min_bright 10         // минимальная яркость (0 - 255)
#define bright_constant 1023  // константа усиления от внешнего света (0 - 1023), чем МЕНЬШЕ константа, тем "резче" будет прибавляться яркость
#define coef 0.4              // коэффициент фильтра (0.0 - 1.0), чем больше - тем медленнее меняется яркость
#define auto_bright 1         // автоматическая подстройка яркости от уровня внешнего освещения (1 - включить, 0 - выключить)
/////////////////////////////////////////////
#define COLOR_ORDER GRB  // тип ленты
#define LED_PIN 6  // пин дата от ленты
#define MIN_PIN 5  // пин минутной кнопки
#define HUR_PIN 4  // пин часовой кнопки
#define BRI_PIN A0 // PIN фоторезистора
/////////////////////////////////////////////
CRGB leds[NUM_LEDS];  // определение СД ленты
uint8_t  digits[] = { // определяем символы для отображения
// код начинается с 0b0, далее идут 7 цифр, каждая цифра это номер фрагмента, 1 - включен, 0- отключен
// далее указан получающийся символ и порядковый номер в массиве
  0b00111111,     // Символ 0          0
  0b00100001,     // Символ 1          1
  0b01110110,     // Символ 2          2
  0b01110011,     // Символ 3          3
  0b01101001,     // Символ 4          4
  0b01011011,     // Символ 5          5
  0b01011111,     // Символ 6          6
  0b00110001,     // Символ 7          7
  0b01111111,     // Символ 8          8
  0b01111011,     // Символ 9          9
  0b01111000,     // Символ * градус  10
  0b00011110,     // Символ C         11
  0b00000000,     // Без символа      12
  0b01000000      // Символ -         13
};
/////////////////////////////////////////////
bool Dot = true;    // переменная для точек
int last_digit = 0; // последний символ равен нулю
byte set_light;     // переменная для освещенности
byte brightness;    // переменная для освещенности
int new_bright, new_bright_f; // переменная для освещенности
unsigned long bright_timer, off_timer; // переменная для освещенности
/////////////////////////////////////////////
//управление цветом
//int ledColor = 0x00FFFF;    // цвет в hex
//long ledColor = CRGB::Blue; // цвет в hex
CRGB ledColor = CRGB::Blue;   // цвет в hex
// массив цветов, для рандом при включенном режиме cylon(); ledColor =  ColorTable[random(16)];
CRGB ColorTable[NUM_COLORS] = { // Таблица цветов
  CRGB::Amethyst,
  CRGB::Aqua,
  CRGB::Blue,
  CRGB::Chartreuse,
  CRGB::DarkGreen,
  CRGB::DarkMagenta,
  CRGB::DarkOrange,
  CRGB::DeepPink,
  CRGB::Fuchsia,
  CRGB::Gold,
  CRGB::GreenYellow,
  CRGB::LightCoral,
  CRGB::Tomato,
  CRGB::Salmon,
  CRGB::Red,
  CRGB::Orchid
};
/////////////////////////////////////////////
void setup() { // настройки
  Serial.begin(9600);
  Now.begin();
  Now.settime(0,14,22,23,1,22,6);
  FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS); // подключение ленты
  pinMode(MIN_PIN, INPUT_PULLUP); // кнопка минутная
  pinMode(HUR_PIN, INPUT_PULLUP); // кнопка часовая
  //ниже я вывел питание на отдельные пины, вы можете питать напрямую от источника питания :)
  pinMode(A3, OUTPUT);   // контакт GND барометра
  digitalWrite(A3, LOW); // подача земли на барометр
  pinMode(9, OUTPUT);    // контакт VCC датчика осв
  digitalWrite(9, HIGH); // подача питания на датчик осв
  pinMode(8, OUTPUT);    // контакт VCC DS1302
  digitalWrite(8, HIGH); // подача питания на DS1302
}
/////////////////////////////////////////////
int GetTime() { // функция времени
//  tmElements_t Now;
Now.gettime();
//  RTC.read(Now);
  int hour = Now.Hours;
  int minute = Now.minutes;
  int second = Now.seconds;
  Serial.print(hour);   Serial.print(":");  // вывод часов
  Serial.print(minute); Serial.print(":");  // вывод минут
  Serial.print(second); Serial.println(""); // вывод секунд
  Dot = second % 2; // точки мигают раз в сек
  return (hour * 100 + minute);
};
/////////////////////////////////////////////
void BrightnessCheck() { // функция освещенности
  static uint32_t last_br = millis();
  if ((millis() - last_br) < 10000) return;
  last_br = millis();
  if (auto_bright) {                         // если включена адаптивная яркость
    if (millis() - bright_timer > 100) {     // каждые 100 мс
      bright_timer = millis();               // сбросить таймер
      new_bright = map(analogRead(BRI_PIN), 0, bright_constant, max_bright, min_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);      // установить новую яркость
    }
  }
};
/////////////////////////////////////////////
void TimeToArray() { // вывод времени на экран
  int Now = GetTime(); // получаем время
  boolean Dots = true; // точки
  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(); // выключение точек
    }
  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) {
        ledColor =  ColorTable[random(NUM_COLORS)];     // случайный цвет из таблицы
      }
      last_digit = digit;
    }
    Now /= 10;
  };
};
/////////////////////////////////////////////
void Dots_off()  { // отключаем точки принудительно, где не нужны
  for (uint8_t i = 0; i < DOTS_NUM; i++) {
leds[(LEDS_IN_SEGMENT * 14)+ i] = 0x000000;
}
}
/////////////////////////////////////////////
void TempStreetToArray() { // вывод уличной температуры на экран
  sensors.requestTemp(); // опрос датчика уличной температуры
  int celsius = sensors.getTemp(); // чтение уличной температуры
  Serial.println (celsius);

  Dots_off(); // выключаем точки

  Digit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7)); // символ градуса

  int digit = abs (celsius % 10);
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));

  digit = abs (celsius / 10);
  if (digit == 0)Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // если впереди ноль, то выключаем его
  else
    Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // иначе показываем как есть

  if (sensors.getTemp() <= -1)Digit(digits[13], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // если < или = -1, то показываем -
  else
    Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // иначе выключаем 1 сегмент
};
/////////////////////////////////////////////
void TempToArray() { // вывод температуры с датчика BMP280 на экран
  sensor.begin();
  int celsius = sensor.temperature - 1; // считываем датчик, датчик за часами, часы на стене, там температура чуть выше, корректировка минус 1
  Serial.println (celsius);

  Dots_off(); // выключаем точки
  Digit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7)); // символ градуса
 
  int digit = abs (celsius % 10);
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));
 
  digit = celsius / 10;
  if (digit == 0)Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // если впереди ноль, то выключаем его
  else
    Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // иначе показываем как есть
    
  Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // отключаем 1 сегмент
};
/////////////////////////////////////////////
void PressToArray() { // вывод давления на экран
  sensor.begin();
  int davlenie = sensor.pressure;
  Serial.println (davlenie);

  Dots_off(); // выключаем точки
 
  int digit = davlenie % 10;
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 7));
 
  digit = davlenie % 100 / 10;
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));
 
  digit = davlenie / 100;
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));
 
  Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // отключаем первый сегмент
};
/////////////////////////////////////////////
void TimeAdjust() { // подстройка времени
  int buttonH = digitalRead(HUR_PIN); // кнопка часы
  int buttonM = digitalRead(MIN_PIN); // кнопка минуты
  if (buttonH == LOW || buttonM == LOW) {
    delay(200);
//    tmElements_t Now;
Now.gettime();
//    RTC.read(Now);
    int hour = Now.Hours;
    int minutes = Now.minutes;
    int second = Now.seconds;
    if (buttonH == LOW) {
      if (Now.Hours == 23) {
        Now.Hours = 0;
      }
      else {
        Now.Hours += 1;
      };
    } else {
      if (Now.minutes == 59) {
        Now.minutes = 0;
      }
      else {
        Now.minutes += 1;
      };
    };
    //RTC.write(Now);
    Now.settime(0, minutes, hour);
  }
}
/////////////////////////////////////////////
void Digit (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 : CRGB (0, 0, 0);
      cursor ++;
    }
  }
}
/////////////////////////////////////////////
void loop() {
  BrightnessCheck();
  TimeAdjust();
  static bool TempShow = true; // флаг для температуры в помещении
  static bool TempSShow = true; // флаг для температуры на улице
  static bool PressShow = true; // флаг для давления
  uint32_t tmrall = millis() % 12000 / 1000;
  static uint32_t tmrall_old = 10000;
  if (tmrall_old != tmrall)
  {
    tmrall_old = tmrall;
    if (tmrall < 6)
    {
      TimeToArray();
      TempShow = true;
      TempSShow = true;
      PressShow = true;
    }
    else if (tmrall < 8)
    {
      if (TempShow)
      {
        TempToArray();
        TempShow = false;
      }
    }
    else if (tmrall < 10)
    {
      if (TempSShow)
      {
        TempStreetToArray();
        TempSShow = false;
      }
    }
    else
    {
      if (PressShow)
      {
        PressToArray();
        PressShow = false;
      }
    }
    FastLED.show(); // команда для включения светодиодов
  };
}
/////////////////////////////////////////////
 
  • Лойс +1
Реакции: Khaled

bort707

★★★★★★✩
21 Сен 2020
3,295
958
если на вторую позицию вывести другую цифру, например "0" или "8" - все сегменты горят?
 

bort707

★★★★★★✩
21 Сен 2020
3,295
958
я посмотрел код, что-то с ходу не нашел, что может вызывать такое поведение. Если б вы где-то в коде сдвинули индекс на один - то у вас бы все цифры "поехали", а не только вторая
 
  • Лойс +1
Реакции: lafrof

lafrof

✩✩✩✩✩✩✩
19 Янв 2022
18
2
@bort707, извините что сболомутил вас, светик подвёл. Раньше не сталкивался с таким. Висит две гирлянды по 468 светодиодов на окнах. Светик либо работает либо нет.
 

Вложения

  • Лойс +1
Реакции: bort707

lafrof

✩✩✩✩✩✩✩
19 Янв 2022
18
2
Добрый день подскажите почему кнопки часы, минуты не работают?

C++:
#include <DS1307.h>

#include <iarduino_RTC.h>

/////////////////////////////////////////////
#include <DS1307.h> // библиотека часов из менеджера библиотек
#include <iarduino_RTC.h>                                   // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC Now(RTC_DS1307);
#include <FastLED.h>   // библиотека светодиодов из менеджера библиотек
#include <microDS18B20.h> // библиотека уличного датчика https://github.com/AlexGyver/GyverLibs/releases/download/microDS18B20/microDS18B20.zip
MicroDS18B20 sensors(2);  // присваиваем уличному датчику переменную sensors на 2 PIN
#include <iarduino_Pressure_BMP.h>  // библиотека Adafruit_BMP280_Library датчика BMP280 из менеджера библиотек
iarduino_Pressure_BMP sensor(0x77); // присваиваем датчику BMP280 переменную sensor на адресе (0x76)
/////////////////////////////////////////////
#define LEDS_IN_SEGMENT 1     // задаём сколько у нас светодиодов в сегменте
#define DOTS_NUM 2            // задаём сколько у нас разделительных точек
#define NUM_LEDS (LEDS_IN_SEGMENT * 28 + DOTS_NUM) // вычисляем кол-во светодиодов
#define NUM_COLORS 16         // количество цветов
#define COLOR_CHANGE 0        // смена цвета ( 0 - никогда, 1 - раз в минуту, 2 - каждые десять минут, 3 - каждый час, 4 - каждые десять часов)
#define max_bright 255        // максимальная яркость (0 - 255)
#define min_bright 10         // минимальная яркость (0 - 255)
#define bright_constant 1023  // константа усиления от внешнего света (0 - 1023), чем МЕНЬШЕ константа, тем "резче" будет прибавляться яркость
#define coef 0.4              // коэффициент фильтра (0.0 - 1.0), чем больше - тем медленнее меняется яркость
#define auto_bright 1         // автоматическая подстройка яркости от уровня внешнего освещения (1 - включить, 0 - выключить)
/////////////////////////////////////////////
#define COLOR_ORDER GRB  // тип ленты
#define LED_PIN 6  // пин дата от ленты
#define MIN_PIN 5  // пин минутной кнопки
#define HUR_PIN 4  // пин часовой кнопки
#define BRI_PIN A0 // PIN фоторезистора
/////////////////////////////////////////////
CRGB leds[NUM_LEDS];  // определение СД ленты
uint8_t  digits[] = { // определяем символы для отображения
// код начинается с 0b0, далее идут 7 цифр, каждая цифра это номер фрагмента, 1 - включен, 0- отключен
// далее указан получающийся символ и порядковый номер в массиве
  0b00111111,     // Символ 0          0
  0b00100001,     // Символ 1          1
  0b01110110,     // Символ 2          2
  0b01110011,     // Символ 3          3
  0b01101001,     // Символ 4          4
  0b01011011,     // Символ 5          5
  0b01011111,     // Символ 6          6
  0b00110001,     // Символ 7          7
  0b01111111,     // Символ 8          8
  0b01111011,     // Символ 9          9
  0b01111000,     // Символ * градус  10
  0b00011110,     // Символ C         11
  0b00000000,     // Без символа      12
  0b01000000      // Символ -         13
};
/////////////////////////////////////////////
bool Dot = true;    // переменная для точек
int last_digit = 0; // последний символ равен нулю
byte set_light;     // переменная для освещенности
byte brightness;    // переменная для освещенности
int new_bright, new_bright_f; // переменная для освещенности
unsigned long bright_timer, off_timer; // переменная для освещенности
/////////////////////////////////////////////
//управление цветом
//int ledColor = 0x00FFFF;    // цвет в hex
//long ledColor = CRGB::Blue; // цвет в hex
CRGB ledColor = CRGB::Amethyst;   // цвет в hex
// массив цветов, для рандом при включенном режиме cylon(); ledColor =  ColorTable[random(16)];
CRGB ColorTable[NUM_COLORS] = { // Таблица цветов
  CRGB::Amethyst,
  CRGB::Aqua,
  CRGB::Blue,
  CRGB::Chartreuse,
  CRGB::DarkGreen,
  CRGB::DarkMagenta,
  CRGB::DarkOrange,
  CRGB::DeepPink,
  CRGB::Fuchsia,
  CRGB::Gold,
  CRGB::GreenYellow,
  CRGB::LightCoral,
  CRGB::Tomato,
  CRGB::Salmon,
  CRGB::Red,
  CRGB::Orchid
};
/////////////////////////////////////////////
void setup() { // настройки
  Serial.begin(9600);
  Now.begin();
  Now.settime(0,49,23,23,1,22,6);
  FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS); // подключение ленты
  pinMode(MIN_PIN, INPUT_PULLUP); // кнопка минутная
  pinMode(HUR_PIN, INPUT_PULLUP); // кнопка часовая
  //ниже я вывел питание на отдельные пины, вы можете питать напрямую от источника питания :)
  pinMode(A3, OUTPUT);   // контакт GND барометра
  digitalWrite(A3, LOW); // подача земли на барометр
  pinMode(9, OUTPUT);    // контакт VCC датчика осв
  digitalWrite(9, HIGH); // подача питания на датчик осв
  pinMode(8, OUTPUT);    // контакт VCC DS1302
  digitalWrite(8, HIGH); // подача питания на DS1302
}
/////////////////////////////////////////////
int GetTime() { // функция времени
//  tmElements_t Now;
Now.gettime();
//  RTC.read(Now);
  int hour = Now.Hours;
  int minute = Now.minutes;
  int second = Now.seconds;
  Serial.print(hour);   Serial.print(":");  // вывод часов
  Serial.print(minute); Serial.print(":");  // вывод минут
  Serial.print(second); Serial.println(""); // вывод секунд
  Dot = second % 2; // точки мигают раз в сек
  return (hour * 100 + minute);
};
/////////////////////////////////////////////
void BrightnessCheck() { // функция освещенности
  static uint32_t last_br = millis();
  if ((millis() - last_br) < 10000) return;
  last_br = millis();
  if (auto_bright) {                         // если включена адаптивная яркость
    if (millis() - bright_timer > 100) {     // каждые 100 мс
      bright_timer = millis();               // сбросить таймер
      new_bright = map(analogRead(BRI_PIN), 0, bright_constant, max_bright, min_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);      // установить новую яркость
    }
  }
};
/////////////////////////////////////////////
void TimeToArray() { // вывод времени на экран
  int Now = GetTime(); // получаем время
  boolean Dots = true; // точки
  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(); // выключение точек
    }
  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) {
        ledColor =  ColorTable[random(NUM_COLORS)];     // случайный цвет из таблицы
      }
      last_digit = digit;
    }
    Now /= 10;
  };
};
/////////////////////////////////////////////
void Dots_off()  { // отключаем точки принудительно, где не нужны
  for (uint8_t i = 0; i < DOTS_NUM; i++) {
leds[(LEDS_IN_SEGMENT * 14)+ i] = 0x000000;
}
}
/////////////////////////////////////////////
void TempStreetToArray() { // вывод уличной температуры на экран
  sensors.requestTemp(); // опрос датчика уличной температуры
  int celsius = sensors.getTemp(); // чтение уличной температуры
  Serial.println (celsius);

  Dots_off(); // выключаем точки

  Digit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7)); // символ градуса

  int digit = abs (celsius % 10);
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));

  digit = abs (celsius / 10);
  if (digit == 0)Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // если впереди ноль, то выключаем его
  else
    Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // иначе показываем как есть

  if (sensors.getTemp() <= -1)Digit(digits[13], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // если < или = -1, то показываем -
  else
    Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // иначе выключаем 1 сегмент
};
/////////////////////////////////////////////
void TempToArray() { // вывод температуры с датчика BMP280 на экран
  sensor.begin();
  int celsius = sensor.temperature - 1; // считываем датчик, датчик за часами, часы на стене, там температура чуть выше, корректировка минус 1
  Serial.println (celsius);

  Dots_off(); // выключаем точки
  Digit(digits[10], (NUM_LEDS - LEDS_IN_SEGMENT * 7)); // символ градуса
 
  int digit = abs (celsius % 10);
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));
 
  digit = celsius / 10;
  if (digit == 0)Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // если впереди ноль, то выключаем его
  else
    Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); // иначе показываем как есть
    
  Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // отключаем 1 сегмент
};
/////////////////////////////////////////////
void PressToArray() { // вывод давления на экран
  sensor.begin();
  int davlenie = sensor.pressure;
  Serial.println (davlenie);

  Dots_off(); // выключаем точки
 
  int digit = davlenie % 10;
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 7));
 
  digit = davlenie % 100 / 10;
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 14));
 
  digit = davlenie / 100;
  Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));
 
  Digit(digits[12], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); // отключаем первый сегмент
};
/////////////////////////////////////////////
void TimeAdjust() { // подстройка времени
  int buttonH = digitalRead(HUR_PIN); // кнопка часы
  int buttonM = digitalRead(MIN_PIN); // кнопка минуты
  if (buttonH == LOW || buttonM == LOW) {
    delay(200);
//    tmElements_t Now;
Now.gettime();
//    RTC.read(Now);
    int hour = Now.Hours;
    int minutes = Now.minutes;
    int second = Now.seconds;
    if (buttonH == LOW) {
      if (Now.Hours == 23) {
        Now.Hours = 0;
      }
      else {
        Now.Hours += 1;
      };
    } else {
      if (Now.minutes == 59) {
        Now.minutes = 0;
      }
      else {
        Now.minutes += 1;
      };
    };
    //RTC.write(Now);
    Now.settime(0, minutes, hour);
  }
}
/////////////////////////////////////////////
void Digit (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 : CRGB (0, 0, 0);
      cursor ++;
    }
  }
}
/////////////////////////////////////////////
void loop() {
  BrightnessCheck();
  TimeAdjust();
  static bool TempShow = true; // флаг для температуры в помещении
  static bool TempSShow = true; // флаг для температуры на улице
  static bool PressShow = true; // флаг для давления
  uint32_t tmrall = millis() % 12000 / 1000;
  static uint32_t tmrall_old = 10000;
  if (tmrall_old != tmrall)
  {
    tmrall_old = tmrall;
    if (tmrall < 6)
    {
      TimeToArray();
      TempShow = true;
      TempSShow = true;
      PressShow = true;
    }
    else if (tmrall < 8)
    {
      if (TempShow)
      {
        TempToArray();
        TempShow = false;
      }
    }
    else if (tmrall < 10)
    {
      if (TempSShow)
      {
        TempStreetToArray();
        TempSShow = false;
      }
    }
    else
    {
      if (PressShow)
      {
        PressToArray();
        PressShow = false;
      }
    }
    FastLED.show(); // команда для включения светодиодов
  };
}
/////////////////////////////////////////////