Большие часы на адресных светодиодах 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. Кое-что я перевел для лучшего понимания.

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

Комментарии

kym13

★★✩✩✩✩✩
14 Ноя 2020
446
67
Ещё бы понять где начало ленты, выводящей точки: снизу или сверху?
Вот и я о том же подумал. Когда паял в принципе было без разницы какую точку первую подключать верхнюю или нижнюю. Вообще по схеме сначала первая подключается, ща у себя посмотрю, благо есть табло легко разбирающееся.

Да, слева на право верхняя точка первая.
 

Вложения

  • 300.1 KB Просмотры: 62

bort707

★★★★★★✩
21 Сен 2020
2,904
863
Да, слева на право верхняя точка первая.
ну вот вам тогда
C++:
#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;
}
пример испольхования,
зажечь верхнюю, погасить нижнюю:
C++:
BrightOneDot(UPPER_DOT, 1);
BrightOneDot(LOWER_DOT, 0);
 
Изменено:
  • Лойс +1
Реакции: kym13

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
Поменяете число диодов на сегмент - и все посыпется.
зачем пугаешь людей) тут конкретный пример для конкретного случая вполне достаточен)
для себя тогда поправлю, возможно из-за этого у некоторых траблы с кодом, из-за разного кол-ва СД)

Поправил точки под настройки)
 

Вложения

Изменено:

bort707

★★★★★★✩
21 Сен 2020
2,904
863
возможно из-за этого у некоторых траблы с кодом, из-за разного кол-ва СД
вот именно
написали вам код, не зависимый от числа диодов - а вы его постоянно рушите, добавляя подобные решения "для конкретного случая".
И, главное - ведь совсем нетрудно написать грамотно, никаких особых знаний не надо, только аккуратность.
 

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
написали вам код, не зависимый от числа диодов
изначально делалось все под себя, тут не было активности ранее) этот вариант мне подсказали вроде тут, с тех пор так и работает, подправил код, код уже есть в скетче, только скопировать и перенести в новое место) чуть выше выложил обновление, у меня в часах работает)

P.S. начал кто работать с проектом на ESP?)
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
446
67
ну вот вам тогда
C++:
#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;
}
пример испольхования,
зажечь верхнюю, погасить нижнюю:
C++:
BrightOneDot(UPPER_DOT, 1);
BrightOneDot(LOWER_DOT, 0);
Всё заработало, правда пришлось во все массивы вставлять
А в массивах кроме даты поставил везде нули
Эту строку в массиве вывода даты закоментировал // BrightDots(1); //разделительные точки включены BrightDots(1);

зачем пугаешь людей) тут конкретный пример для конкретного случая вполне достаточен)
для себя тогда поправлю, возможно из-за этого у некоторых траблы с кодом, из-за разного кол-ва СД)

Поправил точки под настройки)
На фото 2 LED на сегмент, если нужно могу часа через три проверить на 3 LED на сегмент. Есть панель готовая.

Прошу прощения, это я погорячился насчёт проверки на 3 LED, я часы уже в корпус воткнул и запаял, Табло и ардуины то свободные есть, а вот модуля 3231 нет пока в наличии. Есть в наличии RTC_DS1307 и RTC_PCF_8563, но как их втулить в этот скетч знаний не хватает.

Вот скетч с одной точкой в дате, 2 LED на сегмент
 

Вложения

  • Лойс +1
Реакции: начинающий

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
@kym13,
.
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
446
67
@kym13,
.
Это я читал, подключить к ардуине не проблема, проблема вставить в скетч:oops:
 

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
Переделал код под ESP8266, пока только с часами DS3231, надо проверять работоспособность)
Задел под датчики сделал, подобрал библиотеки)
Есть кому проверить?)
C++:
// подключаем библиотеку «ESP8266WiFi»:
#include <ESP8266WiFi.h>
//#include <OneWire.h>
//#include <DallasTemperature.h>
#include <RTClib.h>
RTC_DS3231 rtc;
//#include <Wire.h>
//#include <SPI.h>
//#include <Adafruit_Sensor.h>
//#include <Adafruit_BMP280.h>
#include <FastLED.h>   // библиотека светодиодов из менеджера библиотек

