Skip to content

Instantly share code, notes, and snippets.

@alexgorbatchev
Forked from adammhaile/FastLEDDisk.ino
Created September 8, 2017 22:50
Show Gist options
  • Select an option

  • Save alexgorbatchev/344ce8aaf7ac2cf788c19526e11644c3 to your computer and use it in GitHub Desktop.

Select an option

Save alexgorbatchev/344ce8aaf7ac2cf788c19526e11644c3 to your computer and use it in GitHub Desktop.

Revisions

  1. @adammhaile adammhaile revised this gist May 4, 2015. 1 changed file with 14 additions and 0 deletions.
    14 changes: 14 additions & 0 deletions FastLEDDisk.ino
    Original file line number Diff line number Diff line change
    @@ -128,6 +128,13 @@ void fillRing360(uint8_t ring, CRGB color, int16_t startAngle, int16_t endAngle)
    leds[i] = color;
    }
    }
    else if(start == end)
    {
    for(int i=rings[ring][0]; i<=rings[ring][1]; i++)
    {
    leds[i] = color;
    }
    }
    else
    {
    for(int i=start; i<=end; i++)
    @@ -153,6 +160,13 @@ void fillRing256(uint8_t ring, CRGB color, uint8_t startAngle, uint8_t endAngle)
    leds[i] = color;
    }
    }
    else if(start == end)
    {
    for(int i=rings[ring][0]; i<=rings[ring][1]; i++)
    {
    leds[i] = color;
    }
    }
    else
    {
    for(int i=start; i<=end; i++)
  2. @adammhaile adammhaile created this gist May 3, 2015.
    247 changes: 247 additions & 0 deletions FastLEDDisk.ino
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,247 @@
    #include "FastLED.h"

    #define NUM_LEDS 255

    #define DATA_PIN SPI_DATA
    #define CLOCK_PIN SPI_CLOCK

    // Define the array of leds
    CRGB leds[NUM_LEDS];

    #define ringCount 10 //Total Number of Rings. AdaFruit Disk has 10

    //Map rings on disk to indicies.
    //This is where all the magic happens.
    //Each represents one of the concentric rings.
    uint8_t rings[ringCount][2] = {
    {254,254}, //0 Center Point
    {248,253}, //1
    {236,247}, //2
    {216,235}, //3
    {192,215}, //4
    {164,191}, //5
    {132,163}, //6
    {92,131}, //7
    {48,91}, //8
    {0,47}, //9 Outter Ring
    };

    //For convenience, last ring index
    uint8_t lastRing = ringCount - 1;

    //Arrays containing degrees between each pixel for each ring.
    //This is to speed up later calculations by doing these ahead of time.
    //I've given everything with the option of using 360 degres per cirlce
    //or 256. The latter fits nicer into a single byte and *should* be a bit
    //faster since it's only doing single byte math and not having to deal with
    //negative angles since uint8_t already rolls around to a positive value.
    //In the 256 degree per circle methods, 64 is equivalent to 90, 128 to 180,
    //and 192 to 270
    float * ringSteps360;
    float * ringSteps256;

    //360 Degree Helper function to map angle and ring index to pixel
    uint16_t angleToPixel360(int16_t angle, uint8_t ring)
    {
    if(ring >= ringCount) return 0;
    angle = angle%360;
    if(angle < 0) angle = 360 + angle;
    return rings[ring][0] + int(angle/ringSteps360[ring]);
    }

    //256 Degree Helper function to map angle and ring index to pixel
    uint16_t angleToPixel256(uint8_t angle, uint8_t ring)
    {
    if(ring >= ringCount) return 0;
    return rings[ring][0] + int(angle/ringSteps256[ring]);
    }

    //Fill in the ringSteps arrays for later use.
    inline void setupRings()
    {
    ringSteps360 = (float*)malloc(ringCount * sizeof(float));
    uint8_t count = 0;
    for(int r=0; r<ringCount; r++)
    {
    count = (rings[r][1] - rings[r][0] + 1);
    ringSteps360[r] = (360.0/float(count));
    }

    ringSteps256 = (float*)malloc(ringCount * sizeof(float));
    count = 0;
    for(int r=0; r<ringCount; r++)
    {
    count = (rings[r][1] - rings[r][0] + 1);
    ringSteps256[r] = (256.0/float(count));
    }
    }

    //360 Degree helper to set a pixel, given angle and ring index
    void setPixel360(int16_t angle, uint8_t ring, CRGB color)
    {
    uint16_t pixel = angleToPixel360(angle, ring);
    leds[pixel] = color;
    }

    //256 Degree helper to set a pixel, given angle and ring index
    void setPixel256(uint8_t angle, uint8_t ring, CRGB color)
    {
    uint16_t pixel = angleToPixel256(angle, ring);
    leds[pixel] = color;
    }

    //360 Degree function to draw a line along a given angle from one ring to another
    void drawRadius360(int16_t angle, CRGB color, uint8_t startRing, uint8_t endRing)
    {
    if(startRing > lastRing) startRing = 0;
    if(endRing > lastRing) endRing = lastRing;
    for(uint8_t r=startRing; r<=endRing; r++)
    {
    setPixel360(angle, r, color);
    }
    }

    //256 Degree function to draw a line along a given angle from one ring to another
    void drawRadius256(uint8_t angle, CRGB color, uint8_t startRing, uint8_t endRing)
    {
    if(startRing > lastRing) startRing = 0;
    if(endRing > lastRing) endRing = lastRing;
    for(uint8_t r=startRing; r<=endRing; r++)
    {
    setPixel256(angle, r, color);
    }
    }

    //360 Degree function to fill a ring from one angle to another (draw an arc)
    void fillRing360(uint8_t ring, CRGB color, int16_t startAngle, int16_t endAngle)
    {
    uint8_t start = angleToPixel360(startAngle, ring);
    uint8_t end = angleToPixel360(endAngle, ring);
    if(start > end)
    {
    for(int i=start; i<=rings[ring][1]; i++)
    {
    leds[i] = color;
    }
    for(int i=rings[ring][0]; i<=end; i++)
    {
    leds[i] = color;
    }
    }
    else
    {
    for(int i=start; i<=end; i++)
    {
    leds[i] = color;
    }
    }
    }

    //256 Degree function to fill a ring from one angle to another (draw an arc)
    void fillRing256(uint8_t ring, CRGB color, uint8_t startAngle, uint8_t endAngle)
    {
    uint8_t start = angleToPixel256(startAngle, ring);
    uint8_t end = angleToPixel256(endAngle, ring);
    if(start > end)
    {
    for(int i=start; i<=rings[ring][1]; i++)
    {
    leds[i] = color;
    }
    for(int i=rings[ring][0]; i<=end; i++)
    {
    leds[i] = color;
    }
    }
    else
    {
    for(int i=start; i<=end; i++)
    {
    leds[i] = color;
    }
    }
    }

    void setup() {
    setupRings();

    Serial.begin(115200);
    LEDS.addLeds<APA102,DATA_PIN,CLOCK_PIN,BGR>(leds,NUM_LEDS);
    LEDS.setBrightness(64);
    }


    uint16_t pixel = 0;
    uint8_t angle256 = 0;
    void loop() {

    //Chase a single pixel around the outer ring
    for(int angle360 = 0; angle360 < 360; angle360++)
    {
    FastLED.clear();
    setPixel360(angle360, lastRing, CRGB::Red);
    FastLED.show();
    }

    //Chase a single pixel around the outer ring using 256 degrees per circle.
    //Note that this will appear faster because there are less steps in the circle.
    angle256 = 0;
    while(true)
    {
    FastLED.clear();
    setPixel256(angle256, lastRing, CRGB::Green);
    FastLED.show();
    angle256++;
    if(angle256 == 0) break;
    }

    //Chase radius line using 360 degrees per circle
    for(int angle360 = 0; angle360 < 360; angle360++)
    {
    FastLED.clear();
    drawRadius360(angle360, CRGB::Blue, 0, lastRing);
    FastLED.show();
    }

    //Chase radius line using 256 degrees per circle
    angle256 = 0;
    while(true)
    {
    FastLED.clear();
    drawRadius256(angle256, CRGB::Purple, 0, lastRing);
    FastLED.show();
    angle256++;
    if(angle256 == 0) break;
    }

    //Draw a half circle (180 degree) rainbow using 360 degrees per circle
    for(int angle360 = 0; angle360 < 360; angle360++)
    {
    FastLED.clear();
    fillRing360(9, CRGB::Red, angle360 - 90, angle360 + 90);
    fillRing360(8, CRGB::Orange, angle360 - 90, angle360 + 90);
    fillRing360(7, CRGB::Yellow, angle360 - 90, angle360 + 90);
    fillRing360(6, CRGB::Green, angle360 - 90, angle360 + 90);
    fillRing360(5, CRGB::Blue, angle360 - 90, angle360 + 90);
    fillRing360(4, CRGB::Purple, angle360 - 90, angle360 + 90);
    FastLED.show();
    }

    //Draw a half circle (128 degree) rainbow using 256 degrees per circle
    angle256 = 0;
    while(true)
    {
    FastLED.clear();
    fillRing256(9, CRGB::Purple, angle256 - 64, angle256 + 64);
    fillRing256(8, CRGB::Blue, angle256 - 64, angle256 + 64);
    fillRing256(7, CRGB::Green, angle256 - 64, angle256 + 64);
    fillRing256(6, CRGB::Yellow, angle256 - 64, angle256 + 64);
    fillRing256(5, CRGB::Orange, angle256 - 64, angle256 + 64);
    fillRing256(4, CRGB::Red, angle256 - 64, angle256 + 64);
    FastLED.show();
    angle256++;
    if(angle256 == 0) break;
    }
    }