Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <NeoPixelBus.h>
- #include <ESP8266WiFi.h>
- #include <unordered_map>
- #include <vector>
- //#define serial_dbg
- const uint16_t PixelCount = 858; // Exactly 858 LEDs (0 to 857)
- const uint8_t PixelPin = 2;
- const char* ssid = "#######"; // privacy :P
- const char* password = "#######"; // privacy :P
- const byte MSG_BEGIN = 0xF0;
- const byte C_ACTIVE = 0xC0;
- const byte C_OFF = 0xC1;
- const byte C_ON = 0xC2;
- const byte C_RGBW = 0xC3;
- const byte C_STATUS = 0xC4;
- const byte C_RGBW_RANGE = 0xC5;
- const byte CA_OK = 0xA0;
- const byte CA_STATUS = 0xA1;
- const byte CA_ERROR = 0xAF;
- const unsigned long switchThreshold = 1000;
- WiFiServer server(22255);
- NeoPixelBus<NeoGrbwFeature, NeoEsp8266Uart1800KbpsMethod> strip(PixelCount, PixelPin);
- WiFiClient stdClient;
- //RgbwColor currentCol;
- bool whiteLight;
- bool isOn;
- int lastSwitch;
- unsigned long switchTime;
- //short first, last;
- unsigned long nextCheck;
- struct RgbwHash {
- std::size_t operator()(RgbwColor const& col) const noexcept {
- return std::hash<int>{}((col.R << 12) | (col.G << 8) | (col.B << 4) | col.W);
- }
- };
- const int lineIndex[] = { 0, 63, // llWR ( 64 LEDs)
- 64, 163, // llWB (100 LEDs)
- 164, 227, // llWL ( 64 LEDs)
- 228, 327, // llWF (100 LEDs)
- 328, 393, // llDL ( 66 LEDs)
- 394, 493, // llDF (100 LEDs)
- 494, 558, // llDR ( 65 LEDs)
- 559, 656, // llDB ( 98 LEDs)
- 657, 668, // llTW ( 12 LEDs)
- 669, 711, // llTC ( 43 LEDs)
- 712, 741, // llTP ( 30 LEDs)
- 742, 754, // llTS ( 13 LEDs)
- 755, 797, // llTB ( 43 LEDs)
- 798, 857 }; // llB ( 60 LEDs)
- RgbwColor lineColors[14];
- void updateLight() {
- if (!isOn) {
- strip.ClearTo(RgbwColor(0, 0, 0, 0));
- }
- else {
- if (whiteLight) {
- strip.ClearTo(RgbwColor(0, 0, 0, 128), 0, 656); // Clear all ceiling strips to white
- strip.ClearTo(RgbwColor(0, 0, 0, 0), 657, 857); // And the rest to black
- }
- else {
- for (int i = 0; i < 14; i++) {
- strip.ClearTo(lineColors[i], lineIndex[2 * i], lineIndex[(2 * i) + 1]);
- }
- }
- }
- strip.Show();
- #ifdef serial_dbg
- Serial.println("Light updated, new Values are:");
- for (int i = 0; i < 14; i++) {
- Serial.println(String(i) + ": " + String(lineColors[i].R) + " , " + String(lineColors[i].G) + " , " + String(lineColors[i].B) + " , " + String(lineColors[i].W));
- }
- #endif
- }
- void sendStatus(WiFiClient& client) {
- std::vector<byte> barr;
- barr.push_back(MSG_BEGIN);
- barr.push_back(CA_STATUS);
- barr.push_back((byte)isOn);
- std::unordered_map<RgbwColor, uint16_t, RgbwHash> map;
- std::unordered_map<RgbwColor, uint16_t, RgbwHash>::iterator it;
- for (int i = 0; i < 14; i++) {
- it = map.find(lineColors[i]);
- if (it != map.end()) {
- it->second = it->second | (1 << i);
- }
- else {
- map.emplace(lineColors[i], 1 << i);
- }
- }
- for (auto item : map) {
- barr.push_back(highByte(item.second));
- barr.push_back(lowByte(item.second));
- barr.push_back(item.first.R);
- barr.push_back(item.first.G);
- barr.push_back(item.first.B);
- barr.push_back(item.first.W);
- }
- client.write(barr.data(), barr.size());
- #ifdef serial_dbg
- Serial.println("Sending CA_STATUS");
- #endif
- }
- void runCommand(WiFiClient& client) {
- /*byte mess[128] = { 0 };
- client.peekBytes(mess, 128);
- Serial.print("Client Message is: ");
- for (byte b : mess) {
- Serial.print(String(b) + " ");
- }*/
- if (client.read() != MSG_BEGIN) exit;
- byte cmd = client.read();
- //Serial.println("Client Command is " + String(cmd));
- switch (cmd) {
- case C_ACTIVE: {
- if (!stdClient.connected()) {
- stdClient = client;
- #ifdef serial_dbg
- Serial.println("Sending CA_OK");
- #endif
- }
- break;
- }
- case C_OFF: {
- if (isOn) {
- isOn = false;
- updateLight();
- sendStatus(client);
- }
- break;
- }
- case C_ON: {
- if (!isOn) {
- isOn = true;
- updateLight();
- sendStatus(client);
- }
- break;
- }
- case C_RGBW: {
- #ifdef serial_dbg
- Serial.println(String(client.available()));
- #endif
- do {
- uint16_t mask = (client.read() << 8) | client.read();
- #ifdef serial_dbg
- Serial.println(String(mask, BIN));
- #endif
- RgbwColor currCol = RgbwColor(client.read(), client.read(), client.read(), client.read());
- #ifdef serial_dbg
- Serial.println("CurrCol: " + String(currCol.R) + " , " + String(currCol.G) + " , " + String(currCol.B) + " , " + String(currCol.W));
- #endif
- for (int i = 0; i < 14; i++) {
- if (mask & (1 << i)) {
- lineColors[i] = currCol;
- #ifdef serial_dbg
- Serial.println("Line " + String(i) + " | " + String(currCol.R) + " , " + String(currCol.G) + " , " + String(currCol.B) + " , " + String(currCol.W));
- #endif
- }
- }
- } while (client.available() >= 6);
- isOn = true;
- updateLight();
- sendStatus(client);
- break;
- }
- case C_STATUS: {
- sendStatus(client);
- break;
- }
- default:
- break;
- }
- }
- void setup() {
- // put your setup code here, to run once:
- #ifdef serial_dbg
- Serial.begin(115200);
- while (!Serial);
- Serial.println();
- Serial.println();
- Serial.print("Connecting to WiFi ");
- Serial.println(ssid);
- #endif
- WiFi.mode(WIFI_STA);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- #ifdef serial_dbg
- Serial.print(".");
- #endif
- }
- #ifdef serial_dbg
- Serial.println("");
- Serial.println("WiFi connected");
- #endif
- server.begin();
- #ifdef serial_dbg
- Serial.println("Server started at port 22255");
- Serial.println(WiFi.localIP());
- #endif
- strip.Begin();
- strip.Show();
- #ifdef serial_dbg
- Serial.println("LEDs initialized");
- #endif
- //currentCol = RgbwColor(0, 0, 0, 127);
- for (int i = 0; i < 14; i++) {
- lineColors[i] = RgbwColor(0, 0, 0, 64);
- }
- isOn = true;
- whiteLight = true;
- switchTime = 0;
- pinMode(3, INPUT);
- lastSwitch = digitalRead(3);
- #ifdef serial_dbg
- Serial.println("Status of Switch: " + String(lastSwitch));
- #endif
- updateLight();
- #ifdef serial_dbg
- Serial.println("Running...");
- #endif
- }
- void loop() {
- // Light Switch
- unsigned long currentTime = millis();
- if (currentTime > nextCheck) {
- if (digitalRead(3) != lastSwitch) {
- lastSwitch = digitalRead(3);
- #ifdef serial_dbg
- Serial.println("Status changed to: " + String(lastSwitch));
- #endif
- isOn = !isOn;
- if (isOn) {
- if (!whiteLight && switchTime != 0 && currentTime - switchTime <= switchThreshold) {
- whiteLight = true;
- }
- else {
- whiteLight = false;
- }
- switchTime = 0;
- }
- else {
- switchTime = currentTime;
- }
- updateLight();
- }
- nextCheck = currentTime + 50;
- }
- // Message handling
- if (stdClient.available() > 0) {
- #ifdef serial_dbg
- Serial.println("sdtClient message");
- #endif
- runCommand(stdClient);
- stdClient.flush();
- }
- else {
- WiFiClient client = server.available();
- if (!client) return;
- int del = 0;
- #ifdef serial_dbg
- Serial.println("New Client");
- #endif
- while (!client.available()) {
- if (del == 500) {
- #ifdef serial_dbg
- Serial.println("Timeout, client disconnected");
- #endif
- return;
- }
- ++del;
- delay(5);
- }
- runCommand(client);
- client.flush();
- #ifdef serial_dbg
- Serial.println("Client Disconnected");
- #endif
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment