new bits n fixes
[xmas-ornament.git] / code / sketch_dec10a.ino
1 //NodeMCU  Wemos D1
2 //Arduino as ISP
3 #include <SPI.h>
4 #include <NTPClient.h>
5 #include <ESP8266WiFi.h>
6 #include <WiFiUdp.h>
7 #include <Adafruit_NeoPixel.h>
8
9
10 #define LED_PIN D6
11 #define LED_COUNT 6
12
13 static uint16_t hue = 0; // 0-359
14 uint8_t saturation = 100; // 0-100
15 uint8_t lightness = 50; // 0-100
16 unsigned int PColor=0;
17
18 const char *ssid     = "SSID";
19 const char *password = "PASSWORD";
20
21 const long utcOffsetInSeconds = 3600*-5;
22
23 WiFiUDP ntpUDP;
24 NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
25 Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
26
27 //arduino
28 //const int dataPin = 13;   //Outputs the byte to transfer
29 //const int loadPin = 11;   //3 //Controls the internal transference of data in SN74HC595 internal registers
30 //const int clockPin = 12;  // 4//Generates the clock signal to control the transference of data
31
32 //nodeMCU
33 //const int dataPin = 14;   //Outputs the byte to transfer
34 //const int loadPin = 0;   //3 //Controls the internal transference of data in SN74HC595 internal registers
35 //const int clockPin = 4;  // 4//Generates the clock signal to control the transference of data
36
37 //wemos
38 const int dataPin = 14;  //D5 //Outputs the byte to transfer
39 const int loadPin = 0;   //D3 //3 //Controls the internal transference of data in SN74HC595 internal registers
40 const int clockPin = 4;  //D2 // 4//Generates the clock signal to control the transference of data
41
42
43 byte digits[10] {
44   0b11111100,
45   0b01100000,
46   0b11011010,
47   0b11110010,
48   0b01100110,
49   0b10110110,
50   0b10111110,
51   0b11100000,
52   0b11111110,
53   0b11100110
54 };
55
56 void setup() {
57   Serial.begin(115200);
58   
59   pinMode(dataPin, OUTPUT);
60   pinMode(loadPin, OUTPUT);
61   pinMode(clockPin, OUTPUT);  
62   digitalWrite(loadPin, 0);
63   shiftOut(dataPin, clockPin, LSBFIRST, 0b0000000000000000);
64   digitalWrite(loadPin, 1);
65
66   WiFi.begin(ssid, password);
67   int i=0;
68   int b=0;
69   while ( WiFi.status() != WL_CONNECTED ) {
70     delay ( 500 );
71     digitalWrite(loadPin, 0);
72     shiftOut(dataPin, clockPin, LSBFIRST, digits[i]); //right
73     shiftOut(dataPin, clockPin, LSBFIRST, digits[b]); //left
74     digitalWrite(loadPin, 1);
75     i++;
76     if (i==10) {
77       i=0;
78       b++;
79     }
80     if (b==9 && i==9) {
81       digitalWrite(loadPin, 0);
82       shiftOut(dataPin, clockPin, LSBFIRST, 0b00001010); //right
83       shiftOut(dataPin, clockPin, LSBFIRST, 0b10011111); //left
84       digitalWrite(loadPin, 1);
85       delay(10000);
86       i=0;
87       b=0;
88     }
89   }
90   timeClient.begin();
91   strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
92   strip.show();            // Turn OFF all pixels ASAP
93   strip.setBrightness(25); // Set BRIGHTNESS to about 1/5 (max = 255)
94 }
95
96 void chase() {
97   byte disp = 0;
98   for (unsigned int j=0; j<5; j++) {
99     for (unsigned int i=0; i<8; i++) {
100       digitalWrite(loadPin, 0);
101       bitSet(disp, i);
102       shiftOut(dataPin, clockPin, LSBFIRST, disp); //right
103       shiftOut(dataPin, clockPin, LSBFIRST, disp); //left
104       digitalWrite(loadPin, 1);
105       delay(25);
106       bitClear(disp, i);
107     }  
108   }
109 }
110
111 void casino() {
112   for (unsigned int i=0; i<20; i++) {
113     digitalWrite(loadPin, 0);
114     shiftOut(dataPin, clockPin, LSBFIRST, digits[random(0,9)]); //right
115     shiftOut(dataPin, clockPin, LSBFIRST, digits[random(0,9)]); //left
116     digitalWrite(loadPin, 1);
117     delay(25);
118   }  
119 }
120
121 /**
122  * Map HSL color space to RGB
123  * 
124  * Totally borrowed from:
125  * http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/ 
126  * 
127  * Probably not the most efficient solution, but 
128  * it get's the job done.
129  */
130 uint32_t hsl(uint16_t ih, uint8_t is, uint8_t il) {
131
132   float h, s, l, t1, t2, tr, tg, tb;
133   uint8_t r, g, b;
134
135   h = (ih % 360) / 360.0;
136   s = constrain(is, 0, 100) / 100.0;
137   l = constrain(il, 0, 100) / 100.0;
138
139   if ( s == 0 ) { 
140     r = g = b = 255 * l;
141     return ((uint32_t)r << 16) | ((uint32_t)g <<  8) | b;
142   } 
143   
144   if ( l < 0.5 ) t1 = l * (1.0 + s);
145   else t1 = l + s - l * s;
146   
147   t2 = 2 * l - t1;
148   tr = h + 1/3.0;
149   tg = h;
150   tb = h - 1/3.0;
151
152   r = hsl_convert(tr, t1, t2);
153   g = hsl_convert(tg, t1, t2);
154   b = hsl_convert(tb, t1, t2);
155
156   // NeoPixel packed RGB color
157   return ((uint32_t)r << 16) | ((uint32_t)g <<  8) | b;
158 }
159 /**
160  * HSL Convert
161  * Helper function
162  */
163 uint8_t hsl_convert(float c, float t1, float t2) {
164
165   if ( c < 0 ) c+=1; 
166   else if ( c > 1 ) c-=1;
167
168   if ( 6 * c < 1 ) c = t2 + ( t1 - t2 ) * 6 * c;
169   else if ( 2 * c < 1 ) c = t1;
170   else if ( 3 * c < 2 ) c = t2 + ( t1 - t2 ) * ( 2/3.0 - c ) * 6;
171   else c = t2;
172   
173   return (uint8_t)(c*255); 
174 }
175
176 void loop() {
177   timeClient.update();
178
179   unsigned int b=0;
180   unsigned int Hour = timeClient.getHours();
181   unsigned int Minute = timeClient.getMinutes();
182   unsigned int Seconds = timeClient.getSeconds();
183   unsigned int Hour1 = (Hour/10U) % 10;
184   unsigned int Hour2 = (Hour/1U) % 10;
185   unsigned int Minute1 = (Minute/10U) % 10;
186   unsigned int Minute2 = (Minute/1U) % 10;
187   digitalWrite(loadPin, 0);
188   shiftOut(dataPin, clockPin, LSBFIRST, 0b0000000000000000);
189   digitalWrite(loadPin, 1);
190   chase();
191   while (Seconds<60) {
192   
193     for (b=0; b<6; b++) {
194       strip.setPixelColor(b, hsl(PColor, saturation, lightness));
195       strip.show();
196     }
197
198     PColor++;
199     if (PColor>360) {
200       PColor=0;
201     }
202     casino();
203     digitalWrite(loadPin, 0);
204     shiftOut(dataPin, clockPin, LSBFIRST, digits[Hour2]); //right
205     shiftOut(dataPin, clockPin, LSBFIRST, digits[Hour1]); //left
206     digitalWrite(loadPin, 1);
207     delay(3000);
208     digitalWrite(loadPin, 0);
209     shiftOut(dataPin, clockPin, LSBFIRST, digits[Minute2]); //right
210     shiftOut(dataPin, clockPin, LSBFIRST, digits[Minute1]); //left
211     digitalWrite(loadPin, 1);
212     delay(3000);
213     Seconds = Seconds+6;
214   }
215 }