Created
May 6, 2021 02:40
-
-
Save OSDDQD/fb18c4b3d57c226186df58b1c1c37ed2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define FASTLED_ALLOW_INTERRUPTS 0 | |
#include "ESP8266WiFi.h" | |
#include "WiFiUdp.h" | |
#include "ESP8266httpUpdate.h" | |
#include "FastLED.h" | |
#include "FlexTimer.h" | |
#include "FastFX.h" | |
#include "FFXCoreEffects.h" | |
#define PIR_PIN 14 | |
#define LED_PIN 6 | |
#define COB_PIN 2 | |
#define NUM_LEDS 500 | |
#define LEVELS 12 | |
#define BASE_BRIGHTNESS 10 | |
#define BASE_INTERVAL 5 | |
#define IP 40 // адрес станции, уникальный для каждого | |
#define NEXT_IP 41 | |
#define PREV_IP 45 | |
#define WIFI_SSID "LEDSTATE" | |
#define WIFI_PASS "123456789" | |
#define UDP_PORT 4210 | |
// UDP | |
WiFiUDP UDP; | |
char packet[255]; | |
char reply[] = "Packet received!"; | |
IPAddress next_IP(192, 168, 0, NEXT_IP); | |
IPAddress prev_IP(192, 168, 0, PREV_IP); | |
// Set your Static IP address | |
IPAddress local_IP(192, 168, 1, IP); | |
// Set your Gateway IP address | |
IPAddress gateway(192, 168, 1, 1); | |
IPAddress subnet(255, 255, 255, 0); | |
int level = 1; | |
int brightness = 0; | |
boolean cooldown = false; | |
String segName; | |
//String segments[] = {"R1", "R1B", "R2", "R2B", "R3", "R3B", "R4", "R4B", "R5", "R5B", "R6", "R6B"}; | |
String segments[] = {"R1", "R2", "R3", "R4", "R5", "R6"}; | |
int segmentsCount = sizeof(segments) / sizeof(segments[0]); | |
// This is an array of leds. One item for each led in your strip. | |
CRGB leds[NUM_LEDS]; | |
FFXController fxctrlr = FFXController(); | |
StepTimer TimerC(5000); | |
class WowOverlayFX : public FFXOverlay { | |
public: | |
WowOverlayFX( uint16_t initSize, uint8_t speed, uint8_t repeat ) : FFXOverlay(initSize, speed, repeat, 0) { | |
// fxName = WOW_OVLY_FX_NAME; | |
currColor.setColorMode(FFXColor::FFXColorMode::palette256); | |
setMovement(MVT_FORWARD); | |
setMaxAlpha(255); | |
setVCycleRange(90); | |
setPixelRange(0, numLeds - 1); | |
} | |
WowOverlayFX( uint16_t initSize, uint8_t speed, uint8_t repeat, const CRGBPalette16 &pal) : WowOverlayFX(initSize, speed, repeat) { | |
currColor.setPalette(pal); | |
} | |
void setPixelRange( uint16_t lo, uint16_t hi ) { | |
rangeLo = lo > (numLeds - 1) ? numLeds - 1 : lo; | |
rangeHi = hi < rangeLo ? rangeLo : ( hi > (numLeds - 1) ? (numLeds - 1) : hi ); | |
rangeMid = (rangeHi - rangeLo + 1) / 2; | |
} | |
virtual void initLeds(CRGB *bufLeds ) override { | |
for (uint16_t i = rangeLo; i <= rangeHi; i++) { | |
bufLeds[i] = CRGB::Aqua; | |
} | |
setUpdated(true); | |
} | |
virtual void onVCycleStart( CRGB *currFrame ) override { | |
// set all pixels to transparent | |
// clearAlpha(); | |
// if starting in the center - set the middle 3 pixels opaque and move outward from there... | |
if (getCurrMovement(getCurrVCycle()) == MVT_BACKWARD) { | |
// alpha[rangeMid + 1] = 255; | |
// alpha[rangeMid] = 255; | |
// alpha[rangeMid - 1] = 255; | |
} | |
// call parent class' method in case it needs to do something | |
FFXOverlay::onVCycleStart( currFrame ); | |
} | |
virtual void onVCycleEnd( CRGB *currFrame ) override { | |
// clearAlpha(); | |
// call parent class' method in case it needs to do something | |
FFXOverlay::onVCycleEnd( currFrame ); | |
} | |
virtual void writeNextFrame( CRGB *bufLeds ) override { | |
uint8_t a; | |
uint16_t vindex = fixed_map( getMovementVPhase(), 1, getVCycleRange(), rangeLo, rangeHi); | |
if (vindex <= rangeMid) { | |
a = (getCurrMovement(getCurrVCycle()) == MVT_BACKWARD) ? 0 : 255; | |
fadeToBlackBy(bufLeds, numLeds , 18); | |
// fadeToBlackBy(bufLeds, numLeds, 16); | |
alpha[vindex] = a; | |
// fadeToBlackBy(bufLeds, numLeds, 5); | |
alpha[mirror(vindex)] = a; | |
} else { | |
// for (int i = 0; i <= 20; i++) { | |
fadeToBlackBy(bufLeds, numLeds , 5); | |
// } | |
} | |
setUpdated(true); | |
} | |
private: | |
uint16_t rangeLo = 0; | |
uint16_t rangeHi = 0; | |
uint16_t rangeMid = 0; | |
uint16_t slowdown = 1000; | |
}; | |
class FirstLightFX : public FFXBase { | |
public: | |
FirstLightFX(uint16_t initSize) : FFXBase( initSize,/* interval */ 15UL, | |
/* min interval */ 15UL, | |
/* max interval */ 30UL ) { | |
getFXColor().setColorMode( FFXColor::FFXColorMode::singleCRGB); | |
getFXColor().setCRGB( CRGB::Aqua); | |
} | |
virtual void initLeds( CRGB *bufLeds ) override { | |
fill_solid( bufLeds, numLeds, CRGB::Black); | |
} | |
virtual void writeNextFrame( CRGB *bufLeds ) override { | |
// fadeToBlackBy(bufLeds, numLeds, 25); | |
// bufLeds[getMovementPhase() - 1] = currColor.getCRGB(); | |
} | |
}; | |
void setup() { | |
// sanity check delay - allows reprogramming if accidently blowing power w/leds | |
delay(30000); | |
// initialize serial communication at 115200 | |
Serial.begin(115200); | |
if (!WiFi.config(local_IP, gateway, subnet)) { | |
Serial.println("STA Failed to configure"); | |
} | |
// Begin WiFi | |
WiFi.begin(WIFI_SSID, WIFI_PASS); | |
// Connecting to WiFi... | |
Serial.print("Connecting to "); | |
Serial.print(WIFI_SSID); | |
// Loop continuously while WiFi is not connected | |
while (WiFi.status() != WL_CONNECTED) | |
{ | |
delay(100); | |
Serial.print("."); | |
} | |
// Connected to WiFi | |
Serial.println(); | |
Serial.print("Connected! IP address: "); | |
Serial.println(WiFi.localIP()); | |
// Begin listening to UDP port | |
UDP.begin(UDP_PORT); | |
Serial.print("Listening on UDP port "); | |
Serial.println(UDP_PORT); | |
// pinMode(LED_PIN, OUTPUT); | |
initLeds(); | |
// pinMode(PIR_PIN, INPUT); | |
// digitalWrite(PIR_PIN, LOW); | |
// PIRTimer.start(); | |
} | |
void initLeds() | |
{ | |
FastLED.addLeds<WS2811, LED_PIN, RBG>(leds, NUM_LEDS); | |
FastLED.clear(); | |
fxctrlr.initialize( new FFXFastLEDPixelController( leds, NUM_LEDS )); | |
fxctrlr.getPrimarySegment()->setFX( new FirstLightFX( NUM_LEDS )); | |
fxctrlr.getPrimarySegment()->setBrightness( BASE_BRIGHTNESS ); | |
fxctrlr.getPrimarySegment()->getFX()->setInterval( BASE_INTERVAL ); | |
fxctrlr.getPrimarySegment()->getFX()->setMovement( FFXBase::MovementType::MVT_FORWARD ); | |
fxctrlr.getPrimarySegment()->getFX()->getFXColor().setColorMode( FFXColor::FFXColorMode::singleCRGB ); | |
fxctrlr.getPrimarySegment()->getFX()->getFXColor().setCRGB( CRGB::Black ); | |
// Setup segments... | |
FFXSegment *seg; | |
seg = fxctrlr.addSegment( "R1", 0, 61 ); | |
seg->setFX( new FirstLightFX( seg->getLength() )); | |
seg->getFX()->getFXColor().setCRGB( CRGB::Black); | |
seg->getFX()->setMovement( FFXBase::MovementType::MVT_FORWARD); | |
seg->setOpacity(255); | |
seg = fxctrlr.addSegment("R2", 62, 143); | |
seg->setFX( new FirstLightFX( seg->getLength() )); | |
seg->getFX()->getFXColor().setCRGB( CRGB::Black); | |
seg->getFX()->setMovement( FFXBase::MovementType::MVT_FORWARD); | |
seg->setOpacity(255); | |
seg = fxctrlr.addSegment("R3", 144, 249); | |
seg->setFX( new FirstLightFX( seg->getLength() )); | |
seg->getFX()->getFXColor().setCRGB( CRGB::Black); | |
seg->getFX()->setMovement( FFXBase::MovementType::MVT_FORWARD); | |
seg->setOpacity(255); | |
seg = fxctrlr.addSegment("R4", 250, 349); | |
seg->setFX( new FirstLightFX( seg->getLength() )); | |
seg->getFX()->getFXColor().setCRGB( CRGB::Black); | |
seg->getFX()->setMovement( FFXBase::MovementType::MVT_FORWARD); | |
seg->setOpacity(255); | |
seg = fxctrlr.addSegment("R5", 350, 415); | |
seg->setFX( new FirstLightFX( seg->getLength() )); | |
seg->getFX()->getFXColor().setCRGB( CRGB::Black); | |
seg->getFX()->setMovement( FFXBase::MovementType::MVT_FORWARD); | |
seg->setOpacity(255); | |
seg = fxctrlr.addSegment("R6", 416, 477); | |
seg->setFX( new FirstLightFX( seg->getLength() )); | |
seg->getFX()->getFXColor().setCRGB( CRGB::Black); | |
seg->getFX()->setMovement( FFXBase::MovementType::MVT_FORWARD); | |
seg->setOpacity(255); | |
} | |
void loop() { | |
// PIRRead(); | |
fxctrlr.update(); | |
int interval = random(5, 60); | |
Serial.print("INTERVAL: "); | |
Serial.println(interval); | |
if(!cooldown) { | |
EVERY_N_SECONDS(interval){ | |
setLighting(); | |
} | |
} | |
// If packet received... | |
int packetSize = UDP.parsePacket(); | |
if (packetSize) { | |
Serial.print("SIGNAL RECEIVED!"); | |
Serial.println(packetSize); | |
int len = UDP.read(packet, 255); | |
if (len > 0) { | |
setLighting(); | |
TimerC.start(); | |
cooldown = true; | |
} | |
Serial.print("Packet received: "); | |
Serial.println(packet); | |
} | |
if(TimerC.isUp()) { | |
cooldown = false; | |
} | |
} | |
void setLighting() | |
{ | |
if (level >= LEVELS) { | |
level = 0; | |
} | |
if (level < LEVELS) { | |
level++; | |
brightness = (255 / LEVELS) * level; | |
if (level == LEVELS) { | |
brightness = 255; | |
} | |
} | |
Serial.print("BRIGHTNESS: "); | |
Serial.println(brightness); | |
Serial.print("LEVEL: "); | |
Serial.println(level); | |
// fxctrlr.getPrimarySegment()->getFX()->setInterval( BASE_INTERVAL * level ); | |
fxctrlr.getPrimarySegment()->setBrightness(brightness); | |
FFXSegment *seg; | |
FFXOverlay *newOvl; | |
Serial.print("SEGMENTS: "); | |
Serial.println(segmentsCount); | |
for (int i = 0; i < segmentsCount; i++) { | |
segName = segments[i]; | |
Serial.print("SEGMENT NAME: "); | |
Serial.println(segName); | |
seg = fxctrlr.findSegment(segName); | |
if (seg) { | |
Serial.print("SEGMENT TRUE: "); | |
Serial.println(segName); | |
newOvl = new WowOverlayFX(seg->getLength(), 255, 1); // speed: 255, cycles: 1 | |
newOvl->setMovement( FFXBase::MovementType::MVT_FORWARD ); | |
newOvl->setMaxAlpha(brightness); // opacity - 255 is max | |
seg->setOverlay(newOvl); | |
} | |
} | |
UDP.beginPacket(next_IP, UDP_PORT); | |
UDP.write(reply); | |
UDP.endPacket(); | |
UDP.beginPacket(prev_IP, UDP_PORT); | |
UDP.write(reply); | |
UDP.endPacket(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment