From bb15c289364fb8da4ecf51c65eb824c3119c8f26 Mon Sep 17 00:00:00 2001 From: JelleWie <1545223+jellewie@users.noreply.github.com> Date: Wed, 28 Oct 2020 13:25:46 +0100 Subject: [PATCH 1/5] tried to add PHYSICS animation --- Arduino/Animation.h | 32 +++++++++++++++++++++++++++++++- Arduino/Arduino.ino | 2 ++ Arduino/functions.h | 4 ++-- Arduino/handler.ino | 2 +- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Arduino/Animation.h b/Arduino/Animation.h index 2f23bca..04dd46f 100644 --- a/Arduino/Animation.h +++ b/Arduino/Animation.h @@ -13,7 +13,7 @@ Arduino.ino: Add the caller to 'switch (Mode) {' as a new case 'case ###: if (LastMode != Mode) StartAnimation(xxx, -2); break;'. where ### is the enum name and xxx ths ID in the 'switch (CurrentAnimation)' */ byte CurrentAnimation; //Which AnimationCounter Animation is selected -byte TotalAnimations = 12; +byte TotalAnimations = 13; CRGB AnimationRGB = {0, 0, 0}; //================================================== @@ -350,6 +350,36 @@ void ShowAnimation(bool Start) { //This would be called to show an Animati UpdateLEDs = true; } } break; + case 13: { //PHYSICS + static byte Counter = 0; + static CRGB LEDsStart[TotalLEDs]; + if (Start) { + LED_Rainbow(0, TotalLEDs, 255 / TotalLEDs); //Init with rainbow color, so we have something to work with + + memcpy(LEDsStart, LEDs, TotalLEDs * 3); //Save the start position so we can refference it later, amount*3 since we use 3 colors: RGB + //Amount = sizeof(LEDs) / sizeof(LEDs[0]); + + Counter = 0; //Reset the counter + } + EVERY_N_MILLISECONDS(250) { + for (byte i = 0; i < TotalLEDs; i++) { + + //https://www.desmos.com/calculator/g4ccytokl8 + float _pos = cos((i + Counter) / 9.55) * 30 + 30; + LEDs[i] = LEDsStart[LEDtoPosition(_pos)]; + + + //LEDs[i] = LEDsStart[LEDtoPosition(i + Counter)]; + } + Counter++; + if (Counter >= TotalLEDs) + Counter = 0; + + LEDs[Counter] = CRGB(0, 0, 255); //Just add a rotating RED LED, so we know the code still works + + UpdateLEDs = true; + } + } break; default: AnimationCounter = 0; //Stop animation diff --git a/Arduino/Arduino.ino b/Arduino/Arduino.ino index c4a853f..9cdddec 100644 --- a/Arduino/Arduino.ino +++ b/Arduino/Arduino.ino @@ -254,6 +254,8 @@ void loopLEDS() { case SMILEY: if (LastMode != Mode) StartAnimation(10, -2); break; case FLASH2: if (LastMode != Mode) StartAnimation(11, -2); break; case PACMAN: if (LastMode != Mode) StartAnimation(12, -2); break; + case PHYSICS: if (LastMode != Mode) StartAnimation(13, -2); break; + default: #ifdef SerialEnabled Serial.println("mode with ID " + String(Mode) + " not found"); diff --git a/Arduino/functions.h b/Arduino/functions.h index aef2031..5d0184f 100644 --- a/Arduino/functions.h +++ b/Arduino/functions.h @@ -6,10 +6,10 @@ struct TimeS { unsigned long Ticks; }; enum Modes {OFF, ON, WIFI, RESET, CLOCK, - BLINK, BPM, CONFETTI, FLASH, GLITTER, JUGGLE, MOVE, RAINBOW, SINELON, SINELON2, SMILEY, FLASH2, PACMAN + BLINK, BPM, CONFETTI, FLASH, GLITTER, JUGGLE, MOVE, RAINBOW, SINELON, SINELON2, SMILEY, FLASH2, PACMAN, PHYSICS }; //Just to make the code more clear to read, OFF=0 and ON=1 etc String ModesString[] = {"OFF", "ON", "WIFI", "RESET", "CLOCK", - "BLINK", "BPM", "CONFETTI", "FLASH", "GLITTER", "JUGGLE", "MOVE", "RAINBOW", "SINELON", "SINELON2", "SMILEY", "FLASH2", "PACMAN" + "BLINK", "BPM", "CONFETTI", "FLASH", "GLITTER", "JUGGLE", "MOVE", "RAINBOW", "SINELON", "SINELON2", "SMILEY", "FLASH2", "PACMAN", "PHYSICS" }; //ALL CAPS! const byte Modes_Amount = sizeof(ModesString) / sizeof(ModesString[0]); //Why filling this in if we can automate that? :) diff --git a/Arduino/handler.ino b/Arduino/handler.ino index 6bef9ce..770477f 100644 --- a/Arduino/handler.ino +++ b/Arduino/handler.ino @@ -216,7 +216,7 @@ void handle_OnConnect() { "let Sg=new Slider('Green');" "let Sb=new Slider('Blue');" - "let Dm=new DropDown({name:'Mode',setParamName:'m',possibleValues:['OFF','ON','WIFI','CLOCK','BLINK','BPM','CONFETTI','FLASH','FLASH2','GLITTER','JUGGLE','MOVE','PACMAN','RAINBOW','SINELON','SINELON2','SMILEY'],modifySendParams:(oldParams)=>{if(Dm.value=='WIFI'){let extraData=this.getServerStateMessageData();return{...oldParams,...extraData};}},});" + "let Dm=new DropDown({name:'Mode',setParamName:'m',possibleValues:['OFF','ON','WIFI','CLOCK','BLINK','BPM','CONFETTI','PHYSICS','FLASH','FLASH2','GLITTER','JUGGLE','MOVE','PACMAN','RAINBOW','SINELON','SINELON2','SMILEY'],modifySendParams:(oldParams)=>{if(Dm.value=='WIFI'){let extraData=this.getServerStateMessageData();return{...oldParams,...extraData};}},});" "let Dbm=new DropDown({name:'Bootmode',setParamName:'bm',possibleValues:['OFF','ON','WIFI','CLOCK']});" "let Ddm=new DropDown({name:'Doublepress mode',setParamName:'dm',possibleValues:['WIFI','CLOCK','BLINK','RAINBOW']});" From a9b77a9f29d00382b9c1ab895ae6a284b5bf42d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelle=20Wie=C2=BF?= <1545223+jellewie@users.noreply.github.com> Date: Fri, 21 May 2021 00:17:31 +0200 Subject: [PATCH 2/5] Tried to make it work, but there is a overflow or something --- Arduino/Structs.h | 4 ++-- Arduino/handler.ino | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Arduino/Structs.h b/Arduino/Structs.h index 178875b..f825913 100644 --- a/Arduino/Structs.h +++ b/Arduino/Structs.h @@ -6,10 +6,10 @@ struct TimeS { unsigned long Ticks; }; enum Modes {OFF, ON, WIFI, RESET, CLOCK, - BLINK, BPM, CONFETTI, FLASH, GLITTER, JUGGLE, MOVE, RAINBOW, SINELON, SINELON2, SMILEY, FLASH2, PACMAN + BLINK, BPM, CONFETTI, FLASH, GLITTER, JUGGLE, MOVE, RAINBOW, SINELON, SINELON2, SMILEY, FLASH2, PACMAN, PHYSICS }; //Just to make the code more clear to read, OFF=0 and ON=1 etc String ModesString[] = {"OFF", "ON", "WIFI", "RESET", "CLOCK", - "BLINK", "BPM", "CONFETTI", "FLASH", "GLITTER", "JUGGLE", "MOVE", "RAINBOW", "SINELON", "SINELON2", "SMILEY", "FLASH2", "PACMAN" + "BLINK", "BPM", "CONFETTI", "FLASH", "GLITTER", "JUGGLE", "MOVE", "RAINBOW", "SINELON", "SINELON2", "SMILEY", "FLASH2", "PACMAN", "PHYSICS" }; //ALL CAPS! const byte Modes_Amount = sizeof(ModesString) / sizeof(ModesString[0]);//Why filling this in if we can automate that? :) diff --git a/Arduino/handler.ino b/Arduino/handler.ino index ce4c073..ce71029 100644 --- a/Arduino/handler.ino +++ b/Arduino/handler.ino @@ -230,7 +230,7 @@ void handle_OnConnect() { "let Sg=new Slider('Green');" "let Sb=new Slider('Blue');" - "let Dm=new DropDown({name:'Mode',setParamName:'m',possibleValues:['OFF','ON','WIFI','CLOCK','BLINK','BPM','CONFETTI','PHYSICS','FLASH','FLASH2','GLITTER','JUGGLE','MOVE','PACMAN','RAINBOW','SINELON','SINELON2','SMILEY'],modifySendParams:(oldParams)=>{if(Dm.value=='WIFI'){let extraData=this.getServerStateMessageData();return{...oldParams,...extraData};}},});" + "let Dm=new DropDown({name:'Mode',setParamName:'m',possibleValues:['OFF','ON','WIFI','CLOCK','BLINK','BPM','CONFETTI','FLASH','FLASH2','GLITTER','JUGGLE','MOVE','PACMAN','PHYSICS','RAINBOW','SINELON','SINELON2','SMILEY'],modifySendParams:(oldParams)=>{if(Dm.value=='WIFI'){let extraData=this.getServerStateMessageData();return{...oldParams,...extraData};}},});" "let Dbm=new DropDown({name:'Bootmode',setParamName:'bm',possibleValues:['OFF','ON','WIFI','CLOCK']});" "let Ddm=new DropDown({name:'Doublepress mode',setParamName:'dm',possibleValues:['WIFI','CLOCK','BLINK','RAINBOW']});" From 0b21f2d0ae2a06947b82f2c8b940d79c4fdd95bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelle=20Wie=C2=BF?= <1545223+jellewie@users.noreply.github.com> Date: Fri, 21 May 2021 00:36:15 +0200 Subject: [PATCH 3/5] It forgot to save this part The is the most important part, so that was weird --- Arduino/Animation.h | 46 +++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/Arduino/Animation.h b/Arduino/Animation.h index e0b1b30..49d0f1f 100644 --- a/Arduino/Animation.h +++ b/Arduino/Animation.h @@ -248,37 +248,43 @@ void ShowAnimation(bool Start) { //This would be UpdateLEDs = true; } } break; - case 13: { //PHYSICS - static byte Counter = 0; - static CRGB LEDsStart[TotalLEDs]; + + case 13: { //PHYSICS +#define Speed -0.02 +#define Drag 0.981 + CRGB Saved_Color[TotalLEDsClock]; + float Position[TotalLEDsClock]; + float Velocity[TotalLEDsClock]; if (Start) { - LED_Rainbow(0, TotalLEDs, 255 / TotalLEDs); //Init with rainbow color, so we have something to work with - memcpy(LEDsStart, LEDs, TotalLEDs * 3); //Save the start position so we can refference it later, amount*3 since we use 3 colors: RGB - //Amount = sizeof(LEDs) / sizeof(LEDs[0]); + LED_Rainbow(0, TotalLEDsClock, 255 / TotalLEDsClock); - Counter = 0; //Reset the counter + for (int i = 0; i < TotalLEDsClock; i++) { + Position[i] = i; + Saved_Color[i].r = LEDs[i].r; + Saved_Color[i].g = LEDs[i].g; + Saved_Color[i].b = LEDs[i].b; + } + //memcpy(Saved_Color, LEDs, sizeof(Saved_Color)); //Destination, Source, Size http://www.cplusplus.com/reference/cstring/memcpy/ } - EVERY_N_MILLISECONDS(250) { - for (byte i = 0; i < TotalLEDs; i++) { +#define ANIMATION_TIME_PHYSICS 1000/30 + EVERY_N_MILLISECONDS(ANIMATION_TIME_PHYSICS) { + LED_Fill(1, TotalLEDsClock - 1, CRGB(0, 0, 0), TotalLEDsClock); //Clear All LEDs so we start from a blank slate - //https://www.desmos.com/calculator/g4ccytokl8 - float _pos = cos((i + Counter) / 9.55) * 30 + 30; - LEDs[i] = LEDsStart[LEDtoPosition(_pos)]; + LED_Flash(0, 1, CRGB(255, 0, 0), CRGB(0, 0, 255), TotalLEDsClock); + for (int i = 0; i < TotalLEDsClock; i++) { + float Acceleration = Speed * (Position[i] - TotalLEDsClock / 2);//Calculate howmuch we wish to move (just linear) https://www.desmos.com/calculator/ljo4mllyzq y=-\frac{1}{2}\left(x-b\right) + Velocity[i] = Velocity[i] * Drag + Acceleration; //Set the Velocity to be (the speed we shere add) * (Drag) + (howmuch we wish to move) + Position[i] = Position[i] + Velocity[i]; //Calculate new position + //LED_Add(LEDtoPosition(round(Position[i])), 1, Saved_Color[i], TotalLEDsClock); //Draw the LED - //LEDs[i] = LEDsStart[LEDtoPosition(i + Counter)]; + int _LedPos = round(Position[i]); + LED_Fill(LEDtoPosition(_LedPos), 1, CRGB(0, 0, 255)); } - Counter++; - if (Counter >= TotalLEDs) - Counter = 0; - - LEDs[Counter] = CRGB(0, 0, 255); //Just add a rotating RED LED, so we know the code still works - UpdateLEDs = true; } } break; - default: AnimationCounter = 0; //Stop animation #ifdef SerialEnabled From f893809c83d21c1e009baa07548d94c8eb381980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelle=20Wie=C2=BF?= <1545223+jellewie@users.noreply.github.com> Date: Fri, 21 May 2021 00:50:45 +0200 Subject: [PATCH 4/5] Changed it in such a form how it should work --- Arduino/Animation.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Arduino/Animation.h b/Arduino/Animation.h index 49d0f1f..68ab346 100644 --- a/Arduino/Animation.h +++ b/Arduino/Animation.h @@ -248,7 +248,6 @@ void ShowAnimation(bool Start) { //This would be UpdateLEDs = true; } } break; - case 13: { //PHYSICS #define Speed -0.02 #define Drag 0.981 @@ -267,7 +266,7 @@ void ShowAnimation(bool Start) { //This would be } //memcpy(Saved_Color, LEDs, sizeof(Saved_Color)); //Destination, Source, Size http://www.cplusplus.com/reference/cstring/memcpy/ } -#define ANIMATION_TIME_PHYSICS 1000/30 +#define ANIMATION_TIME_PHYSICS 1000/10 EVERY_N_MILLISECONDS(ANIMATION_TIME_PHYSICS) { LED_Fill(1, TotalLEDsClock - 1, CRGB(0, 0, 0), TotalLEDsClock); //Clear All LEDs so we start from a blank slate @@ -277,14 +276,12 @@ void ShowAnimation(bool Start) { //This would be float Acceleration = Speed * (Position[i] - TotalLEDsClock / 2);//Calculate howmuch we wish to move (just linear) https://www.desmos.com/calculator/ljo4mllyzq y=-\frac{1}{2}\left(x-b\right) Velocity[i] = Velocity[i] * Drag + Acceleration; //Set the Velocity to be (the speed we shere add) * (Drag) + (howmuch we wish to move) Position[i] = Position[i] + Velocity[i]; //Calculate new position - //LED_Add(LEDtoPosition(round(Position[i])), 1, Saved_Color[i], TotalLEDsClock); //Draw the LED - - int _LedPos = round(Position[i]); - LED_Fill(LEDtoPosition(_LedPos), 1, CRGB(0, 0, 255)); + LED_Add(LEDtoPosition(round(Position[i])), 1, Saved_Color[i], TotalLEDsClock); //Draw the LED } UpdateLEDs = true; } } break; + default: AnimationCounter = 0; //Stop animation #ifdef SerialEnabled From 31d755a351229810df8ab0864d1016ff4935d9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelle=20Wie=C2=BF?= <1545223+jellewie@users.noreply.github.com> Date: Fri, 21 May 2021 12:31:37 +0200 Subject: [PATCH 5/5] Fixed it! :D --- Arduino/Animation.h | 46 +++++++++++++++++++++++++-------------------- Arduino/handler.ino | 10 ++++++++-- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/Arduino/Animation.h b/Arduino/Animation.h index 68ab346..193a616 100644 --- a/Arduino/Animation.h +++ b/Arduino/Animation.h @@ -91,6 +91,7 @@ void ShowAnimation(bool Start) { //This would be UpdateLEDs = true; } break; case 2: { //CONFETTI + if (Start) ClockClear(); #define ANIMATION_TIME_CONFETTI 1000 / 60 EVERY_N_MILLISECONDS(ANIMATION_TIME_CONFETTI) { //Limit to 60FPS fadeToBlackBy(LEDs, TotalLEDsClock, 1); //Dim a color by (X/256ths) @@ -102,12 +103,14 @@ void ShowAnimation(bool Start) { //This would be } } break; case 3: { //FLASH + if (Start) ClockClear(); EVERY_N_MILLISECONDS(500) { LED_Flash(0, TotalLEDsClock, AnimationRGB); UpdateLEDs = true; } } break; case 4: { //GLITTER + if (Start) ClockClear(); #define ANIMATION_TIME_GLITTER 1000 / 60 EVERY_N_MILLISECONDS(ANIMATION_TIME_GLITTER) { //Limit to 60FPS fadeToBlackBy(LEDs, TotalLEDsClock, 1); //Dim a color by (X/256ths) @@ -117,6 +120,7 @@ void ShowAnimation(bool Start) { //This would be } } break; case 5: { //JUGGLE + if (Start) ClockClear(); #define ANIMATION_TIME_JUGGLE 1000 / 30 EVERY_N_MILLISECONDS(ANIMATION_TIME_JUGGLE) { //Limit to x FPS fadeToBlackBy(LEDs, TotalLEDsClock, 10); @@ -149,6 +153,7 @@ void ShowAnimation(bool Start) { //This would be } } break; case 8: { //SINELON + if (Start) ClockClear(); #define ANIMATION_TIME_SINELON 1000 / 30 EVERY_N_MILLISECONDS(ANIMATION_TIME_SINELON) { //Limit to x FPS AnimationSinelon(AnimationRGB, 5, Start, 13); @@ -156,6 +161,7 @@ void ShowAnimation(bool Start) { //This would be } } break; case 9: { //SINELON2 + if (Start) ClockClear(); #define ANIMATION_TIME_SINELON2 1000 / 30 EVERY_N_MILLISECONDS(ANIMATION_TIME_SINELON2) { //Limit to x FPS if (AnimationSinelon(AnimationRGB, 1, Start, 13)) @@ -168,6 +174,7 @@ void ShowAnimation(bool Start) { //This would be static byte BlinkCounter; static byte BlinkEachxLoops = 20; if (Start) { + ClockClear(); BlinkLeft = random8(0, 2); BlinkCounter = 0; BlinkEachxLoops = random8(20, 50); @@ -249,34 +256,34 @@ void ShowAnimation(bool Start) { //This would be } } break; case 13: { //PHYSICS -#define Speed -0.02 -#define Drag 0.981 - CRGB Saved_Color[TotalLEDsClock]; - float Position[TotalLEDsClock]; - float Velocity[TotalLEDsClock]; +#define Speed -0.004 //Lower = slower +#define Drag 0.995 //Lower = more slowdown per step +#define FallToLED TotalLEDsClock / 2 + static CRGB Saved_Color[TotalLEDsClock]; + static float Position[TotalLEDsClock]; + static float Velocity[TotalLEDsClock]; + EVERY_N_SECONDS(30) { //Just repeat is sometimes, to keep the standalone Mode intresting + for (int i = 0; i < TotalLEDsClock; i++) { + Position[i] = i; + Velocity[i] = 0; + } + } if (Start) { - - LED_Rainbow(0, TotalLEDsClock, 255 / TotalLEDsClock); - for (int i = 0; i < TotalLEDsClock; i++) { Position[i] = i; - Saved_Color[i].r = LEDs[i].r; - Saved_Color[i].g = LEDs[i].g; - Saved_Color[i].b = LEDs[i].b; + Velocity[i] = 0; + Saved_Color[i] = LEDs[LEDtoPosition(i)]; //Dont use memcpy since its about the same speed, but doesnt allow the offset } - //memcpy(Saved_Color, LEDs, sizeof(Saved_Color)); //Destination, Source, Size http://www.cplusplus.com/reference/cstring/memcpy/ } -#define ANIMATION_TIME_PHYSICS 1000/10 +#define ANIMATION_TIME_PHYSICS 1000/60 EVERY_N_MILLISECONDS(ANIMATION_TIME_PHYSICS) { - LED_Fill(1, TotalLEDsClock - 1, CRGB(0, 0, 0), TotalLEDsClock); //Clear All LEDs so we start from a blank slate - - LED_Flash(0, 1, CRGB(255, 0, 0), CRGB(0, 0, 255), TotalLEDsClock); - + ClockClear(); //Clear the LEDs so we start from a blank slate for (int i = 0; i < TotalLEDsClock; i++) { - float Acceleration = Speed * (Position[i] - TotalLEDsClock / 2);//Calculate howmuch we wish to move (just linear) https://www.desmos.com/calculator/ljo4mllyzq y=-\frac{1}{2}\left(x-b\right) + float Acceleration = Speed * (Position[i] - FallToLED);//Calculate howmuch we wish to move (just linear) https://www.desmos.com/calculator/ljo4mllyzq y=-\frac{1}{2}\left(x-b\right) Velocity[i] = Velocity[i] * Drag + Acceleration; //Set the Velocity to be (the speed we shere add) * (Drag) + (howmuch we wish to move) Position[i] = Position[i] + Velocity[i]; //Calculate new position - LED_Add(LEDtoPosition(round(Position[i])), 1, Saved_Color[i], TotalLEDsClock); //Draw the LED + signed int _Pos = round(Position[i]); + LED_Add(LEDtoPosition(_Pos), 1, Saved_Color[i], TotalLEDsClock); //Draw the LED } UpdateLEDs = true; } @@ -300,6 +307,5 @@ void StartAnimation(byte ID, int Time) { #ifdef SerialEnabled Serial.println("AN: Selected special mode " + String(CurrentAnimation)); #endif //SerialEnabled - FastLED.clear(); ShowAnimation(true); } diff --git a/Arduino/handler.ino b/Arduino/handler.ino index ce71029..a3519e5 100644 --- a/Arduino/handler.ino +++ b/Arduino/handler.ino @@ -96,8 +96,14 @@ void handle_Set() { #ifdef Server_SerialEnabled Serial.println(); #endif //Server_SerialEnabled - if (LastMode != Mode and Section == 0) //If mode has updated, and we are talking about the whole LEDstrip, clear the current state - FastLED.clear(); + + + //Do not clear the clock/LED, we could need it for PHYSICS, but unsure how this would impact Section support, will fix later when I know more + + //if (LastMode != Mode and Section == 0) //If mode has updated, and we are talking about the whole LEDstrip, clear the current state + // FastLED.clear(); + + bool ColorUpdated = false; if (Mode == WIFI) AnimationCounter = 0; if (AnimationCounter != 0) { //Animation needs to be shown