Большие настенные часы на Arduino

Green
Offline
Зарегистрирован: 01.10.2015

Не люблю я этих часописателей.( Но тут пришлось самому шкрябать. Хрен чего влазит в ATtiny2313 + ds1307 + ds18b20 + кнопка. Но ведь и день недели нужно отображать, а то некоторые задалбывают.)

Fenicksnet
Offline
Зарегистрирован: 25.03.2019

уберу +-0.30 пока не разобрался. их не много, сами допишут. :-)

// часики с температурой на ESP8266 и DS18B20.
// версия ядра ESP 2.7.4, версия выше не работает, мерцают светодиоды
// не забыть указвать часовой пояс, сервер NTP.
// для подключения к своему WIFI.  
//подключится к сети CLOCK_ESP, перейти по адресу 192.168.4.1 выбрать свою сеть и ввести  пароль.
/* последовательность подключения сегментов
     ---3----    ---10---        ---19--     ---26---    
     |      |    |      |        |      |   |       |
     4      2    11     9   16   20    18   27      25
     |      |    |      |   |    |      |   |       |
  Di >--1----    ---8---    |    ---17---    ---24---
     |      |    |      |   |    |      |   |       |
     5      7   12     14   15   21    23   28     30
     |      |    |      |        |      |   |       |
     ---6---     ---13---        ---22---    ---29---
*/
#include <WiFiManager.h> // <a href="https://github.com/tzapu/WiFiManager" rel="nofollow">https://github.com/tzapu/WiFiManager</a>
#include <NTPClient.h>
#include <WiFiUdp.h>

#define AP_SSID "CLOCK_ESP"                       //  имя wifi сети создаваемой esp для подключения 
char ntpServerName[] = "3.ru.pool.ntp.org";            //  сервер времени, например "3.ru.pool.ntp.org"
float TIME_ZONE = 3 ;                              //  часовой пояс 
int NTP_UPDATE = 60 ;                             //  период обновления времени минут
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServerName, TIME_ZONE * 3600, NTP_UPDATE * 60000);

// лента WS281х
#include <FastLED.h>               // библиотека для ленты
#define DATA_PIN 2                 // пин подключения ленты GPIO 2  --> R 1k --> Din
#define COLOR_ORDER GRB            // 12V ( BRG )   5V ( GRB )( если цвета диодов не сотвествуют меняем:( GRB, GBR, RGB, RBG, BGR, BRG) )
#define LEDS_IN_SEGMENT 1          // Задаём сколько у нас светодиодов в сегменте.
#define DOTS_NUM 2                 // Задаём количество разделительных точек 0 , 1 или 2.
#define LEDS_IN_DOTS 1             // количество светодиодов в 1 точке
#define DOT_BLINK 1                // мигать точками одновременно(0) или поочереди (1) 
#define NUM_COLORS 16              // кол-во цветов
#define Bright 255                 // яркость ленты (0-255)
// температура
#include <microDS18B20.h>          // библиотека ds18b20   https://github.com/GyverLibs/microDS18B20
#define DS18_pin 0                 // пин подключения датчика DS18B20
#define TEMP_UPDATE 20             // период обновления датчика температуры секунд.
#define Temp_on   1                // показывать температуру 1, нет 0.
#define Temp_minus 1               // показывать знак минус 1, нет 0 ( если температура выше -10)
#define Temp_show 15               // периодичность показа температуры сек.
#define Temp_show_time 3           // сколько секунд показывать температуру
#define Temp_Resolution 11         // разрешение термометра (9-12)
#define Color_minus 1              // менять цвет температуры при отрицательном значении  1 менять, 0 не менять
#define Color_plus 1               // менять цвет температуры при положительном значении  1 менять, 0 не менять
long TempM_Color = CRGB::Blue;     // цвет температуры при отрицательном значении
long TempP_Color = CRGB::Red;      // цвет температуры при положительном значении

uint32_t Temp_timer;
uint8_t Hour, Min, Sec;
bool flag, Start = true;
int TempC = -888;
long PreledColor;

