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

PareNN

✩✩✩✩✩✩✩
25 Дек 2020
4
0
сколько платите? :)
Наверное придется все самому доделавать! Просто esp8266 намного лучше подходит для часов при стоимости как ардуино нано. Просто посмотрел версию 1.7 бета - написано что 2 датчика температуры, посмотрел код - фик там только 1.
 

bort707

★★★★★★✩
21 Сен 2020
3,298
958
посмотрел версию 1.7 бета - написано что 2 датчика температуры, посмотрел код - фик там только 1.
потенциально там заложено два, а дальше кому сколько надо - столько и делает.

Переделка на 8266 - вещь несложная... когда знаешь. Но в любом случае переписывание кода и его тестирование на другом чипе требует приличного времени, превышающего порог простой помощи на форуме.
Поэтому тут или делаете сами, или заказываете
 

PareNN

✩✩✩✩✩✩✩
25 Дек 2020
4
0
Понимаю что переделка не сложная - если занимаешься постоянно. Алгоритм остается такой же, только переделать чтение-запись в память и получение времени по ntp. Время, а время деньги - понимаю. Выкрою время по возможности попробую сам все сделать, спасибо!
 

PareNN

✩✩✩✩✩✩✩
25 Дек 2020
4
0
Спасибо, значит только со временем останется погулять и с подключением к WIFI роутеру.
 

maksland

★★★✩✩✩✩
13 Янв 2019
616
145
Omsk
8266 одобряю , только RTC оставить тоже надо а то не всегда wifi стабильный может и тем более 24/7 быть
для настройки можно wifi использовать если часы высоко будут
и по wifi синхронизацию делать раз в час например
 

bort707

★★★★★★✩
21 Сен 2020
3,298
958
8266 одобряю , только RTC оставить тоже надо а то не всегда wifi стабильный
RTC в первую очередь нужен для того, чтобы часы не сбивались при отключении питания. А так то внутренний таймер вполне пригоден для отсчета времени между синхронизациями и без RTC
 

maksland

★★★✩✩✩✩
13 Янв 2019
616
145
Omsk
те пока wifi не подрубишь, с телефона например, часы будут показывать всё что угодно :)
у нас в деревне часто свет рубят :(
 

stranic123

✩✩✩✩✩✩✩
17 Июл 2019
4
0
Привет всем! Парни кто может подключить датчик DS18B20 в версии часов 1.7 как я понял там надо что-то дописать в коде который на pin 10 и можно-ли сделать что-бы переход радуги был не каждую минуту а каждый час я очень слаб в программировании.
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@stranic123,он там же подключен) Неужели запятые сложно поставить, как это безобразие прочитать?)

это как раз можно не переделывать - насколько я помню, для 8266 есть библиотека с эмуляцией EEPROM, основной код можно не трогать
подробности кто нашел?)
собирался на НГ праздниках заняться 8266, но не добрался)
вначале начал смотреть, нужно менять библиотеки, с nano не подходят под 8266)
 
Изменено:

suhorukov-p

✩✩✩✩✩✩✩
16 Фев 2019
39
6
Всем привет!!! Наконец то я добрался до своих часиков))) Перепрошил их на 2 датчика температуры. Часы работаю без глюков,с Сентября 2020 года. температуру показывают как нужно. Коллеги по работе уже к ним привыкли и понимают отлично, что первое показание дома, а второе на улице.

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

maksland

★★★✩✩✩✩
13 Янв 2019
616
145
Omsk
эх... раскрашивать бы температуру по цвету "-" синим а "+" красным
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
Поправленный вариант без новогоднего режима, удалил в нем ненужное)
Часы, уличный датчик на DS18B20, внутри BMP280 для температуры и давления.
C++:
#include <DS3232RTC.h>
#include <FastLED.h>
#include <microDS18B20.h>
MicroDS18B20 sensors(2);
#include <iarduino_Pressure_BMP.h>
iarduino_Pressure_BMP 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), чем больше - тем медленнее меняется яркость
int new_bright, new_bright_f;
#define auto_bright 1         // автоматическая подстройка яркости от уровня внешнего освещения (1 - включить, 0 - выключить)
unsigned long bright_timer, off_timer;


