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