#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Wire.h>
#include "Font7Seg.h"
#include "RTClib.h"
#include <FastLED.h>
FASTLED_USING_NAMESPACE
RTC_DS3231 rtc;
#define PIN 3
#define DATA_PIN 3
#define NUM_LEDS 60
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define MAX_POWER_MILLIAMPS 1000
#define FASTLED_ALLOW_INTERRUPTS 0
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 6
#define CLK_PIN 13
#define DATA_PIN 11
#define CS_PIN 10
#define SPEED_TIME 75
#define PAUSE_TIME 0
#define MAX_MESG 20
#define DS1307_ADDRESS 0x68
uint8_t wday, mday, month, year;
uint8_t hours, minutes, seconds;
uint8_t se, mi, st;
extern CRGB leds[NUM_LEDS];
char szTime[9]; // mm:ss\0
char szMesg[MAX_MESG + 1] = "";
float humidity, celsius, fahrenheit;
uint8_t degC[] = { 6, 3, 3, 56, 68, 68, 68 }; // Deg C
uint8_t degF[] = { 6, 3, 3, 124, 20, 20, 4 }; // Deg F
uint8_t clear = 0x00;
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void beginDS1307() {
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(clear);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 0x07);
seconds = bcdToDec(Wire.read());
minutes = bcdToDec(Wire.read());
hours = bcdToDec(Wire.read() & 0xff);
wday = bcdToDec(Wire.read());
mday = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = bcdToDec(Wire.read());
}
uint8_t decToBcd(uint8_t value) {
return ((value / 10 * 16) + (value % 10));
}
uint8_t bcdToDec(uint8_t value) {
return ((value / 16 * 10) + (value % 16));
}
void getTime(char *psz, bool f = true) {
sprintf(psz, "%02d%c%02d%c%02d", hours, (f ? ':' : ' '), minutes, (f ? ':' : ' '), seconds);
}
void getDate(char *psz) {
char szBuf[10];
sprintf(psz, "%d %s %04d", mday , mon2str(month, szBuf, sizeof(szBuf) - 1), (year + 2000));
}
char *mon2str(uint8_t mon, char *psz, uint8_t len) {
static const __FlashStringHelper* str[] = {
F("Jan"), F("Feb"), F("Mar"), F("Apr"),
F("May"), F("Jun"), F("Jul"), F("Aug"),
F("Sep"), F("Oct"), F("Nov"), F("Dec")
};
strncpy_P(psz, (const char PROGMEM *)str[mon - 1], len);
psz[len] = '\0';
return (psz);
}
char *dow2str(uint8_t code, char *psz, uint8_t len) {
static const __FlashStringHelper* str[] = {
F("Sunday"), F("Monday"), F("Tuesday"),
F("Wednesday"), F("Thursday"), F("Friday"),
F("Saturday")
};
strncpy_P(psz, (const char PROGMEM *)str[code - 1], len);
psz[len] = '\0';
return (psz);
}
CRGB leds[NUM_LEDS];
void setup(void) {
Wire.begin();
P.begin(2);
P.setInvert(false);
P.setZone(0, MAX_DEVICES - 6, MAX_DEVICES - 1);
P.setZone(1, MAX_DEVICES - 6, MAX_DEVICES - 1);
P.displayZoneText(1, szTime, PA_CENTER, SPEED_TIME, PAUSE_TIME, PA_PRINT, PA_NO_EFFECT);
P.displayZoneText(0, szMesg, PA_CENTER, SPEED_TIME, 0, PA_PRINT , PA_NO_EFFECT);
P.addChar('$', degC);
P.addChar('&', degF);
Serial.begin(9600);
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS)
.setCorrection(UncorrectedColor);
rtc.begin();
Wire.begin();
}
void loop(void) {
static uint32_t lastTime = 0;
static uint8_t display = 0;
static bool flasher = false;
if ((millis() - lastTime) >= 1000) {
lastTime = millis();
getTime(szMesg, flasher);
flasher = !flasher;
}
if (seconds == 0) {
display++;
P.setTextEffect(0, PA_PRINT, PA_WIPE_CURSOR);
}
switch (display) {
case 4: // Day of week
P.setFont(0, nullptr);
P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
dow2str(wday, szMesg, MAX_MESG);
break;
default: // Calendar
P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
display = 0;
getDate(szMesg);
break;
}
pacifica_loop();
rtc_loop();
FastLED.show();
}
CRGBPalette16 pacifica_palette_1 = { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 };
CRGBPalette16 pacifica_palette_2 = { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F };
CRGBPalette16 pacifica_palette_3 = { 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33,
0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF };
void rtc_loop() {
DateTime now = rtc.now();
se = now.second();
mi = now.minute();
st = now.hour();
if (st >= 12) {
st = st - 12;
}
st = st * 5;
st = st + mi / 12;
leds[se] = CRGB(0, 255, 0); // Green
leds[mi] = CRGB(240, 10, 10); // Red
leds[st] = CRGB(247, 39, 199); // Magenta
if (mi == st) {
leds[mi = st] = CRGB(255, 0, 150);
}
if (st == se) {
leds[se = st] = CRGB(255, 255, 150);
}
if (mi == se) {
leds[se = mi] = CRGB(255, 255, 0);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void pacifica_loop()
{
// Increment the four "color index start" counters, one for each wave layer.
// Each is incremented at a different speed, and the speeds vary over time.
static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4;
static uint32_t sLastms = 0;
uint32_t ms = GET_MILLIS();
uint32_t deltams = ms - sLastms;
sLastms = ms;
uint16_t speedfactor1 = beatsin16(3, 179, 269);
uint16_t speedfactor2 = beatsin16(4, 179, 269);
uint32_t deltams1 = (deltams * speedfactor1) / 256;
uint32_t deltams2 = (deltams * speedfactor2) / 256;
uint32_t deltams21 = (deltams1 + deltams2) / 2;
sCIStart1 += (deltams1 * beatsin88(1011, 10, 13));
sCIStart2 -= (deltams21 * beatsin88(777, 8, 11));
sCIStart3 -= (deltams1 * beatsin88(501, 5, 7));
sCIStart4 -= (deltams2 * beatsin88(257, 4, 6));
// Clear out the LED array to a dim background blue-green
fill_solid( leds, NUM_LEDS, CRGB( 2, 6, 10));
// Render each of four layers, with different scales and speeds, that vary over time
pacifica_one_layer( pacifica_palette_1, sCIStart1, beatsin16( 3, 11 * 256, 14 * 256), beatsin8( 10, 70, 130), 0 - beat16( 301) );
pacifica_one_layer( pacifica_palette_2, sCIStart2, beatsin16( 4, 6 * 256, 9 * 256), beatsin8( 17, 40, 80), beat16( 401) );
pacifica_one_layer( pacifica_palette_3, sCIStart3, 6 * 256, beatsin8( 9, 10, 38), 0 - beat16(503));
pacifica_one_layer( pacifica_palette_3, sCIStart4, 5 * 256, beatsin8( 8, 10, 28), beat16(601));
// Add brighter 'whitecaps' where the waves lines up more
pacifica_add_whitecaps();
// Deepen the blues and greens a bit
pacifica_deepen_colors();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Add one layer of waves into the led array
void pacifica_one_layer(CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) {
CRGB leds[NUM_LEDS]; // Deklarasikan 'leds' di sini
// ... bagian lain dari fungsi
uint16_t ci = cistart;
uint16_t waveangle = ioff;
uint16_t wavescale_half = (wavescale / 2) + 20;
for ( uint16_t i = 0; i < NUM_LEDS; i++) {
waveangle += 250;
uint16_t s16 = sin16( waveangle ) + 32768;
uint16_t cs = scale16( s16, wavescale_half ) + wavescale_half;
ci += cs;
uint16_t sindex16 = sin16( ci) + 32768;
uint8_t sindex8 = scale16( sindex16, 240);
CRGB c = ColorFromPalette( p, sindex8, bri, LINEARBLEND);
leds[i] += c;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Add extra 'white' to areas where the four layers of light have lined up brightly
void pacifica_add_whitecaps() {
CRGB leds[NUM_LEDS]; // Deklarasikan 'leds' di sini
// ... bagian lain dari fungsi
uint8_t basethreshold = beatsin8( 9, 55, 65);
uint8_t wave = beat8( 7 );
for ( uint16_t i = 0; i < NUM_LEDS; i++) {
uint8_t threshold = scale8( sin8( wave), 20) + basethreshold;
wave += 7;
uint8_t l = leds[i].getAverageLight();
if ( l > threshold) {
uint8_t overage = l - threshold;
uint8_t overage2 = qadd8( overage, overage);
leds[i] += CRGB( overage, overage2, qadd8( overage2, overage2));
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Deepen the blues and greens
void pacifica_deepen_colors() {
CRGB leds[NUM_LEDS]; // Deklarasikan 'leds' di sini
// ... bagian lain dari fungsi
for ( uint16_t i = 0; i < NUM_LEDS; i++) {
leds[i].blue = scale8( leds[i].blue, 145);
leds[i].green = scale8( leds[i].green, 200);
leds[i] |= CRGB( 2, 5, 7);
}
}