├── firmware1024.bin ├── firmware4096.bin ├── FHEM_DOIF_NFX.txt ├── README.md └── _P124_NeoPixelBusFX.ino /firmware1024.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djcysmic/NeopixelBusFX/HEAD/firmware1024.bin -------------------------------------------------------------------------------- /firmware4096.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djcysmic/NeopixelBusFX/HEAD/firmware4096.bin -------------------------------------------------------------------------------- /FHEM_DOIF_NFX.txt: -------------------------------------------------------------------------------- 1 | defmod di.sz.nfx DOIF ## cmd_1: Ausschalten\ 2 | ([$SELF:effect] eq "off") (\ 3 | set [$SELF:device] nfx off 1000 10\ 4 | )\ 5 | ## cmd_2: Animation anhalten\ 6 | DOELSEIF ([$SELF:effect] eq "stop") (\ 7 | set [$SELF:device] nfx stop\ 8 | )\ 9 | ## cmd_3: Einschalten\ 10 | DOELSEIF ([$SELF:effect] eq "on") (\ 11 | set [$SELF:device] nfx on 1000 10\ 12 | )\ 13 | ## cmd_4: Alle Pixel auf eine Farbe setzen\ 14 | DOELSEIF ([$SELF:effect] eq "all") (\ 15 | set [$SELF:device] nfx all [$SELF:color_1]\ 16 | )\ 17 | ## cmd_5: Regenbogen-Effekt\ 18 | DOELSEIF ([$SELF:effect] eq "rainbow") (\ 19 | set [$SELF:device] nfx rainbow [$SELF:speed]\ 20 | )\ 21 | ## cmd_6: Feuer-Effekt\ 22 | DOELSEIF ([$SELF:effect] eq "fire") (\ 23 | set [$SELF:device] nfx fire [$SELF:speed] 255 40 20\ 24 | )\ 25 | ## cmd_7: Fake TV Animation\ 26 | DOELSEIF ([$SELF:effect] eq "faketv") (\ 27 | set [$SELF:device] nfx faketv 1 72\ 28 | )\ 29 | ## cmd_8: Colorfade\ 30 | DOELSEIF ([$SELF:effect] eq "colorfade") (\ 31 | set [$SELF:device] nfx colorfade [$SELF:color_1] [$SELF:color_2] 1 72\ 32 | )\ 33 | ## cmd_9: Knightrider\ 34 | DOELSEIF ([$SELF:effect] eq "kitt") (\ 35 | set [$SELF:device] nfx kitt [$SELF:color_1] [$SELF:speed]\ 36 | )\ 37 | ## cmd_10: Theater\ 38 | DOELSEIF ([$SELF:effect] eq "theatre") (\ 39 | set [$SELF:device] nfx theatre [$SELF:color_1] [$SELF:color_2] 5 [$SELF:speed]\ 40 | )\ 41 | ## cmd_11: Twinklefade\ 42 | DOELSEIF ([$SELF:effect] eq "twinklefade") (\ 43 | set [$SELF:device] nfx twinklefade [$SELF:color_1] 8 [$SELF:speed]\ 44 | )\ 45 | ## cmd_12: Wipe-Effekt\ 46 | DOELSEIF ([$SELF:effect] eq "wipe") (\ 47 | set [$SELF:device] nfx wipe [$SELF:color_1] [$SELF:color_2] [$SELF:speed]\ 48 | )\ 49 | ## cmd_13: Dualwipe-IN-Effekt\ 50 | DOELSEIF ([$SELF:effect] eq "dualwipe") (\ 51 | set [$SELF:device] nfx dualwipe [$SELF:color_1] [$SELF:color_2] [$SELF:speed]\ 52 | )\ 53 | ## cmd_14: Dualwipe-OUT-Effekt\ 54 | DOELSEIF ([$SELF:effect] eq "dualwipeout") (\ 55 | set [$SELF:device] nfx dualwipe 000000 [$SELF:color_2] [$SELF:speed]\ 56 | )\ 57 | ## cmd_15: Twinkle\ 58 | DOELSEIF ([$SELF:effect] eq "twinkle") (\ 59 | set [$SELF:device] nfx twinkle [$SELF:color_1] [$SELF:color_2] [$SELF:speed]\ 60 | )\ 61 | ## cmd_16: Comet\ 62 | DOELSEIF ([$SELF:effect] eq "comet") (\ 63 | set [$SELF:device] nfx comet [$SELF:color_1] [$SELF:speed]\ 64 | )\ 65 | ## cmd_17: Scan\ 66 | DOELSEIF ([$SELF:effect] eq "scan") (\ 67 | set [$SELF:device] nfx scan [$SELF:color_1] [$SELF:color_2] [$SELF:speed]\ 68 | )\ 69 | ## cmd_18: Dualscan\ 70 | DOELSEIF ([$SELF:effect] eq "dualscan") (\ 71 | set [$SELF:device] nfx dualscan [$SELF:color_1] [$SELF:color_2] [$SELF:speed]\ 72 | )\ 73 | ## cmd_19: Sparkle\ 74 | DOELSEIF ([$SELF:effect] eq "sparkle") (\ 75 | set [$SELF:device] nfx sparkle [$SELF:color_1] [$SELF:color_2] [$SELF:speed]\ 76 | ) 77 | attr di.sz.nfx alias NeopixelBusFX 78 | attr di.sz.nfx cmdIcon play:rc_PLAY stop:rc_STOP on:taster_ch_an_gruen off:taster_ch_aus_rot 79 | attr di.sz.nfx devStateIcon initialized:general_ok@green cmd_1:general_aus@darkred cmd_2:rc_STOP cmd_3:general_an@green cmd_4:rc_1 cmd_5:rc_2 cmd_6:rc_3 cmd_7:rc_4 cmd_8:rc_5 cmd_9:rc_6 cmd_10:rc_7 cmd_11:rc_8 cmd_12:rc_9 80 | attr di.sz.nfx do always 81 | attr di.sz.nfx eventMap /effect on:on/effect off:off/effect stop:stop/ 82 | attr di.sz.nfx group 01_NeopixelBusFX 83 | attr di.sz.nfx icon hue_filled_lightstrip 84 | attr di.sz.nfx readingList speed,effect,color_1,color_2,device 85 | attr di.sz.nfx room Logik,Schlafzimmer 86 | attr di.sz.nfx setList device:test.esp.wemos.1,sz.esp.innensensor effect:wipe,dualwipe,dualwipeout,all,fire,faketv,kitt,comet,theatre,rainbow,colorfade,scan,dualscan,twinkle,twinklefade,sparkle color_1:colorpicker,rgb color_2:colorpicker,rgb speed:selectnumbers,-50,1,50,0,lin 87 | attr di.sz.nfx stateFormat state 88 | attr di.sz.nfx webCmd device:effect:color_1:color_2:speed:play:stop:on:off 89 | attr di.sz.nfx webCmdLabel Controller:Effekt:Farbe ;1:Farbe ;2:Speed: ;: ;: ;: ; 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | List of commands:
2 | 3 | nfx off [fadetime, default:1000] [delay +/-ms, default:20]
4 | o switches the stripe off
5 | 6 | nfx on [fadetime, default:1000] [delay +/-ms, default:20]
7 | o restores last state of the stripe
8 | 9 | nfx dim dimvalue
10 | o dim stripe overall
11 | o dimvalue 0-255, default:255
12 | 13 | nfx line startpixel endpixel color
14 | nfx hsvline startpixel endpixel hue saturation brightness
15 | 16 | nfx one pixel color
17 | nfx hsvone pixel hue saturation brightness
18 | 19 | nfx all color [fadetime, default:1000] [delay +/-ms, default:20]
20 | nfx rgb color [fadetime, default:1000] [delay +/-ms, default:20]
21 | nfx fade color [fadetime, default:1000] [delay +/-ms, default:20]
22 | 23 | nfx hsv hue[0-360] saturation[0-100] brightness[0-100] [fadetime, default:1000] [delay +/-ms, default:20]
24 | 25 | nfx colorfade startcolor endcolor [startpixel] [endpixel]
26 | o startpixel default: 0
27 | o endpixel default:pixelcount-1
28 | 29 | nfx rainbow [speed] [fadetime, default:1000]
30 | o speed +/- 0-50, default: 25
31 | 32 | nfx kitt color [speed]
33 | o speed +/- 0-50, default: 25
34 | 35 | nfx comet color [speed]
36 | o speed +/- 0-50, default: 25
37 | 38 | nfx theatre color [backgroundcolor] [count] [speed]
39 | o count default: 1
40 | o speed +/- 0-50, default: 25
41 | 42 | nfx scan color [backgroundcolor] [speed]
43 | o speed +/- 0-50, default: 25
44 | 45 | nfx dualscan color [backgroundcolor] [speed]
46 | o speed +/- 0-50, default: 25
47 | 48 | nfx twinkle color [backgroundcolor] [speed]
49 | o speed +/- 0-50, default: 25
50 | 51 | nfx twinklefade color [count] [speed]
52 | o count default: 1
53 | o speed +/- 0-50, default: 25
54 | 55 | nfx sparkle color [backgroundcolor] [speed]
56 | o speed +/- 0-50, default: 25
57 | 58 | nfx wipe color [dotcolor] [speed]
59 | o speed +/- 0-50, default: 25
60 | 61 | nfx dualwipe color [dotcolor] [speed]
62 | o speed +/- 0-50, default: 25
63 | 64 | nfx fire [fps] [brightness] [cooling] [sparking]
65 | o fps default: 50
66 | o brightness 0-255, default: 31
67 | o cooling 20-100, default: 50
68 | o sparking 50-200, default: 120
69 | 70 | nfx fireflicker [intensity] [speed]
71 | o intensity default: 3
72 | o speed +/- 0-50, default: 25
73 | 74 | nfx faketv [startpixel] [endpixel]
75 | Paste faketv.h in ./src
76 | o startpixel default: 0
77 | o endpixel default:pixelcount-1
78 | 79 | nfx simpleclock [bigtickcolor] [smalltickcolor] [hourcolor] [minutecolor] [secondcolor] [backgroundcolor]
80 | o bigtickcolor, default: 505050
81 | o smalltickcolor, default: 101010
82 | o hourcolor, default: 0000FF
83 | o minutecolor, default: 00FF00
84 | o secondcolor, default: FF0000 - color of the second hand - can be set to "off" to turn the second hand completly off
85 | o backgroundcolor, default: 000000
86 | 87 | nfx stop
88 | o stops the effect
89 | 90 | nfx statusrequest
91 | o sends status
92 | 93 | nfx fadetime value in ms, Default: 1000
94 | nfx fadedelay value in +/- ms, Default: 20
95 | nfx speed value 0-50, Default: 25
96 | nfx count number of pixels, Default: 1
97 | nfx bgcolor color, Default: 000000
98 | o sets default parameter 99 | 100 | Use:
101 | 102 | needed:
103 | startcolor,endcolor,color,backgroundcolor, dotcolor -> targetcolor in hex format e.g. ff0000 for red
104 | 105 | [optional] :
106 | fadetime -> fadetime per pixel in ms
107 | delay -> delay time to next pixel in ms, if delay < 0 fades from other end of the stripe
108 | speed -> 0-50, speed < 0 for reverse 109 | 110 | 111 | Based on Adafruit Fake TV Light for Engineers, WS2812FX, NeoPixelBus, Lights, NeoPixel - Basic and Candle modules
112 | 113 | https://learn.adafruit.com/fake-tv-light-for-engineers/overview
114 | https://github.com/Makuna/NeoPixelBus
115 | https://github.com/letscontrolit/ESPEasy
116 | https://github.com/kitesurfer1404/WS2812FX
117 | https://github.com/ddtlabs/ESPEasy-Plugin-Lights
118 | 119 | Thank you to all developers 120 | -------------------------------------------------------------------------------- /_P124_NeoPixelBusFX.ino: -------------------------------------------------------------------------------- 1 | #ifdef USES_P124 2 | //####################################################################################################### 3 | //#################################### Plugin 124: NeoPixelBusFX ######################################## 4 | //####################################################################################################### 5 | /* 6 | List of commands: 7 | 8 | nfx off [fadetime] [delay] 9 | switches the stripe off 10 | 11 | nfx on [fadetime] [delay] 12 | restores last state of the stripe 13 | 14 | nfx dim [dimvalue] 15 | dimvalue 0-255 16 | 17 | nfx line startpixel endpixel color 18 | nfx hsvline startpixel endpixel hue saturation brightness 19 | 20 | nfx one pixel color 21 | nfx hsvone pixel hue saturation brightness 22 | 23 | nfx all color [fadetime] [delay] 24 | nfx rgb color [fadetime] [delay] 25 | nfx fade color [fadetime] [delay] 26 | 27 | nfx hsv hue saturation brightness [fadetime] [delay] 28 | 29 | nfx colorfade startcolor endcolor [startpixel] [endpixel] 30 | 31 | nfx rainbow [speed] [fadetime] 32 | 33 | nfx kitt color [speed] 34 | 35 | nfx comet color [speed] 36 | 37 | nfx theatre color [backgroundcolor] [count] [speed] 38 | 39 | nfx scan color [backgroundcolor] [speed] 40 | 41 | nfx dualscan color [backgroundcolor] [speed] 42 | 43 | nfx twinkle color [backgroundcolor] [speed] 44 | 45 | nfx twinklefade color [count] [speed] 46 | 47 | nfx sparkle color [backgroundcolor] [speed] 48 | 49 | nfx wipe color [dotcolor] [speed] 50 | 51 | nfx dualwipe [dotcolor] [speed] 52 | 53 | nfx fire [fps] [brightness] [cooling] [sparking] 54 | 55 | nfx fireflicker [intensity] [speed] 56 | 57 | nfx faketv [startpixel] [endpixel] 58 | 59 | nfx simpleclock [bigtickcolor] [smalltickcolor] [hourcolor] [minutecolor] [secondcolor, set "off" to disable] [backgroundcolor] 60 | 61 | 62 | nfx stop 63 | stops the effect 64 | 65 | nfx statusrequest 66 | sends status 67 | 68 | nfx fadetime 69 | nfx fadedelay 70 | nfx speed 71 | nfx count 72 | nfx bgcolor 73 | sets default parameter 74 | 75 | Use: 76 | 77 | needed: 78 | color,backgroundcolor -> targetcolor in hex format e.g. ff0000 for red 79 | 80 | [optional]: 81 | fadetime -> fadetime per pixel in ms 82 | delay -> delay time to next pixel in ms, if delay < 0 fades from other end of the stripe 83 | speed -> 0-50, speed < 0 for reverse 84 | 85 | 86 | Based on Adafruit Fake TV Light for Engineers, WS2812FX, NeoPixelBus, Lights, NeoPixel - Basic and Candle modules 87 | 88 | https://learn.adafruit.com/fake-tv-light-for-engineers/overview 89 | https://github.com/letscontrolit/ESPEasy 90 | https://github.com/kitesurfer1404/WS2812FX 91 | https://github.com/Makuna/NeoPixelBus 92 | https://github.com/ddtlabs/ESPEasy-Plugin-Lights 93 | 94 | Thank you to all developers 95 | */ 96 | 97 | #include 98 | #include "faketv.h" //color pattern for FakeTV 99 | 100 | #define SPEED_MAX 50 101 | #define ARRAYSIZE 300 //Max LED Count 102 | 103 | //Choose your color order below: 104 | 105 | #define GRB //should be standard - SK6812(grb), WS2811, and WS2812 106 | //#define GRBW //This is used for SK6812rgbw pixels that have the separate white led in them. 107 | //#define RGB //some older pixels 108 | //#define RGBW //A four element color in the order of Red, Green, Blue, and then White. A common four element format. 109 | //#define BRG //A three element color in the order of Blue, Red, and then Green. 110 | //#define RBG //A three element color in the order of Red, Blue, and then Green. 111 | 112 | #define NEOPIXEL_LIB NeoPixelBrightnessBus // Neopixel library type 113 | #define METHOD NeoEsp8266Uart1800KbpsMethod //GPIO2 - use NeoEsp8266Uart0800KbpsMethod for GPIO1(TX) 114 | 115 | #if defined GRB 116 | #define FEATURE NeoGrbFeature 117 | #elif defined GRBW 118 | #define FEATURE NeoGrbwFeature 119 | #elif defined RGB 120 | #define FEATURE NeoRgbFeature 121 | #elif defined RGBW 122 | #define FEATURE NeoRgbwFeature 123 | #elif defined BRG 124 | #define FEATURE NeoBrgFeature 125 | #elif defined RBG 126 | #define FEATURE NeoRbgFeature 127 | #else 128 | #define FEATURE NeoGrbFeature 129 | #endif 130 | 131 | #define numPixels (sizeof(ftv_colors) / sizeof(ftv_colors[0])) 132 | 133 | NEOPIXEL_LIB* Plugin_124_pixels = NULL; 134 | 135 | const float pi = 3.1415926535897932384626433832795; 136 | 137 | uint16_t pos, 138 | color, 139 | r_pixel, 140 | startpixel, 141 | endpixel, 142 | difference, 143 | fps = 50, 144 | colorcount; 145 | 146 | #if defined(RGBW) || defined(GRBW) 147 | RgbwColor rgb_target[ARRAYSIZE], 148 | rgb_old[ARRAYSIZE], 149 | rgb, rrggbb, 150 | rgb_tick_b = HtmlColor(0x505050), 151 | rgb_tick_s = HtmlColor(0x101010), 152 | rgb_m = HtmlColor(0x00FF00), 153 | rgb_h = HtmlColor(0x0000FF), 154 | rgb_s = HtmlColor(0xFF0000); 155 | #else 156 | RgbColor rgb_target[ARRAYSIZE], 157 | rgb_old[ARRAYSIZE], 158 | rgb, rrggbb, 159 | rgb_tick_b = HtmlColor(0x505050), 160 | rgb_tick_s = HtmlColor(0x101010), 161 | rgb_m = HtmlColor(0x00FF00), 162 | rgb_h = HtmlColor(0x0000FF), 163 | rgb_s = HtmlColor(0xFF0000); 164 | #endif 165 | 166 | int16_t fadedelay = 20; 167 | 168 | uint16_t pixelCount = ARRAYSIZE; 169 | 170 | int8_t defaultspeed = 25, 171 | rainbowspeed = 1, 172 | speed = 25, 173 | count = 1, 174 | rev_intensity = 3; 175 | 176 | uint32_t _counter_mode_step = 0, 177 | fadetime = 1000, 178 | ftv_holdTime, 179 | pixelNum; 180 | 181 | uint16_t ftv_pr = 0, ftv_pg = 0, ftv_pb = 0; // Prev R, G, B; 182 | uint32_t ftv_totalTime, ftv_fadeTime, ftv_startTime, ftv_elapsed; 183 | uint16_t ftv_nr, ftv_ng, ftv_nb, ftv_r, ftv_g, ftv_b, ftv_i, ftv_frac; 184 | uint8_t ftv_hi, ftv_lo, ftv_r8, ftv_g8, ftv_b8; 185 | 186 | String colorStr, 187 | backgroundcolorStr; 188 | 189 | bool gReverseDirection = false; 190 | bool rgb_s_off = false; 191 | bool fadeIn = false; 192 | 193 | byte cooling = 50, 194 | sparking = 120, 195 | brightness = 31; 196 | 197 | unsigned long counter20ms = 0, 198 | starttime[ARRAYSIZE], 199 | starttimerb, 200 | maxtime = 0; 201 | 202 | enum modetype { 203 | Off, On, Fade, ColorFade, Rainbow, Kitt, Comet, Theatre, Scan, Dualscan, Twinkle, TwinkleFade, Sparkle, Fire, FireFlicker, Wipe, Dualwipe, FakeTV, SimpleClock 204 | }; 205 | 206 | const char* modeName[] = { 207 | "off", "on", "fade", "colorfade", "rainbow", "kitt", "comet", "theatre", "scan", "dualscan", "twinkle", "twinklefade", "sparkle", "fire", "fireflicker", "wipe", "dualwipe", "faketv", "simpleclock" 208 | }; 209 | 210 | modetype mode,savemode,lastmode; 211 | 212 | #define PLUGIN_124 213 | #define PLUGIN_ID_124 124 214 | #define PLUGIN_NAME_124 "NeoPixelBusFX" 215 | #define PLUGIN_VALUENAME1_124 "Mode" 216 | #define PLUGIN_VALUENAME2_124 "Lastmode" 217 | #define PLUGIN_VALUENAME3_124 "Fadetime" 218 | #define PLUGIN_VALUENAME4_124 "Fadedelay" 219 | 220 | boolean Plugin_124(byte function, struct EventStruct *event, String& string) 221 | { 222 | boolean success = false; 223 | 224 | switch (function) 225 | { 226 | 227 | case PLUGIN_DEVICE_ADD: 228 | { 229 | Device[++deviceCount].Number = PLUGIN_ID_124; 230 | Device[deviceCount].Type = DEVICE_TYPE_DUMMY; 231 | Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_QUAD; 232 | Device[deviceCount].Custom = true; 233 | Device[deviceCount].Ports = 0; 234 | Device[deviceCount].PullUpOption = false; 235 | Device[deviceCount].InverseLogicOption = false; 236 | Device[deviceCount].FormulaOption = false; 237 | Device[deviceCount].ValueCount = 4; 238 | Device[deviceCount].SendDataOption = true; 239 | Device[deviceCount].TimerOption = true; 240 | Device[deviceCount].TimerOptional = true; 241 | Device[deviceCount].GlobalSyncOption = true; 242 | Device[deviceCount].DecimalsOnly = false; 243 | break; 244 | } 245 | 246 | case PLUGIN_GET_DEVICENAME: 247 | { 248 | string = F(PLUGIN_NAME_124); 249 | break; 250 | } 251 | 252 | case PLUGIN_GET_DEVICEVALUENAMES: 253 | { 254 | strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_124)); 255 | strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_124)); 256 | strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_124)); 257 | strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_124)); 258 | break; 259 | } 260 | 261 | case PLUGIN_WEBFORM_LOAD: 262 | { 263 | addHtml(F("