// другие цвета ТУТ <a href="<a href="https://github.com/FastLED/FastLED/wiki/Pixel-reference#predefined-colors-list" rel="nofollow">https://github.com/FastLED/FastLED/wiki/Pixel-reference#predefined-colors-list</a>"
long ColorTable[NUM_COLORS] = {
  CRGB::Amethyst,
  CRGB::Aqua,
  CRGB::Blue,
  CRGB::Chartreuse,
  CRGB::DarkMagenta,
  CRGB::DarkOrange,
  CRGB::DeepPink,
  CRGB::Fuchsia,
  CRGB::Gold,
  CRGB::GreenYellow,
  CRGB::LightCoral,
  CRGB::Tomato,
  CRGB::Salmon,
  CRGB::Green,
  CRGB::Orchid,
  CRGB::DarkOrchid
};
long ledColor =  ColorTable[random(NUM_COLORS)];

// Вычислемые константы, НЕ РЕДАКТИРОВАТЬ!но если очень хочется то можно.
#define Temp_Update (TEMP_UPDATE*1000)                  // опрос датчика температуры
MicroDS18B20<DS18_pin> DS18;

#define NUM_DOTS (DOTS_NUM * LEDS_IN_DOTS)              //  количество диодов в точках
#define NUM_LEDS (LEDS_IN_SEGMENT * 28 + NUM_DOTS)      //  общее количество светодиодов в ленте
#define DOT_X (LEDS_IN_SEGMENT * 14 )                   //  координата начала точек
CRGB leds[NUM_LEDS];

#define DIG1 (NUM_LEDS - LEDS_IN_SEGMENT * 28 - NUM_DOTS)     // 1 ЦИФРА
#define DIG2 (NUM_LEDS - LEDS_IN_SEGMENT * 21 - NUM_DOTS)     // 2 ЦИФРА
#define DIG3 (NUM_LEDS - LEDS_IN_SEGMENT * 14 )               // 3 ЦИФРА
#define DIG4 (NUM_LEDS - LEDS_IN_SEGMENT * 7 )                // 4 ЦИФРА

uint8_t  digits[] = {
  0b00111111,     // 0  Digit 0
  0b00100001,     // 1  Digit 1
  0b01110110,     // 2  Digit 2
  0b01110011,     // 3  Digit 3
  0b01101001,     // 4  Digit 4
  0b01011011,     // 5  Digit 5
  0b01011111,     // 6  Digit 6
  0b00110001,     // 7  Digit 7
  0b01111111,     // 8  Digit 8
  0b01111011,     // 9  Digit 9
  0b00000000,     // 10 Digit  пусто (ничего не показывать)
  0b01000000,     // 11 Digit - ( знак минус)
  0b01011000,     // 12 Digit c
};

void setup() {

  WiFi.mode(WIFI_STA);
  //Serial.begin(115200);
  DS18.setResolution(Temp_Resolution);
  LEDS.addLeds<WS2812, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(Bright);
  PreledColor = ledColor;
  timeClient.begin();
  WiFiManager wm;
  wm.autoConnect(AP_SSID);

  if (Color_minus == 0 ) {
    TempM_Color = ledColor;
  }
  if (Color_plus == 0)    {
    TempP_Color = ledColor;
  }
}
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 TimeToArray() {
  dots();
  uint8_t  MH = Min;
  uint8_t digit = MH % 10;
  BrightDigit(digits[digit], DIG4);         //
  MH /= 10;
  digit = MH % 10;
  BrightDigit(digits[digit], DIG3);         //
  MH = Hour;
  digit = MH % 10;
  BrightDigit(digits[digit], DIG2);         //
  MH /= 10;
  digit = MH % 10;
  if (digit == 0)  {
    BrightDigit(digits[10], DIG1);
  }
  else   {
    BrightDigit(digits[digit], DIG1);
  }
}
//===== температура
void TempToArray() {
  int tempC;
  if ( TempC < 0)  {
    tempC = (TempC * (-1));
    ledColor = TempM_Color;
  }
  else  {
    tempC = TempC;
    ledColor = TempP_Color;
  }

  if ( DOTS_NUM == 1 )  {
    for (int i = 0; i < NUM_DOTS; i++) {
      leds[DOT_X + i ] = ledColor;
    }
  }
  else  {
    for (int i = 0; i < NUM_DOTS / 2 ; i++)
    {
      leds[DOT_X + i ] = ledColor;
      FastLED.show();
    }
    for (int i = NUM_DOTS / 2 ; i < NUM_DOTS; i++)
    {
      leds[DOT_X + i ] = CRGB::Black;
      FastLED.show();
    }
  }
  BrightDigit(digits[12], DIG4);         //

  uint8_t digit = tempC % 10;
  BrightDigit(digits[digit], DIG3);         //
  tempC /= 10;
  digit = tempC % 10;
  BrightDigit(digits[digit], DIG2);         //
  tempC /= 10;
  digit = tempC % 10;
  if (digit == 0)  {
    if (Temp_minus == 1 && TempC <= 0)
    {
      BrightDigit(digits[11], DIG1);
    }
    else
    {
      BrightDigit(digits[10], DIG1);
    }
  }
  else  {
    BrightDigit(digits[digit], DIG1);
  }
}
//========// мигаем точками
void dots()
{
  if ( DOTS_NUM == 1)  {                                   // если  1 точка
    if (Sec % 2 == 0)    {
      for (int i = 0; i < NUM_DOTS; i++) {
        leds[DOT_X + i ] = ledColor;
        FastLED.show();
      }
    }
    else    {
      for (int i = 0; i < NUM_DOTS; i++) {
        leds[DOT_X + i ] = CRGB::Black;
        FastLED.show();
      }
    }
  }

  else  if ( DOTS_NUM == 2)  {                               // если 2 точки
    if (DOT_BLINK) {                                         //  мигаем поочереди
      if (Sec % 2 == 0)      {
        for (int i = 0; i < NUM_DOTS / 2; i++) {
          leds[DOT_X + i ] = ledColor;
          leds[DOT_X + NUM_DOTS / 2 + i ] = CRGB::Black;
          FastLED.show();
        }
      }
      else      {
        for (int i = 0; i < NUM_DOTS / 2; i++) {
          leds[DOT_X + i ] = CRGB::Black;
          leds[DOT_X + NUM_DOTS / 2 + i ] = ledColor;
          FastLED.show();
        }
      }
    }
    else                                                    // 2 точки мигают одновременно
    {
      if (Sec % 2 == 0)      {
        for (int i = 0; i < NUM_DOTS; i++) {
          leds[DOT_X + i ] = ledColor;
          FastLED.show();
        }
      }
      else      {
        for (int i = 0; i < NUM_DOTS; i++) {
          leds[DOT_X + i ] = CRGB::Black;
          FastLED.show();
        }
      }
    }
  }
}

void loop() {
  timeClient.update();
  Sec = timeClient.getSeconds();

  if (Start == true && Min != timeClient.getMinutes())  {
    Min = timeClient.getMinutes();
    Hour = timeClient.getHours();
    Start = false;
  }

  if ( millis() - Temp_timer >= Temp_Update)  {
    DS18.requestTemp();
    if (DS18.readTemp()) {
      TempC = (DS18.getTemp() * 10);
    }
    Temp_timer = millis();
  }

  if (  Sec == 0 && flag == true)  {
    ledColor = ColorTable[random(NUM_COLORS)];
    Min = timeClient.getMinutes();
    Hour = timeClient.getHours();
    flag = false;
  }
  else if (Sec == 59)  {
    flag = true;
  }
  if ( Temp_on  == 1 && ( Sec % Temp_show > 0  && Sec % Temp_show <= Temp_show_time))
  {
    PreledColor = ledColor;
    TempToArray();
    ledColor = PreledColor;
  }
  else  {
    TimeToArray() ;
  }
  FastLED.show();
//--== FenickSnet ==--
}