mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	* AtmoOrb UdpSocket-Bind Fix * Cleanup and update defaults (to work via PowerLan) * Cleanup and update defaults (to work via PowerLan) * AtmoOrb identification support, small updates * AtmoOrb discovery & identification support, fixes and stability updates * Small clean-ups * Type fix * Add missing include * Adalight - Update default config and levels * Update Atmoorb sketch * Yeelight - Update default value
		
			
				
	
	
		
			355 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			355 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // AtmoOrb by Lightning303 & Rick164, Additions by Lord-Grey
 | |
| //
 | |
| // ESP8266 Standalone Version
 | |
| //
 | |
| //
 | |
| // You may change the settings that are commented
 | |
| 
 | |
| #define FASTLED_ALLOW_INTERRUPTS 0
 | |
| // To make sure that all leds get changed 100% of the time, we need to allow FastLED to disabled interrupts for a short while.
 | |
| // If you experience problems, please set this value to 1.
 | |
| // This is only needed for 3 wire (1 data line + Vcc and GND) chips (e.g. WS2812B). If you are using WS2801, APA102 or similar chipsets, you can set the value back to 1.
 | |
| 
 | |
| #include <ESP8266WiFi.h>
 | |
| #include <WiFiUdp.h>
 | |
| #include <FastLED.h>
 | |
| 
 | |
| #define NUM_LEDS 24 // Number of leds
 | |
| #define DATA_PIN 7 // Data pin for leds (the default pin 7 might correspond to pin 13 on some boards)
 | |
| #define SERIAL_DEBUG 0 // Serial debugging (0=Off, 1=On)
 | |
| 
 | |
| #define ID 1 // Id of this lamp
 | |
| 
 | |
| // Smoothing
 | |
| #define SMOOTH_STEPS 20 // Steps to take for smoothing colors
 | |
| #define SMOOTH_DELAY 10 // Delay between smoothing steps
 | |
| #define SMOOTH_BLOCK 0 // Block incoming colors while smoothing
 | |
| 
 | |
| // Startup color
 | |
| #define STARTUP_RED 255 // Color shown directly after power on
 | |
| #define STARTUP_GREEN 175 // Color shown directly after power on
 | |
| #define STARTUP_BLUE 100 // Color shown directly after power on
 | |
| 
 | |
| // White adjustment
 | |
| #define RED_CORRECTION 220 // Color Correction
 | |
| #define GREEN_CORRECTION 255 // Color Correction
 | |
| #define BLUE_CORRECTION 180 // Color Correction
 | |
| 
 | |
| // RC Switch
 | |
| #define RC_SWITCH 0 // RF transmitter to swtich remote controlled power sockets (0=Off, 1=On)
 | |
| #if RC_SWITCH == 1
 | |
|   #include <RCSwitch.h>
 | |
|   #define RC_PIN 2 // Data pin for RF transmitter
 | |
|   #define RC_SLEEP_DELAY 900000 // Delay until RF transmitter send signals
 | |
|   char* rcCode0 = "10001"; // First part of the transmission code
 | |
|   char* rcCode1 = "00010"; // Second part of the transmission code
 | |
|   RCSwitch mySwitch = RCSwitch();
 | |
|   boolean remoteControlled = false;
 | |
| #endif
 | |
| 
 | |
| // Network settings
 | |
| const char* ssid = "***"; // WiFi SSID
 | |
| const char* password = "***"; // WiFi password
 | |
| 
 | |
| const IPAddress multicastIP(239,255,255,250); // Multicast IP address
 | |
| const int multicastPort = 49692; // Multicast port number
 | |
| IPAddress    ip_null(0,0,0,0);
 | |
| IPAddress    local_IP(0,0,0,0);
 | |
| WiFiUDP Udp;
 | |
| 
 | |
| int          timeout    = 20000;      // wait 20 sec for successfull login
 | |
| boolean      is_connect = false;      // ... not yet connected
 | |
| 
 | |
