IronEnder17

tycho

Jul 11th, 2025
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.14 KB | None | 0 0
  1. #include <FastLED.h>
  2.  
  3.  
  4.  
  5. #define LED_TYPE WS2812B
  6. #define COLOR_ORDER GRB
  7.  
  8. //bussard setup
  9.  
  10. #define DATA_PIN1 3
  11. #define NUM_LEDS1 8
  12.  
  13. CRGBArray<NUM_LEDS1> leds1;
  14.  
  15. #define TWINKLE_SPEED 5
  16. #define TWINKLE_DENSITY 8
  17. #define SECONDS_PER_PALETTE 30
  18.  
  19. CRGB gBackgroundColor = CRGB::Black;
  20.  
  21. #define AUTO_SELECT_BACKGROUND_COLOR 0
  22. #define COOL_LIKE_INCANDESCENT 1
  23.  
  24. CRGBPalette16 gCurrentPalette;
  25. CRGBPalette16 gTargetPalette;
  26.  
  27. //warp setup
  28.  
  29. #define DATA_PIN2 5
  30. #define NUM_LEDS2 30
  31. #define MAX_POWER_MILLIAMPS 500
  32.  
  33. #define FASTLED_ALLOW_INTERRUPTS 0
  34. FASTLED_USING_NAMESPACE
  35.  
  36. //deflector setup
  37.  
  38. //////////////////////////////////////////////////////////////////////////
  39.  
  40. CRGB leds2[NUM_LEDS2];
  41.  
  42. void setup() {
  43. //bussard
  44.  
  45. delay(3000); //safety startup delay
  46. FastLED.addLeds<LED_TYPE, DATA_PIN1, COLOR_ORDER>(leds1, NUM_LEDS1)
  47. .setCorrection(TypicalLEDStrip);
  48. chooseNextColorPalette(gTargetPalette);
  49.  
  50. //warp
  51.  
  52. FastLED.addLeds<LED_TYPE, DATA_PIN2, COLOR_ORDER>(leds2, NUM_LEDS2)
  53. .setCorrection(TypicalLEDStrip);
  54. FastLED.setMaxPowerInVoltsAndMilliamps(5, MAX_POWER_MILLIAMPS);
  55. }
  56.  
  57. void loop()
  58. {
  59. EVERY_N_SECONDS(SECONDS_PER_PALETTE) {
  60. chooseNextColorPalette(gTargetPalette);
  61. }
  62. EVERY_N_MILLISECONDS(10) {
  63. nblendPaletteTowardPalette(gCurrentPalette, gTargetPalette, 12);
  64. }
  65.  
  66. drawTwinkles(leds1);
  67.  
  68. FastLED.show();
  69. }
  70.  
  71.  
  72. void drawTwinkles(CRGBSet& L) {
  73.  
  74. uint16_t PRNG16 = 11337;
  75.  
  76. uint32_t clock32 = millis();
  77.  
  78. CRGB bg;
  79. if ((AUTO_SELECT_BACKGROUND_COLOR == 1) && (gCurrentPalette[0] == gCurrentPalette[1])) {
  80. bg = gCurrentPalette[0];
  81. uint8_t bglight = bg.getAverageLight();
  82. if (bglight > 64) {
  83. bg.nscale8_video(16); // very bright, so scale to 1/16th
  84. } else if (bglight > 16) {
  85. bg.nscale8_video(64); // not that bright, so scale to 1/4th
  86. } else {
  87. bg.nscale8_video(86); // dim, scale to 1/3rd.
  88. }
  89. } else {
  90. bg = gBackgroundColor; // just use the explicitly defined background color
  91. }
  92.  
  93. uint8_t backgroundBrightness = bg.getAverageLight();
  94.  
  95. for (CRGB& pixel : L) {
  96. PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
  97. uint16_t myclockoffset16 = PRNG16; // use that number as clock offset
  98. PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
  99. // use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths)
  100. uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF) >> 4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08;
  101. uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16;
  102. uint8_t myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel
  103.  
  104. // We now have the adjusted 'clock' for this pixel, now we call
  105. // the function that computes what color the pixel should be based
  106. // on the "brightness = f( time )" idea.
  107. CRGB c = computeOneTwinkle(myclock30, myunique8);
  108.  
  109. uint8_t cbright = c.getAverageLight();
  110. int16_t deltabright = cbright - backgroundBrightness;
  111. if (deltabright >= 32 || (!bg)) {
  112. // If the new pixel is significantly brighter than the background color,
  113. // use the new color.
  114. pixel = c;
  115. } else if (deltabright > 0) {
  116. // If the new pixel is just slightly brighter than the background color,
  117. // mix a blend of the new color and the background color
  118. pixel = blend(bg, c, deltabright * 8);
  119. } else {
  120. // if the new pixel is not at all brighter than the background color,
  121. // just use the background color.
  122. pixel = bg;
  123. }
  124. }
  125. }
  126.  
  127. CRGB computeOneTwinkle(uint32_t ms, uint8_t salt) {
  128. uint16_t ticks = ms >> (8 - TWINKLE_SPEED);
  129. uint8_t fastcycle8 = ticks;
  130. uint16_t slowcycle16 = (ticks >> 8) + salt;
  131. slowcycle16 += sin8(slowcycle16);
  132. slowcycle16 = (slowcycle16 * 2053) + 1384;
  133. uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8);
  134.  
  135. uint8_t bright = 0;
  136. if (((slowcycle8 & 0x0E) / 2) < TWINKLE_DENSITY) {
  137. bright = attackDecayWave8(fastcycle8);
  138. }
  139.  
  140. uint8_t hue = slowcycle8 - salt;
  141. CRGB c;
  142. if (bright > 0) {
  143. c = ColorFromPalette(gCurrentPalette, hue, bright, NOBLEND);
  144. if (COOL_LIKE_INCANDESCENT == 1) {
  145. coolLikeIncandescent(c, fastcycle8);
  146. }
  147. } else {
  148. c = CRGB::Black;
  149. }
  150. return c;
  151. }
  152.  
  153. uint8_t attackDecayWave8(uint8_t i) {
  154. if (i < 86) {
  155. return i * 3;
  156. } else {
  157. i -= 86;
  158. return 255 - (i + (i / 2));
  159. }
  160. }
  161.  
  162. void coolLikeIncandescent(CRGB& c, uint8_t phase) {
  163. if (phase < 128) return;
  164.  
  165. uint8_t cooling = (phase - 128) >> 4;
  166. c.g = qsub8(c.g, cooling);
  167. c.b = qsub8(c.b, cooling * 2);
  168. }
  169.  
  170. // A mostly red palette with green accents and white trim.
  171. // "CRGB::Gray" is used as white to keep the brightness more uniform.
  172. const TProgmemRGBPalette16 RedGreenWhite_p FL_PROGMEM = { CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
  173. CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
  174. CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,
  175. CRGB::Green, CRGB::Green, CRGB::Green, CRGB::Green };
  176.  
  177. // A mostly (dark) green palette with red berries.
  178. #define Holly_Green 0x00580c
  179. #define Holly_Red 0xB00402
  180. const TProgmemRGBPalette16 Holly_p FL_PROGMEM = { Holly_Green, Holly_Green, Holly_Green, Holly_Green,
  181. Holly_Green, Holly_Green, Holly_Green, Holly_Green,
  182. Holly_Green, Holly_Green, Holly_Green, Holly_Green,
  183. Holly_Green, Holly_Green, Holly_Green, Holly_Red };
  184.  
  185. // A red and white striped palette
  186. // "CRGB::Gray" is used as white to keep the brightness more uniform.
  187. const TProgmemRGBPalette16 RedWhite_p FL_PROGMEM = { CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
  188. CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray,
  189. CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
  190. CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray };
  191.  
  192. // A mostly blue palette with white accents.
  193. // "CRGB::Gray" is used as white to keep the brightness more uniform.
  194. const TProgmemRGBPalette16 BlueWhite_p FL_PROGMEM = { CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
  195. CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
  196. CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
  197. CRGB::Blue, CRGB::Gray, CRGB::Gray, CRGB::Gray };
  198.  
  199. // A pure "fairy light" palette with some brightness variations
  200. #define HALFFAIRY ((CRGB::FairyLight & 0xFEFEFE) / 2)
  201. #define QUARTERFAIRY ((CRGB::FairyLight & 0xFCFCFC) / 4)
  202. const TProgmemRGBPalette16 FairyLight_p FL_PROGMEM = { CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight,
  203. HALFFAIRY, HALFFAIRY, CRGB::FairyLight, CRGB::FairyLight,
  204. QUARTERFAIRY, QUARTERFAIRY, CRGB::FairyLight, CRGB::FairyLight,
  205. CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight };
  206.  
  207. // A palette of soft snowflakes with the occasional bright one
  208. const TProgmemRGBPalette16 Snow_p FL_PROGMEM = { 0x304048, 0x304048, 0x304048, 0x304048,
  209. 0x304048, 0x304048, 0x304048, 0x304048,
  210. 0x304048, 0x304048, 0x304048, 0x304048,
  211. 0x304048, 0x304048, 0x304048, 0xE0F0FF };
  212.  
  213. // A palette reminiscent of large 'old-school' C9-size tree lights
  214. // in the five classic colors: red, orange, green, blue, and white.
  215. #define C9_Red 0xB80400
  216. #define C9_Orange 0x902C02
  217. #define C9_Green 0x046002
  218. #define C9_Blue 0x070758
  219. #define C9_White 0x606820
  220. const TProgmemRGBPalette16 RetroC9_p FL_PROGMEM = { C9_Red, C9_Orange, C9_Red, C9_Orange,
  221. C9_Orange, C9_Red, C9_Orange, C9_Red,
  222. C9_Green, C9_Green, C9_Green, C9_Green,
  223. C9_Blue, C9_Blue, C9_Blue,
  224. C9_White };
  225.  
  226. // A cold, icy pale blue palette
  227. #define Ice_Blue1 0x0C1040
  228. #define Ice_Blue2 0x182080
  229. #define Ice_Blue3 0x5080C0
  230. const TProgmemRGBPalette16 Ice_p FL_PROGMEM = {
  231. Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
  232. Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
  233. Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
  234. Ice_Blue2, Ice_Blue2, Ice_Blue2, Ice_Blue3
  235. };
  236.  
  237.  
  238. // Add or remove palette names from this list to control which color
  239. // palettes are used, and in what order.
  240. const TProgmemRGBPalette16* ActivePaletteList[] = {
  241. &FairyLight_p,
  242. };
  243.  
  244.  
  245. // Advance to the next color palette in the list (above).
  246. void chooseNextColorPalette(CRGBPalette16& pal) {
  247. const uint8_t numberOfPalettes = sizeof(ActivePaletteList) / sizeof(ActivePaletteList[0]);
  248. static uint8_t whichPalette = -1;
  249. whichPalette = addmod8(whichPalette, 1, numberOfPalettes);
  250.  
  251. pal = *(ActivePaletteList[whichPalette]);
  252. }
  253.  
  254. //warp
  255.  
  256. EVERY_N_MILLISECONDS(20) {
  257. pacifica_loop();
  258. FastLED.show();
  259. }
  260.  
  261.  
  262. CRGBPalette16 pacifica_palette_1 = { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
  263. 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 };
  264. CRGBPalette16 pacifica_palette_2 = { 0x000007, 0x000009, 0x00000B, 0x00000D, 0x000010, 0x000012, 0x000014, 0x000017,
  265. 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F };
  266. CRGBPalette16 pacifica_palette_3 = { 0x010018, 0x030025, 0x020014, 0x03001A, 0x100020, 0x050027, 0x010020, 0x010030,
  267. 0x090039, 0x030040, 0x050050, 0x000060, 0x000070, 0x030380, 0x101010, 0x100510 };
  268.  
  269.  
  270. void pacifica_loop() {
  271. // Increment the four "color index start" counters, one for each wave layer.
  272. // Each is incremented at a different speed, and the speeds vary over time.
  273. static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4;
  274. static uint32_t sLastms = 0;
  275. uint32_t ms = GET_MILLIS();
  276. uint32_t deltams = ms - sLastms;
  277. sLastms = ms;
  278. uint16_t speedfactor1 = beatsin16(3, 179, 269);
  279. uint16_t speedfactor2 = beatsin16(4, 179, 269);
  280. uint32_t deltams1 = (deltams * speedfactor1) / 256;
  281. uint32_t deltams2 = (deltams * speedfactor2) / 256;
  282. uint32_t deltams21 = (deltams1 + deltams2) / 2;
  283. sCIStart1 += (deltams1 * beatsin88(1011, 10, 13));
  284. sCIStart2 -= (deltams21 * beatsin88(777, 8, 11));
  285. sCIStart3 -= (deltams1 * beatsin88(501, 5, 7));
  286. sCIStart4 -= (deltams2 * beatsin88(257, 4, 6));
  287.  
  288. // Clear out the LED array to a dim background blue-green
  289. fill_solid(leds2, NUM_LEDS2, CRGB(2, 6, 10));
  290.  
  291. // Render each of four layers, with different scales and speeds, that vary over time
  292. pacifica_one_layer(pacifica_palette_1, sCIStart1, beatsin16(3, 11 * 256, 14 * 256), beatsin8(10, 70, 130), 0 - beat16(301));
  293. pacifica_one_layer(pacifica_palette_2, sCIStart2, beatsin16(4, 6 * 256, 9 * 256), beatsin8(17, 40, 80), beat16(401));
  294. pacifica_one_layer(pacifica_palette_3, sCIStart3, 6 * 256, beatsin8(9, 10, 38), 0 - beat16(503));
  295. pacifica_one_layer(pacifica_palette_3, sCIStart4, 5 * 256, beatsin8(8, 10, 28), beat16(601));
  296.  
  297. // Add brighter 'whitecaps' where the waves lines up more
  298. pacifica_add_whitecaps();
  299.  
  300. // Deepen the blues and greens a bit
  301. pacifica_deepen_colors();
  302. }
  303.  
  304. // Add one layer of waves into the led array
  305. void pacifica_one_layer(CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) {
  306. uint16_t ci = cistart;
  307. uint16_t waveangle = ioff;
  308. uint16_t wavescale_half = (wavescale / 2) + 20;
  309. for (uint16_t i = 0; i < NUM_LEDS2; i++) {
  310. waveangle += 250;
  311. uint16_t s16 = sin16(waveangle) + 32768;
  312. uint16_t cs = scale16(s16, wavescale_half) + wavescale_half;
  313. ci += cs;
  314. uint16_t sindex16 = sin16(ci) + 32768;
  315. uint8_t sindex8 = scale16(sindex16, 240);
  316. CRGB c = ColorFromPalette(p, sindex8, bri, LINEARBLEND);
  317. leds2[i] += c;
  318. }
  319. }
  320.  
  321. // Add extra 'white' to areas where the four layers of light have lined up brightly
  322. void pacifica_add_whitecaps() {
  323. uint8_t basethreshold = beatsin8(9, 55, 65);
  324. uint8_t wave = beat8(7);
  325.  
  326. for (uint16_t i = 0; i < NUM_LEDS2; i++) {
  327. uint8_t threshold = scale8(sin8(wave), 20) + basethreshold;
  328. wave += 7;
  329. uint8_t l = leds2[i].getAverageLight();
  330. if (l > threshold) {
  331. uint8_t overage = l - threshold;
  332. uint8_t overage2 = qadd8(overage, overage);
  333. leds2[i] += CRGB(overage, overage2, qadd8(overage2, overage2));
  334. }
  335. }
  336. }
  337.  
  338. // Deepen the blues and greens
  339. void pacifica_deepen_colors() {
  340. for (uint16_t i = 0; i < NUM_LEDS2; i++) {
  341. leds2[i].blue = scale8(leds2[i].blue, 200);
  342. leds2[i].green = scale8(leds2[i].green, 100);
  343. leds2[i] |= CRGB(5, 0, 15);
  344. }
  345. }
  346.  
Add Comment
Please, Sign In to add comment