Hi,
can't give you a more recent version (with web ui) but this should be a good start.
you have to modify the code for your WiFi. If no connection can be made manual setup ist started.
first single clicks set hour, then double click switsche to minutes in 5min steps, next doule click sets single minutes, last double click starts clock.
Single click in clock mode starts/stops rainbow mode, double click enters setup ... (as far as I remember)
Haven't checked compilability of the code for month ...
Hw is simple:
60 WS2812 powerd with 3.3V data on GPIO2
pushbutton on GPIO0 to gnd, pullup on PD
Code: Select all#include <Adafruit_NeoPixel.h>
#include <OneButton.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#define PIN 2
#define BTN 0
#define HUE 60
#define mySSID "yourSSID"
#define myPASS "yourPASS"
unsigned long sek, ma;
unsigned int hz, mz, sz, adj = 0, cc = 0;
byte hb = 0x0F, bb = 1, wl = 0;
// setup neopixel
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
// Setup button
OneButton button(BTN, true);
// setup WiFi
char ssid[] = mySSID; // your network SSID (name)
char pass[] = myPASS; // your network password
unsigned int localPort = 2390; // local port to listen for UDP packets
IPAddress timeServer(86,59,13,46); // at.pool.ntp.org NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;
void setup() {
// init serial
Serial.begin(115200);
Serial.println();
// init Neopixels
strip.begin();
// strip.setBrightness(0x10);
strip.clear();
strip.show();
// link the button functions to be called on a button events
button.attachDoubleClick(dclk);
button.attachClick(sclk);
// init WiFi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
delay(500);
while ((WiFi.status() != WL_CONNECTED) && (cc < 15)) {
Serial.print(WiFi.status());
delay(500);
++cc;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi connected");
udp.begin(localPort);
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(200);
while (!udp.parsePacket()) {
Serial.print(".");
sendNTPpacket(timeServer); // send an NTP packet to a time server
delay(200);
}
Serial.println("ntp received");
setTimefromUdp();
WiFi.mode(WIFI_OFF);
}
else {
Serial.println("manual setup");
WiFi.mode(WIFI_OFF);
dclk();
}
} //setup
void loop() {
if (millis() % 1000 <= 10)
{ sek++;
PrintTime();
delay(10);
}
button.tick();
delay(5);
if (millis() % 125 > 110)
{ if (adj == 0)
{ sz = sek % 60;
if (sz == 0)
{ mz = (sek / 60) % 60;
hz = (sek / 720) % 60;
}
}
strip.clear();
if (adj == 5)
{
for (byte i = 0; i < 60; i++)
strip.setPixelColor(i, hsi_rgb((360 / HUE) * ((i + cc) % HUE), 0.93, 0.93));
cc = (cc + 1) % HUE;
}
else
{ for (byte i = 0; i < 60; i += 5)
strip.setPixelColor(i, hb, hb, hb);
strip.setPixelColor(hz, 0x00, 0x00, 0x1F);
strip.setPixelColor(mz, 0x00, 0x1F, 0x00);
strip.setPixelColor(sz, 0x1F, 0x00, 0x00);
hb = hb + bb;
if (hb >= 0x17 || hb <= 0x5) bb = bb * -1;
}
strip.show();
delay(10);
}
if ((sek % 14400) == 14370 && wl == 0)
{ WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
wl = 1;
Serial.println("WiFi_started");
}
if (wl == 1 && WiFi.status() == WL_CONNECTED)
{ udp.begin(localPort);
sendNTPpacket(timeServer);
wl = 2;
Serial.println("ntp_request");
}
if (wl == 2 && udp.parsePacket())
{ setTimefromUdp();
WiFi.mode(WIFI_OFF);
wl = 0;
Serial.println("ntp_received");
}
if ((sek % 14400) == 14390 && wl > 0)
{ WiFi.mode(WIFI_OFF);
wl = 0;
Serial.println("wlan_stopped");
}
} //loop
unsigned long hsi_rgb(float H, float S, float I) {
unsigned int r, g, b;
// H = fmod(H,360); // cycle H around to 0-360 degrees
H = 3.14159 * H / (float)180; // Convert to radians.
S = S > 0 ? (S < 1 ? S : 1) : 0; // clamp S and I to interval [0,1]
I = I > 0 ? (I < 1 ? I : 1) : 0;
// Math! Thanks in part to Kyle Miller.
if (H < 2.09439) {
r = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
g = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
b = 255 * I / 3 * (1 - S);
} else if (H < 4.188787) {
H = H - 2.09439;
g = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
b = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
r = 255 * I / 3 * (1 - S);
} else {
H = H - 4.188787;
b = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
r = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
g = 255 * I / 3 * (1 - S);
}
return (long(r) << 16) | (g << 8) | (b & 0xFF);
} //hsi_rgb
void dclk() {
Serial.print("dbl_click ");
Serial.println(adj);
switch (++adj) {
case 1: {
strip.clear();
sz = -1; mz = -1; hz = 0; sek = 0lu;
strip.setPixelColor(hz, 0x00, 0x00, 0x1F);
break;
}
case 2: {
mz = 0;
strip.setPixelColor(mz, 0x00, 0x1F, 0x00);
break;
}
case 3: {
strip.setPixelColor(mz, 0x00, 0x1F, 0x00);
break;
}
case 4: {
sek = (hz * 720) + (mz * 60);
}
default: {
mz = (sek / 60) % 60;
hz = (sek / 720) % 60;
strip.setBrightness(0xFF);
strip.clear();
adj = 0;
}
}
} //dblclick
void sclk() {
Serial.print("sgl_click ");
Serial.println(adj);
switch (adj) {
case 0: {
strip.setBrightness(0x10);
adj = 5;
cc = 0;
break;
}
case 1: {
strip.setPixelColor(hz, 0, 0, 0);
hz = (hz + 5) % 60;
strip.setPixelColor(hz, 0, 0, 0x1F);
break;
}
case 2: {
strip.setPixelColor(mz, 0, 0, 0);
mz = (mz + 5) % 60;
strip.setPixelColor(mz, 0, 0x1F, 0);
break;
}
case 3: {
strip.setPixelColor(mz, 0, 0, 0);
mz = (mz + 1) % 60;
strip.setPixelColor(mz, 0, 0x1F, 0);
break;
}
case 5: {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
strip.setBrightness(0xFF);
wl = 1; adj = 0;
Serial.println("wlan_started");
break;
}
default:
;
}
} //click
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
udp.beginPacket(address, 123); //NTP requests are to port 123
udp.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket();
} //sendNTPpacket
void setTimefromUdp() {
// We've received a packet, read the data from it
udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
// now convert NTP time into UTC+2 time:
unsigned long utc = (secsSince1900 % 86400L) + 7201L;
if (utc != sek) {
sek = utc;
hz = (sek / 720) % 60;
mz = (sek / 60) % 60;
sz = (sek % 60);
Serial.println("time_adjust");
PrintTime();
}
} // set TimefromUdp
void PrintTime() {
Serial.print(millis()); Serial.print("ms\t");
Serial.print(sek); Serial.print("s\ttime is: ");
Serial.print(int(hz/5)); Serial.print(":");
Serial.print(mz); Serial.print(":");
Serial.print(sz);Serial.print(" \t");
Serial.println(adj);
}