// вписываем здесь SSID и пароль для вашей WiFi-сети:
const char* ssid = "";  // название Wi-Fi сети
const char* password = "";  // пароль сети

// веб-сервер на порте 80:
WiFiServer server(80);

/////////////////////////////////////////////
#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() { // настройки
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected"); // "Подключение к WiFi выполнено"

  // запускаем веб-сервер:
  server.begin();
  Serial.println("Web server running. Waiting for the ESP IP...");
  // "Веб-сервер запущен. Ожидание IP-адреса ESP..."
  delay(10000);
  // печатаем IP-адрес ESP:
  Serial.println(WiFi.localIP());

  Serial.begin(9600);
  FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS); // подключение ленты
}
/////////////////////////////////////////////
int GetTime() { // функция времени
  DateTime now = rtc.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() { // функция освещенности
  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 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();
  TimeToArray();
  FastLED.show(); // команда для включения светодиодов
}
 

Вложения

kym13

★★✩✩✩✩✩
14 Ноя 2020
446
67
Переделал код под ESP8266, пока только с часами DS3231, надо проверять работоспособность)
Задел под датчики сделал, подобрал библиотеки)
Есть кому проверить?)
C++:
// подключаем библиотеку «ESP8266WiFi»:
#include <ESP8266WiFi.h>
//#include <OneWire.h>
//#include <DallasTemperature.h>
#include <RTClib.h>
RTC_DS3231 rtc;
//#include <Wire.h>
//#include <SPI.h>
//#include <Adafruit_Sensor.h>
//#include <Adafruit_BMP280.h>
#include <FastLED.h>   // библиотека светодиодов из менеджера библиотек

// вписываем здесь SSID и пароль для вашей WiFi-сети:
const char* ssid = "";  // название Wi-Fi сети
const char* password = "";  // пароль сети

// веб-сервер на порте 80:
WiFiServer server(80);

/////////////////////////////////////////////
#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() { // настройки
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected"); // "Подключение к WiFi выполнено"

  // запускаем веб-сервер:
  server.begin();
  Serial.println("Web server running. Waiting for the ESP IP...");
  // "Веб-сервер запущен. Ожидание IP-адреса ESP..."
  delay(10000);
  // печатаем IP-адрес ESP:
  Serial.println(WiFi.localIP());

  Serial.begin(9600);
  FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS); // подключение ленты
}
/////////////////////////////////////////////
int GetTime() { // функция времени
  DateTime now = rtc.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() { // функция освещенности
  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 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();
  TimeToArray();
  FastLED.show(); // команда для включения светодиодов
}
Блин, ESPш-ка есть, а вот 3231 кончились, вот если бы на RTC_DS1307 или RTC_PCF_8563
 
Изменено:

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
@kym13, подключи как есть, без модуля часов, надо понять, будет ли работать, сейчас пробую NTP клиент подрубить) ESP тоже есть, но надо отпаивать часы, пока так тестирую)

нашел простую библиотеку NTPClient, а она не работает, печаль)
этот вариант работает, но в UNIX))
 
Изменено:

kym13

★★✩✩✩✩✩
14 Ноя 2020
446
67
Блин, ESPш-ка есть, а вот 3231 кончились, вот если бы на RTC_DS1307 или RTC_PCF_8563
Эти пины указаны для платы ESP?
#define LED_PIN 6 // пин дата от ленты
#define MIN_PIN 5 // пин минутной кнопки
#define HUR_PIN 4 // пин часовой кнопки
#define BRI_PIN A0 // PIN фоторезистора
 

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
@kym13, нужен только 6 пин, для ленты) остальное пока не надо)
пошел отдыхать, может что подскажут по NTP клиенту, или другую библиотеку предложат)
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
446
67
Вот что получилось без RTC. 3 LED на сегмент. Подключен только дисплей и фоторезистор. В мониторе порта только это. На фоторезистор не реагирует.

Вообще ESP должна без RTC работать и получать время с сервера
 

Вложения

  • 110.6 KB Просмотры: 22
  • 128.5 KB Просмотры: 23
Изменено:

maksland

★★★✩✩✩✩
13 Янв 2019
464
107
Omsk
у нас свет часто отключают и wifi бывает временами ... автономность нужна
 

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
@kym13, раз выводит, значит всё ок. Остаётся наладить ntp, сохранять в часы. Остальное доделается)
 