Please connect stripe to GPIO2!")); 264 | addFormNumericBox(F("Led Count"), F("plugin_124_leds"), Settings.TaskDevicePluginConfig[event->TaskIndex][0],1 ,999); 265 | success = true; 266 | break; 267 | } 268 | 269 | case PLUGIN_WEBFORM_SAVE: 270 | { 271 | Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_124_leds")); 272 | //Settings.TaskDevicePin1[event->TaskIndex] = getFormItemInt(F("taskdevicepin1")); 273 | 274 | success = true; 275 | break; 276 | } 277 | 278 | case PLUGIN_INIT: 279 | { 280 | if (!Plugin_124_pixels) 281 | { 282 | Plugin_124_pixels = new NEOPIXEL_LIB(Settings.TaskDevicePluginConfig[event->TaskIndex][0]); 283 | Plugin_124_pixels->Begin(); // This initializes the NeoPixelBus library. 284 | } 285 | 286 | pixelCount = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; 287 | success = true; 288 | break; 289 | } 290 | 291 | case PLUGIN_READ: // -------------------------------------------> 292 | { 293 | // there is no need to read them, just use current values 294 | UserVar[event->BaseVarIndex] = mode; 295 | UserVar[event->BaseVarIndex + 1] = savemode; 296 | UserVar[event->BaseVarIndex + 2] = fadetime; 297 | UserVar[event->BaseVarIndex + 3] = fadedelay; 298 | String log; 299 | log = F("Lights: mode: "); 300 | log += modeName[mode]; 301 | log += F(" lastmode: "); 302 | log += modeName[savemode]; 303 | log += F(" fadetime: "); 304 | log += (int)UserVar[event->BaseVarIndex + 2]; 305 | log += F(" fadedelay: "); 306 | log += (int)UserVar[event->BaseVarIndex + 3]; 307 | addLog(LOG_LEVEL_INFO, log); 308 | 309 | success = true; 310 | break; 311 | } 312 | 313 | case PLUGIN_WRITE: 314 | { 315 | 316 | String log = ""; 317 | String command = parseString(string, 1); 318 | 319 | if (command == F("neopixelfx") || command == F("nfx")) { 320 | success = true; 321 | String subCommand = parseString(string, 2); 322 | 323 | if (subCommand == F("fadetime")) { 324 | fadetime = parseString(string, 3).toInt(); 325 | } 326 | 327 | else if (subCommand == F("fadedelay")) { 328 | fadedelay = parseString(string, 3).toInt(); 329 | } 330 | 331 | else if (subCommand == F("speed")) { 332 | defaultspeed = parseString(string, 3).toInt(); 333 | speed = defaultspeed; 334 | } 335 | 336 | else if (subCommand == F("bgcolor")) { 337 | hex2rrggbb(parseString(string, 3)); 338 | } 339 | 340 | else if (subCommand == F("count")) { 341 | count = parseString(string, 3).toInt(); 342 | } 343 | 344 | else if (subCommand == F("on") || subCommand == F("off")) { 345 | 346 | fadetime = 1000; 347 | fadedelay = 0; 348 | 349 | fadetime = (parseString(string, 3) == "") 350 | ? fadetime 351 | : parseString(string, 3).toInt(); 352 | fadedelay = (parseString(string, 4) == "") 353 | ? fadedelay 354 | : parseString(string, 4).toInt(); 355 | 356 | for (int pixel = 0; pixel < pixelCount; pixel++) { 357 | 358 | r_pixel = (fadedelay < 0) 359 | ? pixelCount - pixel - 1 360 | : pixel; 361 | 362 | starttime[r_pixel] = counter20ms + (pixel * abs(fadedelay) / 20); 363 | 364 | if ( subCommand == F("on") && mode == Off ) { // switch on 365 | rgb_target[pixel] = rgb_old[pixel]; 366 | rgb_old[pixel] = Plugin_124_pixels->GetPixelColor(pixel); 367 | } else if ( subCommand == F("off") ) { // switch off 368 | rgb_old[pixel] = Plugin_124_pixels->GetPixelColor(pixel); 369 | rgb_target[pixel] = RgbColor(0); 370 | } 371 | } 372 | 373 | if ( ( subCommand == F("on") ) && mode == Off ) { // switch on 374 | mode = ( savemode == On ) ? Fade : savemode; 375 | } else if ( subCommand == F("off") ) { // switch off 376 | savemode = mode; 377 | mode = Fade; 378 | } 379 | 380 | maxtime = starttime[r_pixel] + (fadetime / 20); 381 | } 382 | 383 | else if (subCommand == F("dim")) { 384 | Plugin_124_pixels->SetBrightness(parseString(string, 3).toInt()); 385 | } 386 | 387 | else if (subCommand == F("line")) { 388 | mode = On; 389 | 390 | hex2rgb(parseString(string, 5)); 391 | 392 | for (int i = 0; i <= ( parseString(string, 4).toInt()-parseString(string, 3).toInt() + pixelCount) % pixelCount ; i++){ 393 | Plugin_124_pixels->SetPixelColor((i + parseString(string, 3).toInt() - 1) % pixelCount, rgb); 394 | } 395 | } 396 | 397 | else if (subCommand == F("tick")) { 398 | mode = On; 399 | 400 | hex2rgb(parseString(string, 4)); 401 | 402 | // for (int i = 0; i < pixelCount ; i = i + (pixelCount / parseString(string, 3).toInt())) { 403 | for (int i = 0; i < parseString(string, 3).toInt(); i++) { 404 | Plugin_124_pixels->SetPixelColor(i * pixelCount / parseString(string, 3).toInt(), rgb); 405 | } 406 | } 407 | 408 | else if (subCommand == F("one")) { 409 | mode = On; 410 | 411 | uint16_t pixnum = parseString(string, 3).toInt() - 1; 412 | hex2rgb(parseString(string, 4)); 413 | 414 | Plugin_124_pixels->SetPixelColor(pixnum, rgb); 415 | } 416 | 417 | else if (subCommand == F("fade") || subCommand == F("all") || subCommand == F("rgb")) { 418 | mode = Fade; 419 | 420 | if (subCommand == F("all") || subCommand == F("rgb")) { 421 | fadedelay = 0; 422 | } 423 | 424 | hex2rgb(parseString(string, 3)); 425 | hex2rgb_pixel(parseString(string, 3)); 426 | 427 | fadetime = (parseString(string, 4) == "") 428 | ? fadetime 429 | : parseString(string, 4).toInt(); 430 | fadedelay = (parseString(string, 5) == "") 431 | ? fadedelay 432 | : parseString(string, 5).toInt(); 433 | 434 | for (int pixel = 0; pixel < pixelCount; pixel++){ 435 | 436 | r_pixel = (fadedelay < 0) 437 | ? pixelCount - pixel - 1 438 | : pixel; 439 | 440 | starttime[r_pixel] = counter20ms + (pixel * abs(fadedelay) / 20); 441 | 442 | rgb_old[pixel] = Plugin_124_pixels->GetPixelColor(pixel); 443 | } 444 | maxtime = starttime[r_pixel] + (fadetime / 20); 445 | } 446 | 447 | else if (subCommand == F("hsv")) { 448 | mode = Fade; 449 | fadedelay = 0; 450 | rgb = RgbColor(HsbColor(parseString(string, 3).toFloat()/360, parseString(string, 4).toFloat()/100, parseString(string, 5).toFloat()/100)); 451 | 452 | colorStr = ""; 453 | rgb.R < 16 ? colorStr = "0":""; 454 | colorStr += formatToHex(rgb.R,{}); 455 | rgb.G < 16 ? colorStr += "0":""; 456 | colorStr += formatToHex(rgb.G,{}); 457 | rgb.B < 16 ? colorStr += "0":""; 458 | colorStr += formatToHex(rgb.B,{}); 459 | 460 | hex2rgb_pixel(colorStr); 461 | 462 | fadetime = (parseString(string, 6) == "") 463 | ? fadetime 464 | : parseString(string, 6).toInt(); 465 | fadedelay = (parseString(string, 7) == "") 466 | ? fadedelay 467 | : parseString(string, 7).toInt(); 468 | 469 | for (int pixel = 0; pixel < pixelCount; pixel++){ 470 | 471 | r_pixel = (fadedelay < 0) 472 | ? pixelCount - pixel - 1 473 | : pixel; 474 | 475 | starttime[r_pixel] = counter20ms + (pixel * abs(fadedelay) / 20); 476 | 477 | rgb_old[pixel] = Plugin_124_pixels->GetPixelColor(pixel); 478 | } 479 | maxtime = starttime[r_pixel] + (fadetime / 20); 480 | } 481 | 482 | else if (subCommand == F("hsvone")) { 483 | mode = On; 484 | rgb = RgbColor(HsbColor(parseString(string, 4).toFloat()/360, parseString(string, 5).toFloat()/100, parseString(string, 6).toFloat()/100)); 485 | 486 | colorStr = ""; 487 | rgb.R < 16 ? colorStr = "0":""; 488 | colorStr += formatToHex(rgb.R,{}); 489 | rgb.G < 16 ? colorStr += "0":""; 490 | colorStr += formatToHex(rgb.G,{}); 491 | rgb.B < 16 ? colorStr += "0":""; 492 | colorStr += formatToHex(rgb.B,{}); 493 | 494 | hex2rgb(colorStr); 495 | uint16_t pixnum = parseString(string, 3).toInt() - 1; 496 | Plugin_124_pixels->SetPixelColor(pixnum, rgb); 497 | } 498 | 499 | else if (subCommand == F("hsvline")) { 500 | mode = On; 501 | 502 | rgb = RgbColor(HsbColor(parseString(string, 5).toFloat()/360, parseString(string, 6).toFloat()/100, parseString(string, 7).toFloat()/100)); 503 | 504 | colorStr = ""; 505 | rgb.R < 16 ? colorStr = "0":""; 506 | colorStr += formatToHex(rgb.R,{}); 507 | rgb.G < 16 ? colorStr += "0":""; 508 | colorStr += formatToHex(rgb.G,{}); 509 | rgb.B < 16 ? colorStr += "0":""; 510 | colorStr += formatToHex(rgb.B,{}); 511 | 512 | hex2rgb(colorStr); 513 | 514 | for (int i = 0; i <= ( parseString(string, 4).toInt()-parseString(string, 3).toInt() + pixelCount) % pixelCount ; i++){ 515 | Plugin_124_pixels->SetPixelColor((i + parseString(string, 3).toInt() - 1) % pixelCount, rgb); 516 | } 517 | } 518 | 519 | else if (subCommand == F("rainbow")) { 520 | fadeIn = (mode == Off) ? true : false; 521 | mode = Rainbow; 522 | starttimerb = counter20ms; 523 | 524 | rainbowspeed = (parseString(string, 3) == "") 525 | ? speed 526 | : parseString(string, 3).toInt(); 527 | 528 | fadetime = (parseString(string, 4) == "") 529 | ? fadetime 530 | : parseString(string, 4).toInt(); 531 | } 532 | 533 | else if (subCommand == F("colorfade")) { 534 | mode = ColorFade; 535 | 536 | hex2rgb(parseString(string, 3)); 537 | if (parseString(string, 4) != "") hex2rrggbb(parseString(string, 4)); 538 | 539 | startpixel = (parseString(string, 5) == "") 540 | ? 0 541 | : parseString(string, 5).toInt() - 1; 542 | endpixel = (parseString(string, 6) == "") 543 | ? pixelCount - 1 544 | : parseString(string, 6).toInt() - 1; 545 | } 546 | 547 | else if (subCommand == F("kitt")) { 548 | mode = Kitt; 549 | 550 | _counter_mode_step = 0; 551 | 552 | hex2rgb(parseString(string, 3)); 553 | 554 | speed = (parseString(string, 4) == "") 555 | ? defaultspeed 556 | : parseString(string, 4).toInt(); 557 | } 558 | 559 | else if (subCommand == F("comet")) { 560 | mode = Comet; 561 | 562 | _counter_mode_step = 0; 563 | 564 | hex2rgb(parseString(string, 3)); 565 | 566 | speed = (parseString(string, 4) == "") 567 | ? defaultspeed 568 | : parseString(string, 4).toInt(); 569 | } 570 | 571 | else if (subCommand == F("theatre")) { 572 | mode = Theatre; 573 | 574 | hex2rgb(parseString(string, 3)); 575 | if (parseString(string, 4) != "") hex2rrggbb(parseString(string, 4)); 576 | 577 | count = (parseString(string, 5) == "") 578 | ? count 579 | : parseString(string, 5).toInt(); 580 | 581 | speed = (parseString(string, 6) == "") 582 | ? defaultspeed 583 | : parseString(string, 6).toInt(); 584 | 585 | for ( int i = 0; i < pixelCount; i++ ) { 586 | if ((i / count) % 2 == 0) { 587 | Plugin_124_pixels->SetPixelColor(i, rgb); 588 | } else { 589 | Plugin_124_pixels->SetPixelColor(i, rrggbb); 590 | } 591 | } 592 | } 593 | 594 | else if (subCommand == F("scan")) { 595 | mode = Scan; 596 | 597 | _counter_mode_step = 0; 598 | 599 | hex2rgb(parseString(string, 3)); 600 | if (parseString(string, 4) != "") hex2rrggbb(parseString(string, 4)); 601 | 602 | speed = (parseString(string, 5) == "") 603 | ? defaultspeed 604 | : parseString(string, 5).toInt(); 605 | } 606 | 607 | else if (subCommand == F("dualscan")) { 608 | mode = Dualscan; 609 | 610 | _counter_mode_step = 0; 611 | 612 | hex2rgb(parseString(string, 3)); 613 | if (parseString(string, 4) != "") hex2rrggbb(parseString(string, 4)); 614 | 615 | speed = (parseString(string, 5) == "") 616 | ? defaultspeed 617 | : parseString(string, 5).toInt(); 618 | } 619 | 620 | else if (subCommand == F("twinkle")) { 621 | mode = Twinkle; 622 | 623 | _counter_mode_step = 0; 624 | 625 | hex2rgb(parseString(string, 3)); 626 | if (parseString(string, 4) != "") hex2rrggbb(parseString(string, 4)); 627 | 628 | speed = (parseString(string, 5) == "") 629 | ? defaultspeed 630 | : parseString(string, 5).toInt(); 631 | } 632 | 633 | else if (subCommand == F("twinklefade")) { 634 | mode = TwinkleFade; 635 | 636 | hex2rgb(parseString(string, 3)); 637 | 638 | count = (parseString(string, 4) == "") 639 | ? count 640 | : parseString(string, 4).toInt(); 641 | 642 | speed = (parseString(string, 5) == "") 643 | ? defaultspeed 644 | : parseString(string, 5).toInt(); 645 | 646 | } 647 | 648 | else if (subCommand == F("sparkle")) { 649 | mode = Sparkle; 650 | 651 | _counter_mode_step = 0; 652 | 653 | hex2rgb(parseString(string, 3)); 654 | hex2rrggbb(parseString(string, 4)); 655 | 656 | speed = (parseString(string, 5) == "") 657 | ? defaultspeed 658 | : parseString(string, 5).toInt(); 659 | } 660 | 661 | else if (subCommand == F("wipe")) { 662 | mode = Wipe; 663 | 664 | _counter_mode_step = 0; 665 | 666 | hex2rgb(parseString(string, 3)); 667 | if (parseString(string, 4) != "") { 668 | hex2rrggbb(parseString(string, 4)); 669 | } else { 670 | hex2rrggbb("000000"); 671 | } 672 | 673 | speed = (parseString(string, 5) == "") 674 | ? defaultspeed 675 | : parseString(string, 5).toInt(); 676 | } 677 | 678 | else if (subCommand == F("dualwipe")) { 679 | mode = Dualwipe; 680 | 681 | _counter_mode_step = 0; 682 | 683 | hex2rgb(parseString(string, 3)); 684 | if (parseString(string, 4) != "") { 685 | hex2rrggbb(parseString(string, 4)); 686 | } else { 687 | hex2rrggbb("000000"); 688 | } 689 | 690 | speed = (parseString(string, 5) == "") 691 | ? defaultspeed 692 | : parseString(string, 5).toInt(); 693 | } 694 | 695 | else if (subCommand == F("faketv")) { 696 | mode = FakeTV; 697 | _counter_mode_step = 0; 698 | 699 | randomSeed(analogRead(A0)); 700 | pixelNum = random(numPixels); // Begin at random point 701 | 702 | startpixel = (parseString(string, 3) == "") 703 | ? 0 704 | : parseString(string, 3).toInt() - 1; 705 | endpixel = (parseString(string, 4) == "") 706 | ? pixelCount 707 | : parseString(string, 4).toInt(); 708 | } 709 | 710 | else if (subCommand == F("fire")) { 711 | mode = Fire; 712 | 713 | fps = (parseString(string, 3) == "") 714 | ? fps 715 | : parseString(string, 3).toInt(); 716 | 717 | fps = (fps == 0 || fps > 50) ? 50 : fps; 718 | 719 | brightness = (parseString(string, 4) == "") 720 | ? brightness 721 | : parseString(string, 4).toFloat(); 722 | cooling = (parseString(string, 5) == "") 723 | ? cooling 724 | : parseString(string, 5).toFloat(); 725 | sparking = (parseString(string, 6) == "") 726 | ? sparking 727 | : parseString(string, 6).toFloat(); 728 | } 729 | 730 | else if (subCommand == F("fireflicker")) { 731 | mode = FireFlicker; 732 | 733 | rev_intensity = (parseString(string, 3) == "") 734 | ? rev_intensity 735 | : parseString(string, 3).toInt(); 736 | 737 | speed = (parseString(string, 4) == "") 738 | ? defaultspeed 739 | : parseString(string, 4).toInt(); 740 | } 741 | 742 | else if (subCommand == F("simpleclock")) { 743 | mode = SimpleClock; 744 | 745 | #if defined(RGBW) || defined(GRBW) 746 | if (parseString(string, 3) != "") { 747 | if (parseString(string, 3).length() <= 6) { 748 | rgb_tick_s = RgbwColor ( rgbStr2Num(parseString(string, 3)) >> 16, rgbStr2Num(parseString(string, 3)) >> 8, rgbStr2Num(parseString(string, 3))); 749 | } else { 750 | rgb_tick_s = RgbwColor ( rgbStr2Num(parseString(string, 3)) >> 24, rgbStr2Num(parseString(string, 3)) >> 16, rgbStr2Num(parseString(string, 3)) >> 8, rgbStr2Num(parseString(string, 3))); 751 | } 752 | } 753 | 754 | if (parseString(string, 4) != "") { 755 | if (parseString(string, 4).length() <= 6) { 756 | rgb_tick_b = RgbwColor ( rgbStr2Num(parseString(string, 4)) >> 16, rgbStr2Num(parseString(string, 4)) >> 8, rgbStr2Num(parseString(string, 4))); 757 | } else { 758 | rgb_tick_b = RgbwColor ( rgbStr2Num(parseString(string, 4)) >> 24, rgbStr2Num(parseString(string, 4)) >> 16, rgbStr2Num(parseString(string, 4)) >> 8, rgbStr2Num(parseString(string, 4))); 759 | } 760 | } 761 | 762 | if (parseString(string, 5) != "") { 763 | if (parseString(string, 5).length() <= 6) { 764 | rgb_h = RgbwColor ( rgbStr2Num(parseString(string, 5)) >> 16, rgbStr2Num(parseString(string, 5)) >> 8, rgbStr2Num(parseString(string, 5))); 765 | } else { 766 | rgb_h = RgbwColor ( rgbStr2Num(parseString(string, 5)) >> 24, rgbStr2Num(parseString(string, 5)) >> 16, rgbStr2Num(parseString(string, 5)) >> 8, rgbStr2Num(parseString(string, 5))); 767 | } 768 | } 769 | 770 | if (parseString(string, 6) != "") { 771 | if (parseString(string, 6).length() <= 6) { 772 | rgb_m = RgbwColor ( rgbStr2Num(parseString(string, 6)) >> 16, rgbStr2Num(parseString(string, 6)) >> 8, rgbStr2Num(parseString(string, 6))); 773 | } else { 774 | rgb_m = RgbwColor ( rgbStr2Num(parseString(string, 6)) >> 24, rgbStr2Num(parseString(string, 6)) >> 16, rgbStr2Num(parseString(string, 6)) >> 8, rgbStr2Num(parseString(string, 6))); 775 | } 776 | } 777 | 778 | if (parseString(string, 7) != "") { 779 | if (parseString(string, 7) == "off") { 780 | rgb_s_off = true; 781 | } else if (parseString(string, 7).length() <= 6) { 782 | rgb_s_off = false; 783 | rgb_s = RgbwColor ( rgbStr2Num(parseString(string, 7)) >> 16, rgbStr2Num(parseString(string, 7)) >> 8, rgbStr2Num(parseString(string, 7))); 784 | } else { 785 | rgb_s_off = false; 786 | rgb_s = RgbwColor ( rgbStr2Num(parseString(string, 7)) >> 24, rgbStr2Num(parseString(string, 7)) >> 16, rgbStr2Num(parseString(string, 7)) >> 8, rgbStr2Num(parseString(string, 7))); 787 | } 788 | } 789 | 790 | if (parseString(string, 8) != "") { 791 | hex2rrggbb(parseString(string, 8)); 792 | } 793 | 794 | #else 795 | 796 | rgb_tick_s = (parseString(string, 3) == "") 797 | ? rgb_tick_s 798 | : RgbColor ( rgbStr2Num(parseString(string, 3)) >> 16, rgbStr2Num(parseString(string, 3)) >> 8, rgbStr2Num(parseString(string, 3))); 799 | rgb_tick_b = (parseString(string, 4) == "") 800 | ? rgb_tick_b 801 | : RgbColor ( rgbStr2Num(parseString(string, 4)) >> 16, rgbStr2Num(parseString(string, 4)) >> 8, rgbStr2Num(parseString(string, 4))); 802 | rgb_h = (parseString(string, 5) == "") 803 | ? rgb_h 804 | : RgbColor ( rgbStr2Num(parseString(string, 5)) >> 16, rgbStr2Num(parseString(string, 5)) >> 8, rgbStr2Num(parseString(string, 5))); 805 | rgb_m = (parseString(string, 6) == "") 806 | ? rgb_m 807 | : RgbColor ( rgbStr2Num(parseString(string, 6)) >> 16, rgbStr2Num(parseString(string, 6)) >> 8, rgbStr2Num(parseString(string, 6))); 808 | if (parseString(string, 7) != "") { 809 | if (parseString(string, 7) == "off") { 810 | rgb_s_off = true; 811 | } else { 812 | rgb_s_off = false; 813 | rgb_s = RgbColor ( rgbStr2Num(parseString(string, 7)) >> 16, rgbStr2Num(parseString(string, 7)) >> 8, rgbStr2Num(parseString(string, 7))); 814 | } 815 | } 816 | 817 | if (parseString(string, 8) != "") hex2rrggbb(parseString(string, 8)); 818 | 819 | #endif 820 | 821 | } 822 | 823 | else if (subCommand == F("stop")) { 824 | mode = On; 825 | } 826 | 827 | else if (subCommand == F("statusrequest")) { 828 | } 829 | 830 | else if ( subCommand != F("all") && subCommand != F("line") 831 | && subCommand != F("one") && subCommand != F("fade") 832 | && subCommand != F("dim") && subCommand != F("fadetime") 833 | && subCommand != F("speed") && subCommand != F("fadedelay") 834 | && subCommand != F("count") && subCommand != F("bgcolor") 835 | && subCommand != F("on") && subCommand != F("off") 836 | && subCommand != F("rgb") && subCommand != F("rainbow") 837 | && subCommand != F("kitt") && subCommand != F("comet") 838 | && subCommand != F("theatre") && subCommand != F("scan") 839 | && subCommand != F("dualscan") && subCommand != F("twinkle") 840 | && subCommand != F("sparkle") && subCommand != F("fire") 841 | && subCommand != F("fireflicker") && subCommand != F("hsvone") 842 | && subCommand != F("hsv") && subCommand != F("hsvline") 843 | && subCommand != F("twinklefade") && subCommand != F("stop") 844 | && subCommand != F("wipe") && subCommand != F("dualwipe") 845 | && subCommand != F("colorfade") && subCommand != F("simpleclock") 846 | && subCommand != F("faketv") && subCommand != F("statusrequest") ) { 847 | log = F("NeoPixelBus: unknown subcommand: "); 848 | log += subCommand; 849 | addLog(LOG_LEVEL_INFO, log); 850 | 851 | String json; 852 | printToWebJSON = true; 853 | json += F("{\n"); 854 | json += F("\"plugin\": \"124\",\n"); 855 | json += F("\"log\": \""); 856 | json += F("NeoPixelBus: unknown command: "); 857 | json += subCommand; 858 | json += F("\"\n"); 859 | json += F("}\n"); 860 | // event->Source=EventValueSource::Enum::VALUE_SOURCE_HTTP; 861 | SendStatus(event, json); // send http response to controller (JSON format) 862 | printToWeb=false; 863 | } 864 | NeoPixelSendStatus(event); 865 | } // command neopixel 866 | 867 | if ( speed == 0 ) mode = On; // speed = 0 = stop mode 868 | speed = ( speed > SPEED_MAX || speed < -SPEED_MAX ) ? defaultspeed : speed; // avoid invalid values 869 | fadetime = (fadetime <= 0) ? 20 : fadetime; 870 | 871 | break; 872 | } 873 | 874 | case PLUGIN_FIFTY_PER_SECOND: 875 | { 876 | counter20ms++; 877 | lastmode = mode; 878 | 879 | switch (mode) { 880 | case Fade: 881 | fade(); 882 | break; 883 | 884 | case ColorFade: 885 | colorfade(); 886 | break; 887 | 888 | case Rainbow: 889 | rainbow(); 890 | break; 891 | 892 | case Kitt: 893 | kitt(); 894 | break; 895 | 896 | case Comet: 897 | comet(); 898 | break; 899 | 900 | case Theatre: 901 | theatre(); 902 | break; 903 | 904 | case Scan: 905 | scan(); 906 | break; 907 | 908 | case Dualscan: 909 | dualscan(); 910 | break; 911 | 912 | case Twinkle: 913 | twinkle(); 914 | break; 915 | 916 | case TwinkleFade: 917 | twinklefade(); 918 | break; 919 | 920 | case Sparkle: 921 | sparkle(); 922 | break; 923 | 924 | case Fire: 925 | fire(); 926 | break; 927 | 928 | case FireFlicker: 929 | fire_flicker(); 930 | break; 931 | 932 | case Wipe: 933 | wipe(); 934 | break; 935 | 936 | case Dualwipe: 937 | dualwipe(); 938 | break; 939 | 940 | case FakeTV: 941 | faketv(); 942 | break; 943 | 944 | case SimpleClock: 945 | Plugin_124_simpleclock(); 946 | break; 947 | 948 | default: 949 | break; 950 | } // switch mode 951 | 952 | Plugin_124_pixels->Show(); 953 | 954 | if (mode != lastmode) { 955 | String log = ""; 956 | log = F("NeoPixelBus: Mode Change: "); 957 | log += modeName[mode]; 958 | addLog(LOG_LEVEL_INFO, log); 959 | NeoPixelSendStatus(event); 960 | } 961 | success = true; 962 | break; 963 | } 964 | 965 | break; 966 | 967 | 968 | } 969 | return success; 970 | } 971 | 972 | void fade(void) { 973 | for (int pixel = 0; pixel < pixelCount; pixel++){ 974 | long zaehler = 20 * ( counter20ms - starttime[pixel] ); 975 | float progress = (float) zaehler / (float) fadetime ; 976 | progress = (progress < 0) ? 0 : progress; 977 | progress = (progress > 1) ? 1 : progress; 978 | 979 | #if defined(RGBW) || defined(GRBW) 980 | RgbwColor updatedColor = RgbwColor::LinearBlend( 981 | rgb_old[pixel], rgb_target[pixel], 982 | progress); 983 | #else 984 | RgbColor updatedColor = RgbColor::LinearBlend( 985 | rgb_old[pixel], rgb_target[pixel], 986 | progress); 987 | #endif 988 | 989 | if ( counter20ms > maxtime && Plugin_124_pixels->GetPixelColor(pixel).CalculateBrightness() == 0) { 990 | mode = Off; 991 | } else if ( counter20ms > maxtime ) { 992 | mode = On; 993 | } 994 | 995 | Plugin_124_pixels->SetPixelColor(pixel, updatedColor); 996 | } 997 | } 998 | 999 | void colorfade(void) { 1000 | float progress = 0; 1001 | difference = (endpixel - startpixel + pixelCount) % pixelCount; 1002 | for(uint16_t i = 0; i <= difference; i++) 1003 | { 1004 | 1005 | progress = (float) i / ( difference - 1 ); 1006 | progress = (progress >= 1) ? 1 : progress; 1007 | progress = (progress <= 0) ? 0 : progress; 1008 | 1009 | #if defined(RGBW) || defined(GRBW) 1010 | RgbwColor updatedColor = RgbwColor::LinearBlend( 1011 | rgb, rrggbb, 1012 | progress); 1013 | #else 1014 | RgbColor updatedColor = RgbColor::LinearBlend( 1015 | rgb, rrggbb, 1016 | progress); 1017 | #endif 1018 | 1019 | Plugin_124_pixels->SetPixelColor((i + startpixel)%pixelCount, updatedColor); 1020 | } 1021 | mode = On; 1022 | } 1023 | 1024 | 1025 | void wipe(void) { 1026 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0) { 1027 | if (speed > 0) { 1028 | Plugin_124_pixels->SetPixelColor(_counter_mode_step, rrggbb); 1029 | if ( _counter_mode_step > 0 ) Plugin_124_pixels->SetPixelColor( _counter_mode_step - 1, rgb); 1030 | } else { 1031 | Plugin_124_pixels->SetPixelColor(pixelCount - _counter_mode_step - 1, rrggbb); 1032 | if ( _counter_mode_step > 0 ) Plugin_124_pixels->SetPixelColor( pixelCount - _counter_mode_step, rgb); 1033 | } 1034 | if ( _counter_mode_step == pixelCount ) mode = On; 1035 | _counter_mode_step++; 1036 | } 1037 | } 1038 | 1039 | void dualwipe(void) { 1040 | if (counter20ms % (unsigned long)(SPEED_MAX / abs(speed)) == 0) { 1041 | if (speed > 0) { 1042 | int i = _counter_mode_step - pixelCount; 1043 | i = abs(i); 1044 | Plugin_124_pixels->SetPixelColor(_counter_mode_step, rrggbb); 1045 | Plugin_124_pixels->SetPixelColor(i, rgb); 1046 | if (_counter_mode_step > 0 ) { 1047 | Plugin_124_pixels->SetPixelColor(_counter_mode_step - 1, rgb); 1048 | Plugin_124_pixels->SetPixelColor(i - 1, rrggbb); 1049 | } 1050 | } else { 1051 | int i = (pixelCount / 2) - _counter_mode_step; 1052 | i = abs(i); 1053 | Plugin_124_pixels->SetPixelColor(_counter_mode_step + (pixelCount / 2), rrggbb); 1054 | Plugin_124_pixels->SetPixelColor(i, rgb); 1055 | if (_counter_mode_step > 0 ) { 1056 | Plugin_124_pixels->SetPixelColor(_counter_mode_step + (pixelCount / 2) - 1, rgb); 1057 | Plugin_124_pixels->SetPixelColor(i - 1, rrggbb); 1058 | } 1059 | } 1060 | if (_counter_mode_step >= pixelCount / 2) { 1061 | mode = On; 1062 | Plugin_124_pixels->SetPixelColor(_counter_mode_step - 1, rgb); 1063 | } 1064 | _counter_mode_step++; 1065 | } 1066 | } 1067 | 1068 | void faketv(void) { 1069 | if (counter20ms >= ftv_holdTime) { 1070 | 1071 | difference = abs(endpixel - startpixel); 1072 | 1073 | if (ftv_elapsed >= ftv_fadeTime) { 1074 | // Read next 16-bit (5/6/5) color 1075 | ftv_hi = pgm_read_byte(&ftv_colors[pixelNum * 2 ]); 1076 | ftv_lo = pgm_read_byte(&ftv_colors[pixelNum * 2 + 1]); 1077 | if(++pixelNum >= numPixels) pixelNum = 0; 1078 | 1079 | // Expand to 24-bit (8/8/8) 1080 | ftv_r8 = (ftv_hi & 0xF8) | (ftv_hi >> 5); 1081 | ftv_g8 = (ftv_hi << 5) | ((ftv_lo & 0xE0) >> 3) | ((ftv_hi & 0x06) >> 1); 1082 | ftv_b8 = (ftv_lo << 3) | ((ftv_lo & 0x1F) >> 2); 1083 | // Apply gamma correction, further expand to 16/16/16 1084 | ftv_nr = (uint8_t)pgm_read_byte(&ftv_gamma8[ftv_r8]) * 257; // New R/G/B 1085 | ftv_ng = (uint8_t)pgm_read_byte(&ftv_gamma8[ftv_g8]) * 257; 1086 | ftv_nb = (uint8_t)pgm_read_byte(&ftv_gamma8[ftv_b8]) * 257; 1087 | 1088 | ftv_totalTime = random(12, 125); // Semi-random pixel-to-pixel time 1089 | ftv_fadeTime = random(0, ftv_totalTime); // Pixel-to-pixel transition time 1090 | if(random(10) < 3) ftv_fadeTime = 0; // Force scene cut 30% of time 1091 | ftv_holdTime = counter20ms + ftv_totalTime - ftv_fadeTime; // Non-transition time 1092 | ftv_startTime = counter20ms; 1093 | } 1094 | 1095 | ftv_elapsed = counter20ms - ftv_startTime; 1096 | if(ftv_fadeTime) { 1097 | ftv_r = map(ftv_elapsed, 0, ftv_fadeTime, ftv_pr, ftv_nr); // 16-bit interp 1098 | ftv_g = map(ftv_elapsed, 0, ftv_fadeTime, ftv_pg, ftv_ng); 1099 | ftv_b = map(ftv_elapsed, 0, ftv_fadeTime, ftv_pb, ftv_nb); 1100 | } else { // Avoid divide-by-ftv_fraczero in map() 1101 | ftv_r = ftv_nr; 1102 | ftv_g = ftv_ng; 1103 | ftv_b = ftv_nb; 1104 | } 1105 | 1106 | for(ftv_i=0; ftv_i> 8; // Quantize to 8-bit 1108 | ftv_g8 = ftv_g >> 8; 1109 | ftv_b8 = ftv_b >> 8; 1110 | ftv_frac = (ftv_i << 16) / difference; // LED index scaled to 0-65535 (16Bit) 1111 | if((ftv_r8 < 255) && ((ftv_r & 0xFF) >= ftv_frac)) ftv_r8++; // Boost some fraction 1112 | if((ftv_g8 < 255) && ((ftv_g & 0xFF) >= ftv_frac)) ftv_g8++; // of LEDs to handle 1113 | if((ftv_b8 < 255) && ((ftv_b & 0xFF) >= ftv_frac)) ftv_b8++; // interp > 8bit 1114 | Plugin_124_pixels->SetPixelColor(ftv_i + startpixel, RgbColor(ftv_r8, ftv_g8, ftv_b8)); 1115 | } 1116 | 1117 | ftv_pr = ftv_nr; // Prev RGB = new RGB 1118 | ftv_pg = ftv_ng; 1119 | ftv_pb = ftv_nb; 1120 | } 1121 | } 1122 | 1123 | /* 1124 | * Cycles a rainbow over the entire string of LEDs. 1125 | */ 1126 | void rainbow(void) { 1127 | long zaehler = 20 * ( counter20ms - starttimerb ); 1128 | float progress = (float) zaehler / (float) fadetime ; 1129 | if (fadeIn == true) { 1130 | Plugin_124_pixels->SetBrightness(progress * 255); 1131 | fadeIn = (progress == 1) ? false : true; 1132 | } 1133 | for(int i=0; i< pixelCount; i++) 1134 | { 1135 | uint8_t r1 = (Wheel(((i * 256 / pixelCount) + counter20ms * rainbowspeed / 10) & 255) >> 16); 1136 | uint8_t g1 = (Wheel(((i * 256 / pixelCount) + counter20ms * rainbowspeed / 10) & 255) >> 8); 1137 | uint8_t b1 = (Wheel(((i * 256 / pixelCount) + counter20ms * rainbowspeed / 10) & 255)); 1138 | Plugin_124_pixels->SetPixelColor(i, RgbColor(r1, g1, b1)); 1139 | } 1140 | mode = (rainbowspeed == 0) ? On : Rainbow; 1141 | } 1142 | 1143 | 1144 | /* 1145 | * Put a value 0 to 255 in to get a color value. 1146 | * The colours are a transition r -> g -> b -> back to r 1147 | * Inspired by the Adafruit examples. 1148 | */ 1149 | uint32_t Wheel(uint8_t pos) { 1150 | pos = 255 - pos; 1151 | if(pos < 85) { 1152 | return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3); 1153 | } else if(pos < 170) { 1154 | pos -= 85; 1155 | return ((uint32_t)(0) << 16) | ((uint32_t)(pos * 3) << 8) | (255 - pos * 3); 1156 | } else { 1157 | pos -= 170; 1158 | return ((uint32_t)(pos * 3) << 16) | ((uint32_t)(255 - pos * 3) << 8) | (0); 1159 | } 1160 | } 1161 | 1162 | 1163 | // Larson Scanner K.I.T.T. 1164 | void kitt(void) { 1165 | 1166 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0) 1167 | { 1168 | for(uint16_t i=0; i < pixelCount; i++) { 1169 | 1170 | #if defined(RGBW) || defined(GRBW) 1171 | RgbwColor px_rgb = Plugin_124_pixels->GetPixelColor(i); 1172 | 1173 | // fade out (divide by 2) 1174 | px_rgb.R = px_rgb.R >> 1; 1175 | px_rgb.G = px_rgb.G >> 1; 1176 | px_rgb.B = px_rgb.B >> 1; 1177 | px_rgb.W = px_rgb.W >> 1; 1178 | 1179 | #else 1180 | 1181 | RgbColor px_rgb = Plugin_124_pixels->GetPixelColor(i); 1182 | 1183 | // fade out (divide by 2) 1184 | px_rgb.R = px_rgb.R >> 1; 1185 | px_rgb.G = px_rgb.G >> 1; 1186 | px_rgb.B = px_rgb.B >> 1; 1187 | #endif 1188 | 1189 | Plugin_124_pixels->SetPixelColor(i, px_rgb); 1190 | } 1191 | 1192 | uint16_t pos = 0; 1193 | 1194 | if(_counter_mode_step < pixelCount) { 1195 | pos = _counter_mode_step; 1196 | } else { 1197 | pos = (pixelCount * 2) - _counter_mode_step - 2; 1198 | } 1199 | 1200 | Plugin_124_pixels->SetPixelColor(pos, rgb); 1201 | 1202 | _counter_mode_step = (_counter_mode_step + 1) % ((pixelCount * 2) - 2); 1203 | } 1204 | } 1205 | 1206 | 1207 | //Firing comets from one end. 1208 | void comet(void) { 1209 | 1210 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0) 1211 | { 1212 | for(uint16_t i=0; i < pixelCount; i++) { 1213 | 1214 | if (speed > 0) { 1215 | 1216 | #if defined(RGBW) || defined(GRBW) 1217 | RgbwColor px_rgb = Plugin_124_pixels->GetPixelColor(i); 1218 | 1219 | // fade out (divide by 2) 1220 | px_rgb.R = px_rgb.R >> 1; 1221 | px_rgb.G = px_rgb.G >> 1; 1222 | px_rgb.B = px_rgb.B >> 1; 1223 | px_rgb.W = px_rgb.W >> 1; 1224 | 1225 | #else 1226 | 1227 | RgbColor px_rgb = Plugin_124_pixels->GetPixelColor(i); 1228 | 1229 | // fade out (divide by 2) 1230 | px_rgb.R = px_rgb.R >> 1; 1231 | px_rgb.G = px_rgb.G >> 1; 1232 | px_rgb.B = px_rgb.B >> 1; 1233 | #endif 1234 | 1235 | Plugin_124_pixels->SetPixelColor(i, px_rgb); 1236 | 1237 | } else { 1238 | 1239 | 1240 | #if defined(RGBW) || defined(GRBW) 1241 | RgbwColor px_rgb = Plugin_124_pixels->GetPixelColor(pixelCount -i -1); 1242 | 1243 | // fade out (divide by 2) 1244 | px_rgb.R = px_rgb.R >> 1; 1245 | px_rgb.G = px_rgb.G >> 1; 1246 | px_rgb.B = px_rgb.B >> 1; 1247 | px_rgb.W = px_rgb.W >> 1; 1248 | 1249 | #else 1250 | 1251 | RgbColor px_rgb = Plugin_124_pixels->GetPixelColor(pixelCount -i -1); 1252 | 1253 | // fade out (divide by 2) 1254 | px_rgb.R = px_rgb.R >> 1; 1255 | px_rgb.G = px_rgb.G >> 1; 1256 | px_rgb.B = px_rgb.B >> 1; 1257 | #endif 1258 | 1259 | Plugin_124_pixels->SetPixelColor(pixelCount -i -1, px_rgb); 1260 | } 1261 | } 1262 | 1263 | if (speed > 0) { 1264 | Plugin_124_pixels->SetPixelColor(_counter_mode_step, rgb); 1265 | } else { 1266 | Plugin_124_pixels->SetPixelColor(pixelCount - _counter_mode_step -1, rgb); 1267 | } 1268 | 1269 | _counter_mode_step = (_counter_mode_step + 1) % pixelCount; 1270 | } 1271 | } 1272 | 1273 | 1274 | //Theatre lights 1275 | void theatre(void) { 1276 | 1277 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0 && speed != 0) 1278 | { 1279 | if (speed > 0) { 1280 | Plugin_124_pixels->RotateLeft(1,0,(pixelCount/count)*count-1); 1281 | } else { 1282 | Plugin_124_pixels->RotateRight(1,0,(pixelCount/count)*count-1); 1283 | } 1284 | } 1285 | } 1286 | 1287 | 1288 | /* 1289 | * Runs a single pixel back and forth. 1290 | */ 1291 | void scan(void) { 1292 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0 && speed != 0) 1293 | { 1294 | if(_counter_mode_step > uint16_t((pixelCount*2) - 2)) { 1295 | _counter_mode_step = 0; 1296 | } 1297 | _counter_mode_step++; 1298 | 1299 | int i = _counter_mode_step - (pixelCount - 1); 1300 | i = abs(i); 1301 | 1302 | //Plugin_124_pixels->ClearTo(rrggbb); 1303 | for (int i = 0; i < pixelCount; i++) Plugin_124_pixels->SetPixelColor(i,rrggbb); 1304 | Plugin_124_pixels->SetPixelColor(abs(i), rgb); 1305 | } 1306 | 1307 | } 1308 | 1309 | 1310 | /* 1311 | * Runs two pixel back and forth in opposite directions. 1312 | */ 1313 | void dualscan(void) { 1314 | 1315 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0 && speed != 0) { 1316 | if(_counter_mode_step > uint16_t((pixelCount*2) - 2)) { 1317 | _counter_mode_step = 0; 1318 | } 1319 | 1320 | _counter_mode_step++; 1321 | 1322 | int i = _counter_mode_step - (pixelCount - 1); 1323 | i = abs(i); 1324 | 1325 | //Plugin_124_pixels->ClearTo(rrggbb); 1326 | for (int i = 0; i < pixelCount; i++) Plugin_124_pixels->SetPixelColor(i,rrggbb); 1327 | Plugin_124_pixels->SetPixelColor(abs(i), rgb); 1328 | Plugin_124_pixels->SetPixelColor(pixelCount - (i+1), rgb); 1329 | 1330 | } 1331 | } 1332 | 1333 | 1334 | /* 1335 | * Blink several LEDs on, reset, repeat. 1336 | * Inspired by www.tweaking4all.com/hardware/arduino/arduino-led-strip-effects/ 1337 | */ 1338 | void twinkle(void) { 1339 | 1340 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0 && speed != 0) 1341 | { 1342 | if(_counter_mode_step == 0) { 1343 | //Plugin_124_pixels->ClearTo(rrggbb); 1344 | for (int i = 0; i < pixelCount; i++) Plugin_124_pixels->SetPixelColor(i,rrggbb); 1345 | uint16_t min_leds = _max(1, pixelCount/5); // make sure, at least one LED is on 1346 | uint16_t max_leds = _max(1, pixelCount/2); // make sure, at least one LED is on 1347 | _counter_mode_step = random(min_leds, max_leds); 1348 | } 1349 | 1350 | Plugin_124_pixels->SetPixelColor(random(pixelCount), rgb); 1351 | 1352 | _counter_mode_step--; 1353 | } 1354 | } 1355 | 1356 | 1357 | /* 1358 | * Blink several LEDs on, fading out. 1359 | */ 1360 | void twinklefade(void) { 1361 | 1362 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0 && speed != 0) 1363 | { 1364 | for(uint16_t i=0; i < pixelCount; i++) { 1365 | 1366 | #if defined(RGBW) || defined(GRBW) 1367 | RgbwColor px_rgb = Plugin_124_pixels->GetPixelColor(pixelCount -i -1); 1368 | 1369 | // fade out (divide by 2) 1370 | px_rgb.R = px_rgb.R >> 1; 1371 | px_rgb.G = px_rgb.G >> 1; 1372 | px_rgb.B = px_rgb.B >> 1; 1373 | px_rgb.W = px_rgb.W >> 1; 1374 | 1375 | #else 1376 | 1377 | RgbColor px_rgb = Plugin_124_pixels->GetPixelColor(pixelCount -i -1); 1378 | 1379 | // fade out (divide by 2) 1380 | px_rgb.R = px_rgb.R >> 1; 1381 | px_rgb.G = px_rgb.G >> 1; 1382 | px_rgb.B = px_rgb.B >> 1; 1383 | #endif 1384 | 1385 | Plugin_124_pixels->SetPixelColor(i, px_rgb); 1386 | } 1387 | 1388 | if(random(count) < 50) { 1389 | Plugin_124_pixels->SetPixelColor(random(pixelCount), rgb); 1390 | } 1391 | } 1392 | } 1393 | 1394 | 1395 | /* 1396 | * Blinks one LED at a time. 1397 | * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ 1398 | */ 1399 | void sparkle(void) { 1400 | 1401 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0 && speed != 0) 1402 | { 1403 | //Plugin_124_pixels->ClearTo(rrggbb); 1404 | for (int i = 0; i < pixelCount; i++) Plugin_124_pixels->SetPixelColor(i,rrggbb); 1405 | Plugin_124_pixels->SetPixelColor(random(pixelCount), rgb); 1406 | } 1407 | } 1408 | 1409 | //Fire 1410 | unsigned long fireTimer; 1411 | RgbColor leds[ARRAYSIZE]; 1412 | 1413 | void fire(void) { 1414 | 1415 | if (counter20ms > fireTimer + 50 / fps) { 1416 | fireTimer = counter20ms; 1417 | Fire2012(); 1418 | RgbColor pixel; 1419 | 1420 | for (int i = 0; i < pixelCount; i++) { 1421 | pixel = leds[i]; 1422 | pixel = RgbColor::LinearBlend(pixel, RgbColor(0, 0, 0), (255 - brightness)/255.0); 1423 | Plugin_124_pixels->SetPixelColor(i, pixel); 1424 | } 1425 | } 1426 | } 1427 | 1428 | /// random number seed 1429 | uint16_t rand16seed;// = RAND16_SEED; 1430 | 1431 | /// Generate an 8-bit random number 1432 | uint8_t random8() 1433 | { 1434 | rand16seed = (rand16seed * ((uint16_t)(2053))) + ((uint16_t)(13849)); 1435 | // return the sum of the high and low bytes, for better 1436 | // mixing and non-sequential correlation 1437 | return (uint8_t)(((uint8_t)(rand16seed & 0xFF)) + 1438 | ((uint8_t)(rand16seed >> 8))); 1439 | } 1440 | 1441 | /// Generate an 8-bit random number between 0 and lim 1442 | /// @param lim the upper bound for the result 1443 | uint8_t random8(uint8_t lim) 1444 | { 1445 | uint8_t r = random8(); 1446 | r = (r*lim) >> 8; 1447 | return r; 1448 | } 1449 | 1450 | /// Generate an 8-bit random number in the given range 1451 | /// @param min the lower bound for the random number 1452 | /// @param lim the upper bound for the random number 1453 | uint8_t random8(uint8_t min, uint8_t lim) 1454 | { 1455 | uint8_t delta = lim - min; 1456 | uint8_t r = random8(delta) + min; 1457 | return r; 1458 | } 1459 | 1460 | /// subtract one byte from another, saturating at 0x00 1461 | /// @returns i - j with a floor of 0 1462 | uint8_t qsub8( uint8_t i, uint8_t j) 1463 | { 1464 | int t = i - j; 1465 | if( t < 0) t = 0; 1466 | return t; 1467 | } 1468 | 1469 | /// add one byte to another, saturating at 0xFF 1470 | /// @param i - first byte to add 1471 | /// @param j - second byte to add 1472 | /// @returns the sum of i & j, capped at 0xFF 1473 | uint8_t qadd8( uint8_t i, uint8_t j) 1474 | { 1475 | unsigned int t = i + j; 1476 | if( t > 255) t = 255; 1477 | return t; 1478 | } 1479 | 1480 | /// The "video" version of scale8 guarantees that the output will 1481 | /// be only be zero if one or both of the inputs are zero. If both 1482 | /// inputs are non-zero, the output is guaranteed to be non-zero. 1483 | /// This makes for better 'video'/LED dimming, at the cost of 1484 | /// several additional cycles. 1485 | uint8_t scale8_video( uint8_t i, uint8_t scale) 1486 | { 1487 | uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0); 1488 | // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; 1489 | // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; 1490 | return j; 1491 | } 1492 | 1493 | void Fire2012(void) { 1494 | // Array of temperature readings at each simulation cell 1495 | static byte heat[ARRAYSIZE]; 1496 | 1497 | // Step 1. Cool down every cell a little 1498 | for ( int i = 0; i < pixelCount; i++) { 1499 | heat[i] = qsub8( heat[i], random8(0, ((cooling * 10) / pixelCount) + 2)); 1500 | } 1501 | 1502 | // Step 2. Heat from each cell drifts 'up' and diffuses a little 1503 | for ( int k = pixelCount - 1; k >= 2; k--) { 1504 | heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; 1505 | } 1506 | 1507 | // Step 3. Randomly ignite new 'sparks' of heat near the bottom 1508 | if ( random8() < sparking ) { 1509 | int y = random8(7); 1510 | heat[y] = qadd8( heat[y], random8(160, 255) ); 1511 | } 1512 | 1513 | // Step 4. Map from heat cells to LED colors 1514 | for ( int j = 0; j < pixelCount; j++) { 1515 | 1516 | RgbColor heatcolor; 1517 | 1518 | // Scale 'heat' down from 0-255 to 0-191, 1519 | // which can then be easily divided into three 1520 | // equal 'thirds' of 64 units each. 1521 | uint8_t t192 = scale8_video( heat[j], 191); 1522 | 1523 | // calculate a value that ramps up from 1524 | // zero to 255 in each 'third' of the scale. 1525 | uint8_t heatramp = t192 & 0x3F; // 0..63 1526 | heatramp <<= 2; // scale up to 0..252 1527 | 1528 | // now figure out which third of the spectrum we're in: 1529 | if( t192 & 0x80) { 1530 | // we're in the hottest third 1531 | heatcolor.R = 255; // full red 1532 | heatcolor.G = 255; // full green 1533 | heatcolor.B = heatramp; // ramp up blue 1534 | 1535 | } else if( t192 & 0x40 ) { 1536 | // we're in the middle third 1537 | heatcolor.R = 255; // full red 1538 | heatcolor.G = heatramp; // ramp up green 1539 | heatcolor.B = 0; // no blue 1540 | 1541 | } else { 1542 | // we're in the coolest third 1543 | heatcolor.R = heatramp; // ramp up red 1544 | heatcolor.G = 0; // no green 1545 | heatcolor.B = 0; // no blue 1546 | } 1547 | 1548 | int pixelnumber; 1549 | if ( gReverseDirection ) { 1550 | pixelnumber = (pixelCount - 1) - j; 1551 | } else { 1552 | pixelnumber = j; 1553 | } 1554 | leds[pixelnumber] = heatcolor; 1555 | } 1556 | } 1557 | 1558 | /* 1559 | * Fire flicker function 1560 | */ 1561 | void fire_flicker() { 1562 | if (counter20ms % (unsigned long)( SPEED_MAX / abs(speed) ) == 0 && speed != 0) 1563 | { 1564 | byte w = 0; //(SEGMENT.colors[0] >> 24) & 0xFF; 1565 | byte r = 255; //(SEGMENT.colors[0] >> 16) & 0xFF; 1566 | byte g = 96; //(SEGMENT.colors[0] >> 8) & 0xFF; 1567 | byte b = 12; //(SEGMENT.colors[0] & 0xFF); 1568 | byte lum = max(w, max(r, max(g, b))) / rev_intensity; 1569 | for(uint16_t i=0; i <= numPixels-1; i++) { 1570 | int flicker = random8(lum); 1571 | 1572 | #if defined(RGBW) || defined(GRBW) 1573 | Plugin_124_pixels->SetPixelColor(i, RgbwColor (max(r - flicker, 0), max(g - flicker, 0), max(b - flicker, 0), max(w - flicker, 0))); 1574 | #else 1575 | Plugin_124_pixels->SetPixelColor(i, RgbColor (max(r - flicker, 0), max(g - flicker, 0), max(b - flicker, 0))); 1576 | #endif 1577 | } 1578 | } 1579 | } 1580 | 1581 | void Plugin_124_simpleclock() 1582 | { 1583 | byte Hours = node_time.hour()%12; 1584 | byte Minutes = node_time.minute(); 1585 | byte Seconds = node_time.second(); 1586 | byte big_tick = 15; 1587 | byte small_tick = 5; 1588 | 1589 | //hack for sub-second calculations.... reset when first time new second begins.. 1590 | if (cooling != Seconds) maxtime = counter20ms; 1591 | cooling = Seconds; 1592 | Plugin_124_pixels->ClearTo(rrggbb); 1593 | 1594 | for (int i = 0; i < (60/small_tick); i++) { 1595 | if (i%(big_tick/small_tick) == 0) Plugin_124_pixels->SetPixelColor((i*pixelCount*small_tick/60)%pixelCount, rgb_tick_b); 1596 | else Plugin_124_pixels->SetPixelColor((i*pixelCount*small_tick/60)%pixelCount, rgb_tick_s); 1597 | } 1598 | 1599 | 1600 | for(int i = 0; i < pixelCount; i++ ) { 1601 | if ( round((((float)Seconds + ((float)counter20ms-(float)maxtime)/50.0) * (float)pixelCount)/60.0 ) == i ) { 1602 | if ( rgb_s_off == false ) { 1603 | Plugin_124_pixels->SetPixelColor(i, rgb_s); 1604 | } 1605 | } 1606 | else if ( round((((float)Minutes * 60.0)+(float)Seconds)/60.0 * (float)pixelCount / 60.0) == i ) { 1607 | Plugin_124_pixels->SetPixelColor(i, rgb_m); 1608 | } 1609 | else if ( round(((float)Hours+(float)Minutes/60) * (float)pixelCount / 12.0) == i ) { 1610 | Plugin_124_pixels->SetPixelColor(i, rgb_h); 1611 | Plugin_124_pixels->SetPixelColor((i+1)%pixelCount, rgb_h); 1612 | Plugin_124_pixels->SetPixelColor((i-1+pixelCount)%pixelCount, rgb_h); 1613 | } 1614 | } 1615 | } 1616 | 1617 | 1618 | uint32_t rgbStr2Num(String rgbStr) { 1619 | uint32_t rgbDec = (int) strtoul( &rgbStr[0], NULL, 16); 1620 | return rgbDec; 1621 | } 1622 | 1623 | void hex2rgb(String hexcolor) { 1624 | colorStr = hexcolor; 1625 | #if defined(RGBW) || defined(GRBW) 1626 | hexcolor.length() <= 6 1627 | ? rgb = RgbColor ( rgbStr2Num(hexcolor) >> 16, rgbStr2Num(hexcolor) >> 8, rgbStr2Num(hexcolor) ) 1628 | : rgb = RgbwColor ( rgbStr2Num(hexcolor) >> 24, rgbStr2Num(hexcolor) >> 16, rgbStr2Num(hexcolor) >> 8, rgbStr2Num(hexcolor) ); 1629 | #else 1630 | rgb = RgbColor ( rgbStr2Num(hexcolor) >> 16, rgbStr2Num(hexcolor) >> 8, rgbStr2Num(hexcolor) ); 1631 | #endif 1632 | } 1633 | 1634 | void hex2rrggbb(String hexcolor) { 1635 | backgroundcolorStr = hexcolor; 1636 | #if defined(RGBW) || defined(GRBW) 1637 | hexcolor.length() <= 6 1638 | ? rrggbb = RgbColor ( rgbStr2Num(hexcolor) >> 16, rgbStr2Num(hexcolor) >> 8, rgbStr2Num(hexcolor) ) 1639 | : rrggbb = RgbwColor ( rgbStr2Num(hexcolor) >> 24, rgbStr2Num(hexcolor) >> 16, rgbStr2Num(hexcolor) >> 8, rgbStr2Num(hexcolor) ); 1640 | #else 1641 | rrggbb = RgbColor ( rgbStr2Num(hexcolor) >> 16, rgbStr2Num(hexcolor) >> 8, rgbStr2Num(hexcolor) ); 1642 | #endif 1643 | } 1644 | 1645 | void hex2rgb_pixel(String hexcolor) { 1646 | colorStr = hexcolor; 1647 | for ( int i = 0; i < pixelCount; i++) { 1648 | #if defined(RGBW) || defined(GRBW) 1649 | hexcolor.length() <= 6 1650 | ? rgb_target[i] = RgbColor ( rgbStr2Num(hexcolor) >> 16, rgbStr2Num(hexcolor) >> 8, rgbStr2Num(hexcolor) ) 1651 | : rgb_target[i] = RgbwColor ( rgbStr2Num(hexcolor) >> 24, rgbStr2Num(hexcolor) >> 16, rgbStr2Num(hexcolor) >> 8, rgbStr2Num(hexcolor) ); 1652 | #else 1653 | rgb_target[i] = RgbColor ( rgbStr2Num(hexcolor) >> 16, rgbStr2Num(hexcolor) >> 8, rgbStr2Num(hexcolor) ); 1654 | #endif 1655 | } 1656 | } 1657 | 1658 | // --------------------------------------------------------------------------------- 1659 | // ------------------------------ JsonResponse ------------------------------------- 1660 | // --------------------------------------------------------------------------------- 1661 | void NeoPixelSendStatus(struct EventStruct *eventSource) { 1662 | String log = String(F("NeoPixelBusFX: Set ")) + rgb.R 1663 | + String(F("/")) + rgb.G + String(F("/")) + rgb.B; 1664 | addLog(LOG_LEVEL_INFO, log); 1665 | 1666 | String json; 1667 | printToWebJSON = true; 1668 | json += F("{\n"); 1669 | json += F("\"plugin\": \"124"); 1670 | json += F("\",\n\"mode\": \""); 1671 | json += modeName[mode]; 1672 | json += F("\",\n\"lastmode\": \""); 1673 | json += modeName[savemode]; 1674 | json += F("\",\n\"fadetime\": \""); 1675 | json += fadetime; 1676 | json += F("\",\n\"fadedelay\": \""); 1677 | json += fadedelay; 1678 | json += F("\",\n\"dim\": \""); 1679 | json += Plugin_124_pixels->GetBrightness(); 1680 | json += F("\",\n\"rgb\": \""); 1681 | json += colorStr; 1682 | json += F("\",\n\"hue\": \""); 1683 | json += toString((HsbColor(RgbColor(rgb.R,rgb.G,rgb.B)).H * 360),0); 1684 | json += F("\",\n\"saturation\": \""); 1685 | json += toString((HsbColor(RgbColor(rgb.R,rgb.G,rgb.B)).S * 100),0); 1686 | json += F("\",\n\"brightness\": \""); 1687 | json += toString((HsbColor(RgbColor(rgb.R,rgb.G,rgb.B)).B * 100),0); 1688 | json += F("\",\n\"bgcolor\": \""); 1689 | json += backgroundcolorStr; 1690 | json += F("\",\n\"count\": \""); 1691 | json += count; 1692 | json += F("\",\n\"speed\": \""); 1693 | json += speed; 1694 | json += F("\",\n\"pixelcount\": \""); 1695 | json += pixelCount; 1696 | json += F("\"\n}\n"); 1697 | SendStatus(eventSource, json); // send http response to controller (JSON format) 1698 | printToWeb=false; 1699 | } 1700 | #endif // USES_P124 1701 | --------------------------------------------------------------------------------