#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]; // Define LEDs strip

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
  0b00011110,     // Digit C         11
  0b01111100,     // Digit P         12
  0b00000000,     // Blank           13
  0b01000000      // Digit -         14
};

bool Dot = true;  //переменная для точек
//bool TempShow = true;  //переменная для температуры
//bool PressShow = true; //переменная для давления
int last_digit = 0;
byte set_light;
byte brightness;
unsigned long Timer;

//управление цветом
//int ledColor = 0x00FFFF; // Color used (in hex)
//long ledColor = CRGB::Blue; // Color used (in hex)
CRGB ledColor = CRGB::Blue; // Color used (in 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);
  FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS);
  pinMode(MIN_PIN, INPUT_PULLUP); // Define Minutes adjust button pin
  pinMode(HUR_PIN, INPUT_PULLUP); // Define Hours adjust button pin

  pinMode(A3, OUTPUT); //контакт GND барометра
  digitalWrite(A3, LOW);//подача земли на барометр

  pinMode(9, OUTPUT); //контакт VCC датчика осв
  digitalWrite(9, HIGH);//подача питания на датчик осв
}

int GetTime() {
  tmElements_t Now;
  RTC.read(Now);
  int hour = Now.Hour;
  int minute = Now.Minute;
  int second = Now.Second;
  Serial.print(hour);   Serial.print(":");  // Вывод часов
  Serial.print(minute); Serial.print(":");  // Вывод минут
  Serial.print(second); Serial.println(""); // Вывод секунд
  Dot = second % 2;
  return (hour * 100 + minute);
};

void BrightnessCheck() {
  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(); // Получаем время
  Dots(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 -= DOTS_NUM;
    }
    if ( i == 4 & digit == 0)Digit(digits[13], cursor); //Если впереди ноль, то выключаем его
    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 (boolean Dot_On) {
  leds[56] = (Dot_On) ? ledColor : CRGB (0,0,0);
  leds[57] = (Dot_On) ? ledColor : CRGB (0,0,0);
}

void TempStreetToArray() {
  sensors.requestTemp();
  int celsius = sensors.getTemp();
  Serial.println (celsius);
  Dots(0);
 
  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[13], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); //Если впереди ноль, то выключаем его
  else
    Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - 2));
    
  if (sensors.getTemp() <= -1)Digit(digits[14], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM));//если < или = -1, то показываем -
  else
    Digit(digits[13], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); //иначе выключаем

};

void TempToArray() {
  sensor.begin();
  int celsius = sensor.temperature - 1; // датчик за часами, часы на стене, там температура чуть выше
  Serial.println (celsius);
  Dots(0);
  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[13], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM)); //Если впереди ноль, то выключаем его
  else
    Digit(digits[digit], (NUM_LEDS - LEDS_IN_SEGMENT * 21 - DOTS_NUM));
  Digit(digits[13], (NUM_LEDS - LEDS_IN_SEGMENT * 28 - DOTS_NUM)); //отключаем
};