razwal

✩✩✩✩✩✩✩
20 Янв 2020
22
3
Устранил замечания. Добавил второй датчик температуры, некоторые настройки часов (все внутри в описании). Как сделать настройка цвета температуры чтоб настраивалась из прошивки или часов.
Здравствуйте . Обращаюсь к Вячеслав_45 , будет ли дальнейшее развитие вашей прошивки из поста #202 ? (разные цвета температуры , может отдельная настройка цвета отображения часов , добавление датчика давления ...). Просто, как то всё с этой прошивкой заглохло , а очень жаль , в ней есть много полезного (сохранение настроек в памяти , а самое главное для меня "установка количества отображения температуры и даты в минуту" ) .
 
  • Лойс +1
Реакции: maksland

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
а что за проблема с NTP ? В библиотеке прям готовый пример есть
ethernet? там фигня какая-то)
ура, получилось у меня с клиентом) время считывать получается, помогите теперь с записью в часы)
думаю надо вынести клиент в отдельную функцию и обрабатывать ее раз в сутки, думаю достаточно, можно и раз в неделю, также обрабатывать ее можно при запуске в настройках)

по логике timeClient.getHours() надо записать в RTC.now.hour(); и так каждый элемент?)

C++:
// подключаем библиотеку «ESP8266WiFi»:
#include <ESP8266WiFi.h>
#include <NTPClient_Generic.h>
#include <WiFiUdp.h>
//#include <OneWire.h>
//#include <DallasTemperature.h>
#include <RTClib.h>
RTC_DS3231 rtc;
//#include <Wire.h>
//#include <SPI.h>
//#include <Adafruit_Sensor.h>
//#include <Adafruit_BMP280.h>
#include <FastLED.h>   // библиотека светодиодов из менеджера библиотек

char ssid[] = "";             // your network SSID (name)
char pass[] = "";         // your network password
WiFiUDP ntpUDP;
#define TIME_ZONE_OFFSET_HRS            (3)
NTPClient timeClient(ntpUDP);

/////////////////////////////////////////////
#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(115200);
  while (!Serial);
  Serial.println("\nStarting ESP_NTPClient_Basic on " + String(ARDUINO_BOARD));
  Serial.println("Connecting to: " + String(ssid));
  WiFi.begin(ssid, pass);
  while ( WiFi.status() != WL_CONNECTED )
  {
    delay ( 500 );
    Serial.print ( "." );
  }
  Serial.print(F("\nESP_NTPClient_Basic started @ IP address: "));
  Serial.println(WiFi.localIP());
  timeClient.begin();
  timeClient.setTimeOffset(3600 * TIME_ZONE_OFFSET_HRS);
  // default 60000 => 60s. Set to once per hour
  timeClient.setUpdateInterval(SECS_IN_HR);
  Serial.println("Using NTP Server " + timeClient.getPoolServerName());


  FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS); // подключение ленты
}
/////////////////////////////////////////////
int GetTime() { // функция времени
  DateTime now = rtc.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() { // функция освещенности
  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 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();
// TimeToArray();
// FastLED.show(); // команда для включения светодиодов

  timeClient.update();

  if (timeClient.updated())
    Serial.println("********UPDATED********");
  else
    Serial.println("******NOT UPDATED******");
//     Serial.println("LOC : " + timeClient.getFormattedDateTime());
  Serial.print(timeClient.getHours());
  Serial.print(":");
  Serial.print(timeClient.getMinutes());
  Serial.print(":");
  Serial.println(timeClient.getSeconds());

  delay(1000);

}
 

Вложения

Изменено:

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
Какие мысли по #520?) Как реализовать?)
 

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

★★★★★★★
14 Авг 2019
4,197
1,282
Москва
в RTClib есть же:
rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
строка из примера , соотв. 21-ое января 2014 года ровно 3 часа, 0 минут, 0 секунд. что тут думать ? трясти надо!
 

ASM

★★★★✩✩✩
26 Окт 2018
1,515
295
@Старик Похабыч, как записать данные с ntp в rtc. В каком виде там хранятся?) Раз в сутки достаточно) Если в unix, то все просто, принимать можно в unix...