/* Plasma * * By: Andrew Tuline * * Date: July, 2017 * * This demonstrates 2D sinusoids in 1D using 16 bit math. * * It runs at about 450 fps on an Arduino Nano with 60 APA102's. That would be FAST. * * * References: * * https://www.bidouille.org/prog/plasma * http://lodev.org/cgtutor/plasma.html * */ // Use qsuba for smooth pixel colouring and qsubd for non-smooth pixel colouring #define qsubd(x, b) ((x>b)?b:0) // Digital unsigned subtraction macro. if result <0, then => 0. Otherwise, take on fixed value. #define qsuba(x, b) ((x>b)?x-b:0) // Analog Unsigned subtraction macro. if result <0, then => 0 #include "FastLED.h" // FastLED library. Preferably the latest copy of FastLED 2.1. #if FASTLED_VERSION < 3001000 #error "Requires FastLED 3.1 or later; check github for latest code." #endif // Fixed definitions cannot change on the fly. #define LED_DT 12 // Serial data pin for WS2812 or WS2801. #define LED_CK 11 // Serial clock pin for WS2801 or APA102. #define COLOR_ORDER BGR // Are they GRB for WS2812 and GBR for APA102 #define LED_TYPE APA102 // What kind of strip are you using? WS2812, APA102. . . #define NUM_LEDS 60 // Number of LED's. uint8_t max_bright = 255; // Overall brightness definition. It can be changed on the fly. struct CRGB leds[NUM_LEDS]; // Initialize our LED array. CRGBPalette16 currentPalette; // Palette definitions CRGBPalette16 targetPalette; TBlendType currentBlending = LINEARBLEND; void setup() { Serial.begin(57600); // Initialize serial port for debugging. delay(1000); // Soft startup to ease the flow of electrons. LEDS.addLeds(leds, NUM_LEDS); //WS2801 and APA102 // LEDS.addLeds(leds, NUM_LEDS); // WS2812 FastLED.setBrightness(max_bright); set_max_power_in_volts_and_milliamps(5, 500); // FastLED Power management set at 5V, 500mA. currentPalette = OceanColors_p; } // setup() void loop () { EVERY_N_MILLISECONDS(50) { // FastLED based non-blocking delay to update/display the sequence. plasma(); } EVERY_N_MILLISECONDS(1000) { Serial.println(LEDS.getFPS()); // Optional check of our fps. } EVERY_N_MILLISECONDS(100) { uint8_t maxChanges = 24; nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); // AWESOME palette blending capability. } EVERY_N_SECONDS(5) { // Change the target palette to a random one every 5 seconds. uint8_t baseC = random8(); // You can use this as a baseline colour if you want similar hues in the next line. targetPalette = CRGBPalette16(CHSV(baseC+random8(32), 192, random8(128,255)), CHSV(baseC+random8(32), 255, random8(128,255)), CHSV(baseC+random8(32), 192, random8(128,255)), CHSV(baseC+random8(32), 255, random8(128,255))); } FastLED.show(); } // loop() void plasma() { // This is the heart of this program. Sure is short. . . and fast. int thisPhase = beatsin8(6,-64,64); // Setting phase change for a couple of waves. int thatPhase = beatsin8(7,-64,64); for (int k=0; k