void PressToArray() {
  sensor.begin();
  int davlenie = sensor.pressure;
  Serial.println (davlenie);
  Dots(0);
  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[13], (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;
    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 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(){
  static byte key =0;
  BrightnessCheck();
  TimeAdjust();

    if ((millis() - Timer <= 5000) && (key ==0))
      TimeToArray();FastLED.show();key++;
    if ((millis() - Timer <= 7000) && (millis() - Timer > 5000)&& (key ==1))
      TempToArray();FastLED.show();key++;
    if ((millis() - Timer <= 9000) && (millis() - Timer > 7000)&& (key ==2))
      TempStreetToArray();FastLED.show();key++;
    if ((millis() - Timer <= 11000) && (millis() - Timer > 9000)&& (key ==3))
      PressToArray();FastLED.show();key++;
   if ((millis() - Timer <= 13000) && (millis() - Timer > 11000)&& (key ==4))
      Timer = millis();key==0;
}
Поднимаю вопрос с millis, при показе часов мигают как-то не в такт.
Раньше было на задержках, все было норм, но только время нельзя было корректировать в любой момент, пока не пройдут все задержки...
Где может быть проблема?)
 

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

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

А вообще молодец, добился чего хотел!
 

kym13

★★★✩✩✩✩
14 Ноя 2020
716
118
Здравствуйте. Собрал часы на скетче из 89 поста на BME280 и модуле фоторезистора с алиэкспресс, всё работает, но как всегда есть "но". Автоматическая регулировка яркости работает наоборот т.е. когда становиться темно яркость прибавляется, когда светло уменьшается. Поскольку я в программировании ноль с минусом, то тупо вырезал из скетча найденого в нете блок который отвечает за регулировку и вставил в скетч из поста 89, а родной закоментировал и стало всё работать как надо. Вместо корпуса использовал рамку для фотографий формата А4.1-1.jpg2-2.jpg3-3.jpg4-4.jpg

Замерил потребляемый ток, от 700 до 980 мА в зависимости от цвета при максимальной яркости. Запитал от 2А зарядки для смартфона.
Мой скетч:
 

Вложения

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
Автоматическая регулировка яркости работает наоборот
min и max меняешь местами, посмотрел код, закомментировано немного не то)
в конце видео отчетливо заметны точки, которые передержались)
зачем проверять яркость 10 раз в секунду ?
может тогда запихнуть вызов в функцию с датчиками или часами?
 
Изменено:

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

★★★★★★★
14 Авг 2019
4,322
1,319
Москва
Смотрел раз 5, замедлил до 0.25... ничего отчетливого передержанного не заметил , увы.

Не надо пихать функцию яркости в функцию с датчиками и часами, это логически не верно. Сделай внутри проверку на то, что бы прошло какое то время с последней проверки.
C++:
void test_yarkosti()
{
    static uint32_t last_t=millis();
    if (millis()-last_t)<5000) return;
    last_t=millis();
    /*
    тут остальной код работы с яркостью.
    */
}
 

bort707

★★★★★★✩
21 Сен 2020
3,298
958
а если сделать версию, мигание каждую секунду, что нужно сделать?
точки включили - засекли миллис.
как прошло 1000 ис - выключили. снова засекли...
Опять прошло 1000мс - включили обратно...
и так по кругу.

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

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

★★★★★★★
14 Авг 2019
4,322
1,319
Москва
Да, понял. глянул код.
Значит так. Точки у тебя рисуются функцией Dots, в зависимости от переменной Dot.
Переменная Dot у тебя вычисляется в GetTime() , принимается как остаток от деления секунд на 2, т.е. 0 или 1, вроде бы все нормально.
GetTime вызывается из TimeToArray(), которая в промежуток между 0-5 секундой вызывается опять же с бешеной частотой.

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

И еще , ты тут ничего не напутал?
C++:
if ((millis() - Timer <= 5000) && (key ==0))
      TimeToArray();FastLED.show();key++;
    if ((millis() - Timer <= 7000) && (millis() - Timer > 5000)&& (key ==1))
      TempToArray();FastLED.show();key++;
    if ((millis() - Timer <= 9000) && (millis() - Timer > 7000)&& (key ==2))
      TempStreetToArray();FastLED.show();key++;
    if ((millis() - Timer <= 11000) && (millis() - Timer > 9000)&& (key ==3))
      PressToArray();FastLED.show();key++;
   if ((millis() - Timer <= 13000) && (millis() - Timer > 11000)&& (key ==4))
      Timer = millis();key==0;
Получается что key всегда увеличивается и FastLED.show(); происходит 4 раза за цикл ?
 

bort707

★★★★★★✩
21 Сен 2020
3,298
958
Получается что key всегда увеличивается и FastLED.show(); происходит 4 раза за цикл ?
так и надо. первый раз показывается время, второй температура комнатная, третий - температура уличная... Этот кусок кода АСМ помогал писать я и там все (тогда) было верно :)