| CRGB leds[NUM_LEDS];
 | |
| 
 | |
| byte nextColor[3];
 | |
| byte prevColor[3];
 | |
| byte currentColor[3];
 | |
| byte smoothStep = SMOOTH_STEPS;
 | |
| unsigned long smoothMillis;
 | |
| 
 | |
| void setColor(byte red, byte green, byte blue);
 | |
| void setSmoothColor(byte red, byte green, byte blue);
 | |
| void smoothColor();
 | |
| void clearSmoothColors();
 | |
| 
 | |
| void setup()
 | |
| {
 | |
|   FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
 | |
|   //FastLED.setCorrection(TypicalSMD5050);
 | |
|   FastLED.setCorrection(CRGB(RED_CORRECTION, GREEN_CORRECTION, BLUE_CORRECTION));
 | |
|   FastLED.showColor(CRGB(STARTUP_RED, STARTUP_GREEN, STARTUP_BLUE));
 | |
| 
 | |
|   #if RC_SWITCH == 1
 | |
|     mySwitch.enableTransmit(RC_PIN);
 | |
|   #endif
 | |
| 
 | |
|   #if SERIAL_DEBUG == 1
 | |
|     Serial.begin(115200);
 | |
|   #endif
 | |
| 
 | |
|   #if SERIAL_DEBUG == 1
 | |
|     Serial.printf("Connecting to %s ", ssid);
 | |
|   #endif
 | |
| 
 | |
|   // .... wait for WiFi gets valid !!!
 | |
|   unsigned long tick = millis();      // get start-time for login
 | |
|   WiFi.begin(ssid, password);
 | |
|   while ( (!is_connect) &&  ((millis() - tick) < timeout) )
 | |
|   {
 | |
|     yield();                          // ... for safety
 | |
|     is_connect = WiFi.status();       // connected ?
 | |
|     if (!is_connect)                  // only if not yet connected !
 | |
|     {
 | |
|       #if SERIAL_DEBUG == 1
 | |
|         Serial.print(".");              // print a dot while waiting
 | |
|       #endif
 | |
|       delay(50);
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   if (is_connect)
 | |
|   {
 | |
|     #if SERIAL_DEBUG == 1
 | |
|       Serial.print("after ");
 | |
|       Serial.print(millis() - tick);
 | |
|       Serial.println(" ms");
 | |
|     #endif
 | |
|     // .... wait for local_IP becomes valid !!!
 | |
|     is_connect = false;
 | |
|     tick = millis();      // get start-time for login
 | |
|     while ( (!is_connect) &&  ((millis() - tick) < timeout) )
 | |
|     {
 | |
|       yield();                          // ... for safety
 | |
|       local_IP = WiFi.localIP(); 
 | |
|       is_connect = local_IP != ip_null;       // connected ?
 | |
|       if (!is_connect)                  // only if not yet connected !
 | |
|       {
 | |
|         #if SERIAL_DEBUG == 1
 | |
|           Serial.print(".");              // print a dot while waiting
 | |
|         #endif
 | |
|         delay(50);
 | |
|       }
 | |
|     }
 | |
|     if (is_connect)
 | |
|     {
 | |
|       #if SERIAL_DEBUG == 1
 | |
|         Serial.print("local_IP valid after ");
 | |
|         Serial.print(millis() - tick);
 | |
|         Serial.println(" ms");
 | |
|         Serial.println("");
 | |
|         Serial.print(F("Connected to "));
 | |
|         Serial.println(ssid);
 | |
|       #endif
 | |
| 
 | |
|        // ... now start UDP and check the result:
 | |
|       is_connect = Udp.beginMulticast(local_IP, multicastIP, multicastPort);
 | |
|       if (is_connect)
 | |
|       {
 | |
|         #if SERIAL_DEBUG == 1      
 | |
|           Serial.print("Listening to Multicast at ");
 | |
|           Serial.print(multicastIP);
 | |
|           Serial.println(":" + String(multicastPort));
 | |
|         #endif
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         #if SERIAL_DEBUG == 1      
 | |
|           Serial.println(" - ERROR beginMulticast !");
 | |
|         #endif
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       #if SERIAL_DEBUG == 1     
 | |
|         Serial.println("local_IP invalid after timeout !");
 | |
|       #endif
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     #if SERIAL_DEBUG == 1     
 | |
|       Serial.println("- invalid after timeout !");      
 | |
|     #endif
 | |
|   }
 | |
| }
 | |
| 
 | |
| void loop()
 | |
| {
 | |
|   #if SERIAL_DEBUG == 1
 | |
|     if (WiFi.status() != WL_CONNECTED)
 | |
|     {
 | |
|       Serial.print(F("Lost connection to "));
 | |
|       Serial.print(ssid);
 | |
|       Serial.println(F("."));
 | |
|       Serial.println(F("Trying to reconnect."));
 | |
|       while (WiFi.status() != WL_CONNECTED)
 | |
|       {
 | |
|         delay(500);
 | |
|         Serial.print(F("."));
 | |
|       }
 | |
|       Serial.println("");
 | |
|       Serial.println(F("Reconnected."));
 | |
|     }
 | |
|   #endif
 | |
|   if (Udp.parsePacket())
 | |
|   {
 | |
|     byte len = Udp.available();
 | |
|     byte rcvd[len];
 | |
|     Udp.read(rcvd, len);
 | |
| 
 | |
|     #if SERIAL_DEBUG == 1
 | |
|       Serial.print(F("UDP Packet from "));
 | |
|       Serial.print(Udp.remoteIP());
 | |
|       Serial.print(F(":"));
 | |
|       Serial.print(Udp.remotePort());
 | |
|       Serial.print(F(" to "));
 | |
|       Serial.println(Udp.destinationIP());
 | |
|       for (byte i = 0; i < len; i++)
 | |
|       {
 | |
|         Serial.print(rcvd[i]);
 | |
|         Serial.print(F(" "));
 | |
|       }
 | |
|       Serial.println("");
 | |
|     #endif
 | |
|     if (len >= 8 && rcvd[0] == 0xC0 && rcvd[1] == 0xFF && rcvd[2] == 0xEE && (rcvd[4] == ID || rcvd[4] == 0))
 | |
|     {
 | |
|       switch (rcvd[3])
 | |
|       {
 | |
|         case 1:
 | |
|           smoothStep = SMOOTH_STEPS;
 | |
|           forceLedsOFF();
 | |
|           break;
 | |
|         case 2:
 | |
|         default:
 | |
|           setSmoothColor(rcvd[5], rcvd[6], rcvd[7]);
 | |
|           break;
 | |
|         case 4:
 | |
|           setColor(rcvd[5], rcvd[6], rcvd[7]);
 | |
|           smoothStep = SMOOTH_STEPS;
 | |
|           break;
 | |
|         case 8:
 | |
|           #if SERIAL_DEBUG == 1
 | |
|             Serial.print(F("Announce myself. OrbID: "));
 | |
|             Serial.println(ID);
 | |
|           #endif
 | |
|           Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
 | |
|           Udp.write(ID);
 | |
|           Udp.endPacket();
 | |
|           break;
 | |
|         case 9:
 | |
|           #if SERIAL_DEBUG == 1
 | |
|             Serial.print(F("Identify myself. OrbID: "));
 | |
|             Serial.println(ID);
 | |
|           #endif
 | |
|           identify();
 | |
|           break;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   if (smoothStep < SMOOTH_STEPS && millis() >= (smoothMillis + (SMOOTH_DELAY * (smoothStep + 1))))
 | |
|   {
 | |
|     smoothColor();
 | |
|   }
 | |
|   #if RC_SWITCH == 1
 | |
|     if (remoteControlled && currentColor[0] == 0 && currentColor[1] == 0 && currentColor[2] == 0 && millis() >= smoothMillis + RC_SLEEP_DELAY)
 | |
|     {
 | |
|       // Send this signal only once every seconds
 | |
|       smoothMillis += 1000;
 | |
|       mySwitch.switchOff(rcCode0, rcCode1);
 | |
|     }
 | |
|   #endif
 | |
| }
 | |
| 
 | |
| // Display color on leds
 | |
| void setColor(byte red, byte green, byte blue)
 | |
| {
 | |
|   // Is the new color already active?
 | |
|   if (currentColor[0] == red && currentColor[1] == green && currentColor[2] == blue)
 | |
|   {
 | |
|     return;
 | |
|   }
 | |
|   currentColor[0] = red;
 | |
|   currentColor[1] = green;
 | |
|   currentColor[2] = blue;
 | |
| 
 | |
|   FastLED.showColor(CRGB(red, green, blue));
 | |
| }
 | |
| 
 | |
| // Set a new color to smooth to
 | |
| void setSmoothColor(byte red, byte green, byte blue)
 | |
| {
 | |
|   if (smoothStep == SMOOTH_STEPS || SMOOTH_BLOCK == 0)
 | |
|   {
 | |
|     // Is the new color the same as the one we already are smoothing towards?
 | |
|     // If so dont do anything.
 | |
|     if (nextColor[0] == red && nextColor[1] == green && nextColor[2] == blue)
 | |
|     {
 | |
|       return;
 | |
|     }
 | |
|     // Is the new color the same as we have right now?
 | |
|     // If so stop smoothing and keep the current color.
 | |
|     else if (currentColor[0] == red && currentColor[1] == green && currentColor[2] == blue)
 | |
|     {
 | |
|       smoothStep = SMOOTH_STEPS;
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     prevColor[0] = currentColor[0];
 | |
|     prevColor[1] = currentColor[1];
 | |
|     prevColor[2] = currentColor[2];
 | |
| 
 | |
|     nextColor[0] = red;
 | |
|     nextColor[1] = green;
 | |
|     nextColor[2] = blue;
 | |
| 
 | |
|     smoothMillis = millis();
 | |
|     smoothStep = 0;
 | |
| 
 | |
|     #if RC_SWITCH == 1
 | |
|       if (!remoteControlled)
 | |
|       {
 | |
|         remoteControlled = true;
 | |
|       }
 | |
|     #endif
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Display one step to the next color
 | |
| void smoothColor()
 | |
| {
 | |
|   smoothStep++;
 | |
| 
 | |
|   byte red = prevColor[0] + (((nextColor[0] - prevColor[0]) * smoothStep) / SMOOTH_STEPS);
 | |
|   byte green = prevColor[1] + (((nextColor[1] - prevColor[1]) * smoothStep) / SMOOTH_STEPS);
 | |
|   byte blue = prevColor[2] + (((nextColor[2] - prevColor[2]) * smoothStep) / SMOOTH_STEPS);   
 | |
| 
 | |
|   setColor(red, green, blue);
 | |
| }
 | |
| 
 | |
| // Force all leds OFF
 | |
| void forceLedsOFF()
 | |
| {
 | |
|     setColor(0,0,0);
 | |
|     clearSmoothColors();
 | |
| }
 | |
|  
 | |
| // Clear smooth color byte arrays
 | |
| void clearSmoothColors()
 | |
| {
 | |
|     memset(prevColor, 0, sizeof(prevColor));
 | |
|     memset(currentColor, 0, sizeof(nextColor));
 | |
|     memset(nextColor, 0, sizeof(nextColor));
 | |
| }
 | |
| 
 | |
| void identify()
 | |
| {
 | |
|   for (byte i = 0; i < 3; i++)
 | |
|   {
 | |
|     FastLED.showColor(CRGB::LemonChiffon);
 | |
|     delay(500);
 | |
|     FastLED.showColor(CRGB::Black);   
 | |
|     delay(500);
 | |
|   }
 | |
| }
 |