#include <Wire.h> // Нужна для опроса часовой микросхемы DS1307
#include "FastLED.h" // Библиотека управления адресной лентой
#include "buildTime.h" // Библиотека для первоначальной установки часов
#include <GyverButton.h> // Библиотека для удобной работы с кнопками
#include <avr/eeprom.h>
byte
nColor;
// Индекс таблицы цветов
#define DS1307_I2C_ADDRESS 0x68
#define NUM_LEDS 29 // Количество светодиодов (для WS2811 по 3 штуки на контроллер)
#define COLOR_ORDER BRG // Порядок цветов
#define DATA_PIN 10 // Куда подключаем ленту
#define PIN_PHOTO_SENSOR A0 // пин датчика освещенности
#define BTN_MIN 7 // пин кнопки изменения минут
#define BTN_HOUR 8 // пин кнопки изменения часов
#define BTN_COLOR 9 // пин кнопки смены цвета
GButton btnMin(BTN_MIN);
GButton btnHour(BTN_HOUR);
GButton btnColor(BTN_COLOR);
unsigned
long
previousMillis = 0;
//
const
long
interval = 1000;
// Вывод на экран каждую секунду (1000 мс)
boolean corTime =
false
;
byte
second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// Глобальные переменные для хранения времени
CRGB leds[NUM_LEDS];
// Define LEDs strip
byte
digits[10][7] = {{0,1,1,1,1,1,1},
// Digit 0
-
{0,1,0,0,0,0,1},
// Digit 1
-
{1,1,1,0,1,1,0},
// Digit 2
-
{1,1,1,0,0,1,1},
// Digit 3
-
{1,1,0,1,0,0,1},
// Digit 4
-
{1,0,1,1,0,1,1},
// Digit 5
-
{1,0,1,1,1,1,1},
// Digit 6
-
{0,1,1,0,0,0,1},
// Digit 7
-
{1,1,1,1,1,1,1},
// Digit 8
-
{1,1,1,1,0,1,1}};
// Digit 9 | 2D Array for numbers on 7 segment
bool
Dot =
true
;
// Состояние точки
long
ledColor;
// Используется в ф-ции Time2Array для задания цвета точек
long
ColorTable[28] = {
// Таблица цветов
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,
CRGB::Violet,
CRGB::Cyan,
CRGB::HotPink,
CRGB::Teal,
CRGB::Purple,
CRGB::Maroon,
CRGB::DarkBlue,
CRGB::Navy,
CRGB::Turquoise,
CRGB::Lime,
CRGB::Pink,
CRGB::White
};
void
setup() {
-
Wire.begin();
-
Serial.begin(9600);
// DEBUG ONLY
-
LEDS.addLeds<WS2811, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
// Set LED strip type
-
LEDS.setBrightness(50);
// Set initial brightness 1 - 255
-
// Первоначальная установка времени RTC (раскоментировать для однократного запуска!) :
-
// DS1307 seconds, minutes, hours, day, date, month, year
-
// setDS1307time(BUILD_SEC, BUILD_MIN, BUILD_HOUR, 2, BUILD_DAY, BUILD_MONTH, BUILD_YEAR); // из "buildTime.h"
-
// setDS1307time(30,07,13,2,20,12,21); // или вручную :)
-
nColor = eeprom_read_byte(0);
// Читаем из памяти 0-вой позиции
-
ledColor = ColorTable[nColor];
// ledColor записывается в ячейку
-
Serial.print(
"EEPROM(0)= "
);Serial.print(nColor);Serial.print(
" Color = "
);Serial.println(ledColor, HEX);
-
// Записать изменения часов и минут в RTC
-
// Сначала читаем текущие значения тех параметров, что кнопками не изменяются
-
// readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
-
// Пишем только изменяющиеся параметры часов и минут
-
// setDS1307time(second,24,12,dayOfWeek,dayOfMonth,month,year);
-
delay(500);
// Ждем пока все устаканится
}
//*************************************************************************************************
// MAIN
//*************************************************************************************************
void
loop() {
-
unsigned
long
currentMillis = millis();
-
byte
tmp = 33;
-
// int tmpTime;
-
// Опрос часов и вывод на экран происходит один раз в секунду (константа interval)
-
if
(currentMillis - previousMillis >= interval) {
-
previousMillis = currentMillis;
-
// Установка яркости ленты в зависимости от напряжения на фоторезисторе
-
int
val = analogRead(PIN_PHOTO_SENSOR);
-
if
(val <= 40) { LEDS.setBrightness(2); Serial.print(val);}
// Ночной режим
-
else
if
(val>40 and val<=150) { LEDS.setBrightness(35);Serial.println(val);}
// Затененная комната
-
else
if
(val>150 and val<=300) { LEDS.setBrightness(80);Serial.println(val);}
// Днем в тени
-
else
{ LEDS.setBrightness(155);Serial.println(val);}
// Солнечно, максимальный режим
-
// Смена режима часовых точек
-
if
(Dot) Dot =
false
;
-
else
Dot =
true
;
-
// Или так
-
// Dot = !Dot;
-
readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
-
// Коррекция времени
-
/*
if
((dayOfMonth != tmp) and (hour==3 and minute == 2)) {
//Только один раз в сутки!
-
tmp = dayOfMonth;
-
tmpTime = second*60 + minute - 40;
// 40 - настолько убегают часики в сутки :(
-
Serial.print(
"CutTime = "
);Serial.print(minute);Serial.print(
"%"
);Serial.println(second);
-
Serial.print(
"tmpTime = "
);Serial.print(tmpTime);Serial.print(
"tmpTime/60 = "
);Serial.print(tmpTime/60);Serial.print(
"tmpTime%60 = "
);Serial.println(tmpTime%60);
-
setDS1307time(tmpTime/60, tmpTime%60, hour, dayOfWeek, dayOfMonth, month, year);
-
}*/
-
//Новая версия коррекции
-
if
( hour==23 and minute == 48 ) corTime =
true
;
// флаг коррекции
-
if
( hour==23 and minute == 49 and second == 50 and corTime ) { corTime =
false
;
-
setDS1307time(10, minute, hour, dayOfWeek, dayOfMonth, month, year);
// 50-40 = 10 40 секунд назад коррекция
-
}
-
TimeToArray(); FastLED.show();
-
}
// Конец ежесекундной секции
-
// Здесь опрос кнопок и реакция на нажатия
-
btnMin.tick();
-
btnHour.tick();
-
btnColor.tick();
-
if
(btnMin.isClick()) { minute++;
if
(minute >= 60) minute = 0;
-
// readDS1307time(&second, &tmp, &hour, &dayOfWeek, &dayOfMonth, &month, &year); // Читаем снова, чтобы не потерять секунды
-
setDS1307time(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
// Пишем, значимо только первые три параметра
-
TimeToArray(); FastLED.show(); }
// Добавляем минуту и обновляем дисплей
-
if
(btnHour.isClick()) { hour++;
if
(hour >= 24) hour = 0;
-
// readDS1307time(&second, &minute, &tmp, &dayOfWeek, &dayOfMonth, &month, &year); // Читаем снова, чтобы не потерять секунды
-
setDS1307time(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
// Пишем, значимо только первые три параметра
-
TimeToArray(); FastLED.show(); }
// Добавляем час и обновляем дисплей
-
if
(btnColor.isClick()) {
-
if
(nColor < 27) { nColor++; }
else
{ nColor = 0; }
// В таблице 28 цветов, дошли до конца, начинаем с начала
-
eeprom_write_byte(0, nColor);
// Записываем новое значение индекса цвета
-
ledColor = ColorTable[nColor];
// ledColor записывается в ячейку
-
TimeToArray(); FastLED.show(); }
// Берем следующий цвет их списка и обновляем дисплей
}
//**************************************************************************************************
// Функция перевода числа в точки на дисплее
void
TimeToArray(){
-
int
Now = (hour*100+minute);
// Записываем время в виде числа типа 1843 (18:43)
-
int
cursor = 29;
-
//Serial.print(" TIME = ");Serial.print(Now); Serial.print(" LedColor = ");Serial.println(ledColor, HEX);
-
//ledColor = 0x0000FF;
-
if
(Dot){leds[14]=ledColor;}
-
else
{leds[14]=0x000000; }
-
for
(
int
i=1;i<=4;i++){
-
int
digit = Now % 10;
// get last digit in time
-
if
(i==1){
-
cursor =22;
-
for
(
int
k=0; k<=6;k++){
-
if
(digits[digit][k]== 1){leds[cursor]=ledColor;}
-
else
if
(digits[digit][k]==0){leds[cursor]=0x000000;};
-
cursor ++;
-
};
-
}
-
else
if
(i==2){
-
cursor -=14;
-
for
(
int
k=0; k<=6;k++){
-
if
(digits[digit][k]== 1){leds[cursor]=ledColor;}
-
else
if
(digits[digit][k]==0){leds[cursor]=0x000000;};
-
cursor ++;
-
};
-
}
-
else
if
(i==3){
-
cursor =7;
-
for
(
int
k=0; k<=6;k++){
-
if
(digits[digit][k]== 1){leds[cursor]=ledColor;}
-
else
if
(digits[digit][k]==0){leds[cursor]=0x000000;};
-
cursor ++;
-
};
-
}
-
else
if
(i==4){
-
cursor =0;
-
for
(
int
k=0; k<=6;k++){
-
if
(digits[digit][k]== 1){leds[cursor]=ledColor;}
-
else
if
(digits[digit][k]==0){leds[cursor]=0x000000;};
-
cursor ++;
-
};
-
}
-
Now /= 10;
-
}
}
// Функции чтения и записи в микросхему RTC DS1307
void
setDS1307time(
byte
second,
byte
minute,
byte
hour,
byte
dayOfWeek,
byte
dayOfMonth,
byte
month,
byte
year) {
-
// sets time and date data to DS1307
-
Wire.beginTransmission(DS1307_I2C_ADDRESS);
-
Wire.write(0);
// set next input to start at the seconds register
-
Wire.write(decToBcd(second));
// set seconds
-
Wire.write(decToBcd(minute));
// set minutes
-
Wire.write(decToBcd(hour));
// set hours
-
Wire.write(decToBcd(dayOfWeek));
// set day of week (1=Sunday, 7=Saturday)
-
Wire.write(decToBcd(dayOfMonth));
// set date (1 to 31)
-
Wire.write(decToBcd(month));
// set month
-
Wire.write(decToBcd(year));
// set year (0 to 99)
-
Wire.endTransmission();
}
void
readDS1307time(
byte
*second,
byte
*minute,
byte
*hour,
byte
*dayOfWeek,
byte
*dayOfMonth,
byte
*month,
byte
*year) {
-
Wire.beginTransmission(DS1307_I2C_ADDRESS);
-
Wire.write(0);
// set DS1307 register pointer to 00h
-
Wire.endTransmission();
-
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
-
// request seven bytes of data from DS1307 starting from register 00h
-
*second = bcdToDec(Wire.read() & 0x7f);
-
*minute = bcdToDec(Wire.read());
-
*hour = bcdToDec(Wire.read() & 0x3f);
-
*dayOfWeek = bcdToDec(Wire.read());
-
*dayOfMonth = bcdToDec(Wire.read());
-
*month = bcdToDec(Wire.read());
-
*year = bcdToDec(Wire.read());
}
// Сервисные функции по преобразованию вида чисел для DS1307
byte
decToBcd(
byte
val) {
return
( (val/10*16) + (val%10) ); }
// Convert normal decimal numbers to binary coded decimal
byte
bcdToDec(
byte
val) {
return
( (val/16*10) + (val%16) ); }
// Convert binary coded decimal to normal decimal numbers
Подсветка програмного кода
Отправить комментарий
Отправить комментарий