Segment Drawing Functions - AlbertGBarber/PixelSpork GitHub Wiki

Jump to a specific set of namespace functions:

Intro:

Pixel Spork uses Segment Sets to virtually arrange LEDs, which creates a layer of abstraction between what LED you're writing to, and what the physical address of the LED actually is. For example, I may want to write to the 5th LED in a Segment Set, but due the arrangement of the Segment Set, the 5th LED is actually the 10th physical LED. To translate between the virtual Segment LEDs and their physical counterparts, I've written a suite of helper functions listed below. These functions are stored under the segDrawUtils namespace.

An example of using the namespace to call the turnSegSetOff() function:

segDrawUtils::turnSegSetOff( mySegmentSet );

The namespace includes a variety of functions including those to: find the physical address of a Segment Set LED, fill lengths of a Segment Set with color, set the color of a specific LED (taking into account a Color Modes), draw Segment Lines, and more.

In general, you probably won't need to use these functions unless you're writing your own effects.

You can also find these functions in "segDrawUtils.h" and "segDrawUtils.cpp".

Common Arguments:

Function inputs distinguish between pixel locations local to the segment, segment set, and the pixel's physical address by using segSetPixelNum, segPixelNum, or pixelNum as argument names. Note that counting starts from 0 for all cases!!

  • segSetPixelNum (uint16_t) is the location local to the segment set. ex: The 25th pixel in the segment set, its segSetPixelNum is 25.

  • segPixelNum (uint16_t) is the location local to the segment. ex: Its the 5th pixel in the segment, its segPixelNum is 5.

  • pixelNum (uint16_t) is the physical address of the led. ex: The 25th pixel in the segment set has a physical address of 10 so its pixelNum is 10.

For an overall example, consider a Segment Set with 10 LEDs split into two segments, laid out like ( { 0, 1, 2, 3, 4 } , { 9, 8, 7, 6, 5 } ) where the each {} pair represents a segment with the LEDs addresses within. Lets say we want the address of LED #6 in the overall Segment Set, so the segSetPixelNum is 6. This LED is the first LED in the second segment, so its segPixelNum is 0, while its address, pixelNum, is 9.

Some other common arguments:

  • SegmentSetPS SegSet -- The address of the Segment Set you're using.

  • uint16_t segNum -- The number of a Segment in your Segment Set, ie the "1st" Segment.

  • uint8_t secNum -- The number of a section in a Segment in your Segment Set.

  • uint16_t lineNum -- A line number in a Segment Set, ie the "5th" line in a set.

  • uint8_t colorMode -- The Color Mode you're using (leave as 0 if not using a Color Mode).

  • CRGB color -- Usually the intended color of a pixel (may be overwritten by a Color Mode).

  • uint16_t locData[2] -- An array containing { segment number, pixel number in segment }. It is used for passing around a pixel's location data. Usually passed to a function that then fills in the array.

Correctly Calculating Color Modes:

The end goal of any effect is to call setPixelColor( SegSet, pixelNum, color, colorMode, segNum, lineNum ), which is the main function for setting the color of a pixel. Note that the function includes a color, but also a Color Mode. If the color mode is non-zero, the function will over-write the color, replacing it with a color mode output calculated using the extra vars, segNum, and lineNum. All the namespace's drawing functions take color modes into account. There are various functions for finding the pixelNum, segNum and lineNum for any given Segment Set pixel.

While most of the color mode calculation variables are input arguments, there are some that are more easily calculated along-side various drawing effects. These values are stored in the namespace using static variables (listed below), so they are preserved between function calls. The idea is that you call a drawing function for finding a pixel's location (or some other aspect), which in turn sets the static values, allowing you to call setPixelColor() above with all the correct color mode settings calculated. However, since almost all the drawing functions set theses static values (with exceptions listed below), they will overwrite any values for any previously set pixels. Therefore, it's critical that once you have found a pixel's address or local location, you set its color before calling any other drawing functions. Note that any drawing functions that set or return pixel colors (except the "final" setPixelColor() above) automatically do the color mode calculations while setting/getting colors, so you don't need to worry about them.

Overall, this may sound complicated, but in practice it's not really something you need to think about. Ultimately it only prevents you from storing a bunch of pixel addresses; you have to get and set a pixel in one motion. When writing effects you'll probably do this naturally, and if you need any examples, you can always study the existing effects.

Static variables used for Color Mode calculations:

  • uint16_t pixelCount -- A pixel's location, local to the whole segment set, ie the same as segSetPixleNum above. Used for calculating color modes 1 & 6.

Functions that don't set the static Color Mode vars (safe to call whenever):

  • setPixelColor(SegSet, pixelNum, color, colorMode, segNum, lineNum) -- The "final" pixel drawing function, uses the color mode variables, and assumes they have already been calculated.

  • getPixelColor(SegSet, pixelNum, color, colorMode, segNum, lineNum) -- Like setPixelColor above, but returns the color of the pixel based on the pixel's physical address, accounting for color modes. Assumes that all color mode vars have already been calculated.

  • turnSegSetOff(SegSet) -- Doesn't interact with color modes.

  • getLineNumFromPixelNum(SegSet, segPixelNum, segNum) -- Returns a line number, but doesn't need to fetch a pixel number to do so, so it doesn't set any color mode vars.

  • handleBri(SegSet, pixelNum) -- Doesn't interact with color modes.

  • show(SegSet, showNow) -- Doesn't interact with color modes.

  • setGradOffset(SegSet, offsetMax) -- Doesn't interact with color modes.

  • All the "fade to black by" functions.

The Namespace Functions:

Functions for Filling Some or all of a Segment Set:

These functions fill different parts of the Segment Set with solid colors. There's a function for each level of a Segment Set, so one function fills in a whole Set, while another fills in a single Section. There are also functions for filling fixed lengths of Segment Sets.

  • void turnSegSetOff( SegmentSeg &SegSet ); 
    

    Sets a Segment Set's color to black (turns off the LEDs). Doesn't interact with static color mode vars, see Calculating Color Modes above.

  • void fillSegSetColor( SegmentSetPS &SegSet, const CRGB &color, uint8_t colorMode );
    

    Sets a whole Segment Set to a single color.

  • uint16_t fillSegSetLengthColor( SegmentSetPS &SegSet, uint16_t startSegPixel, uint16_t endPixel, 
                                    const CRGB &color, uint8_t colorMode ); 
    

    Sets part of a Segment Set to a single color. startSegPixel and endPixel mark the local starting and ending pixel numbers.

  • uint16_t fillSegColor( SegmentSetPS &SegSet, uint16_t segNum, const CRGB &color, uint8_t colorMode );
    

    Sets a single Segment in a Set to a single color.

  • uint16_t fillSegSecColor( SegmentSetPS &SegSet, uint16_t segNum, uint8_t secNum, uint16_t lengthSoFar, 
                              const CRGB &color, uint8_t colorMode );
    

    Sets a single Section of a Segment to a single color. Note that lengthSoFar is the number of pixels in the segment up to the section we want to fill (secNum). We need this to get the correct address of the section's pixels.

    When calling this function for a single section you can calculate lengthSoFar like:

    uint16_t lengthSoFar = 0;
    for(uint8_t i = 0; i < secNum; i++){
        lengthSoFar += SegSet.getSecLength(segNum, i);
    } 
    

    Where secNum is the section you want to color.

  • uint16_t fillSegLengthColor( SegmentSetPS &SegSet, uint16_t segNum, uint16_t startSegPixel, uint16_t endPixel, 
                                 const CRGB &color, uint8_t colorMode );
    

    Sets part of a Segment in a Set to be a single color. startSegPixel and endPixel mark the local starting and ending pixel numbers to that Segment.

Functions for Drawing Segment Lines:

These functions draw Segment Lines on the Segment Set, taking into account Color Modes. Remember that the total number of Segment Lines is always equal to the length of the longest segment. Each line is the "straightest" path through all segments for a given LED number. See Segment Basics for more.

  • void drawSegLine(SegmentSetPS &SegSet, uint16_t lineNum, const CRGB &color, uint8_t colorMode);
    

    Draws a single color segment line.

  • void drawSegLineSection(SegmentSetPS &SegSet, uint16_t startSeg, uint16_t endSeg, uint16_t lineNum, 
                            const CRGB &color, uint8_t colorMode);
    

    Draws a section of a segment line between the startSeg and endSeg segment numbers (includes the endSeg).

Functions for Finding the Physical Address of an LED (differing levels of knowledge about its local location):

Because Pixel Spork uses Segment Sets to virtually arrange LEDs, we need translation functions to go from an LED's virtual position to its physical address. The functions below handle these translations for different levels of knowledge about where your LED is in the Segment Set. In general, more knowledge means faster execution. Note that these functions all return the LEDs physical address, not local to the Segment Set!

  • uint16_t getSegmentPixel( SegmentSetPS &SegSet, uint16_t segSetPixelNum );
    

    Returns the address of an LED using only its local position in the Segment Set.

  • uint16_t getSegmentPixel( SegmentSetPS &SegSet, uint16_t segNum, uint16_t segPixelNum );
    

    Returns the address of an LED using its local position in a Segment.

  • uint16_t getPixelNumFromLineNum( SegmentSetPS &SegSet, uint16_t segNum, uint16_t lineNum );
    

    Returns the address of an LED based on its line number and what segment it's in. Remember that Segment Lines are "straight" lines between Segments. Then number of lines is always equal to the length of the longest Segment. This function maps a Segment's LED into the closest line. This means that, for shorter Segments, their LEDs will be in multiple lines. See Segment Basics for more.

Functions for Finding What Segment or Line Number a Pixel is on:

Often when trying to color an LED, you'll know some info about where it is, but may need a more complete picture to properly draw it. Say you know where the pixel is in the overall Segment Set, but need to know what Segment it's in. These functions help fill in the missing bits of info.

  • void getSegLocationFromPixel(SegmentSetPS &SegSet, uint16_t segSetPixelNum, uint16_t *locData); //locData is length 2!!
    

    Finds what Segment a pixel is on and its position local to the Segment. The data is stored in a locData array, whose address is passed in as an argument. segSetPixelNum is the pixel's location local to the overall Segment Set. For example, I want to find what Segment the 10th pixel in my Segment Set is in. I pass in 9 (counting from 0!) as segSetPixelNum and a uint16_t locData[2] array. The function fills in the array; the first index is set to the pixel's Segment number (let's say 2 for example), and the second index is set to the Pixel's location within the Segment (let's say its the 5th pixel). I would get a locData that is {2, 5}. If segSetPixelNum is not in the Segment Set, the array will be set to {0, D_LED_PS}, which will prevent the pixel from being drawn, but allow the program to continue to run.

  • uint16_t getLineNumFromPixelNum(SegmentSetPS &SegSet, uint16_t segSetPixelNum);
    

    Returns the Segment Line number a pixel is on based only on its local location within the overall Segment Set.

  • uint16_t getLineNumFromPixelNum(SegmentSetPS &SegSet, uint16_t segPixelNum, uint16_t segNum);
    

    Returns the Segment Line number a pixel is on based on what Segment it's in and its position local to the Segment. Should execute faster than the previous function. Doesn't interact with static color mode vars, see Calculating Color Modes above.

Functions for Setting the Color of a Pixel (for differing levels of knowledge about its local location):

These functions are used to set a pixel's color, including handling Color Modes. They are all different variations of the same function, because you can have different levels of knowledge about where a pixel is. In general, knowing more leads to faster execution.

  • void setPixelColor(SegmentSetPS &SegSet, uint16_t segSetPixelNum, const CRGB &color, uint8_t colorMode);
    

    Sets the color of a pixel, segPixelNum is the pixel's location relative to the entire Segment Set. ex, "the 5th pixel in the Segment Set".

  • void setPixelColor(SegmentSetPS &SegSet, uint16_t segPixelNum, const CRGB &color, 
                       uint8_t colorMode, uint16_t segNum);
    

    Sets the color of a pixel, knowing both what Segment it's in (segNum), and its location in the Segment (segPixelNum). ex, "the 5th pixel in the 2nd Segment."

  • void setPixelColor(SegmentSetPS &SegSet, uint16_t pixelNum, const CRGB &color, 
                       uint8_t colorMode, uint16_t segNum, uint16_t lineNum); 
    

    Sets the color of a pixel, knowing what Segment it's in (segNum), its address (pixelNum), and its line number (lineNum). segNum and lineNum are used for handling Color Modes. Note that pixelNum is the physical address of the LED, not it's location local to the Segment Set! Note that when not using a color mode, you can set colorMode, segNum, and lineNum to 0, as they are not used.

    This is the "final" color setting function that you'll probably use most often, and is used by most other drawing functions. Note that it assumes you have correctly set any static color mode vars, see Calculating Color Modes above.

Functions for Determining the Color of Pixel, Accounting for Color Modes:

The output color of a pixel can be changed by different Color Modes, replacing what color the effect sets it to. Sometimes you need to know what color a pixel is going to be as part of an effect (like if you're blending colors for example). Note that a color is required as an input for all these functions, this is the pixel's color before being replaced by a Color Mode. Ie if an effect wants to set the pixel to CRGB::Red, you'd pass in CRGB::Red as the color. If the Color Mode is 0, the original pixel color, color, will be returned as is.

  • void getPixelColor(SegmentSetPS &SegSet, uint16_t segSetPixelNum, pixelInfoPS *pixelInfo, 
                       const CRGB &color, uint8_t colorMode);
    

    Gets the color a pixel will be when drawn and its location data using the pixel's location local to the whole Segment Set. The data is stored in pixelInfo, which is a struct you provide to the function. Generally, when getting a pixel's color, you also want to know its address, Segment number etc. This function servers as a shortcut to get all the data using pixelInfo.

    pixelInfo's data members are:

    • CRGB color -- The color the pixel should be, accounting for Color Modes.
    • CRGB pixelLoc -- The pixel's physical address on the strip.
    • CRGB segNum -- The number of the segment the pixel is in.
    • CRGB lineNum -- The line number the pixel is a member of in the segment set.

    See pixelInfo.h in code for the struct details.

  • CRGB getPixelColor(SegmentSetPS &SegSet, uint16_t pixelNum, const CRGB &color, uint8_t colorMode, 
                       uint16_t segNum, uint16_t lineNum);
    

    Returns the color a pixel will be when drawn using its physical address, pixelNum, what Segment it's in, and its Line Number. Note that when not using a color mode, you can set colorMode, segNum, and lineNum to 0, as they are not used.

    This is a "final" color getting function that you'll probably use most often, particularly when blending colors. Note that it assumes you have correctly set any static color mode vars, see Calculating Color Modes above.

Functions for Getting/Setting Pixel Colors, Treating the Segment Set as a Matrix:

These functions set/get pixel colors, treating the segment set as matrix with dimensions numLines X numSegs. So your "x" input is a line number (lineNum), and your "y" input is a segment number (segNum). They should be particularly handy in adapting existing matrix-based effects to Pixel Spork.

  • void setPixelColor_XY(SegmentSetPS &SegSet, uint16_t lineNum, uint16_t segNum, 
                          const CRGB &color, uint8_t colorMode);
    

    Sets the pixel color at (lineNum, segNum), treating the segment set as matrix. Your "x" is lineNum and "y" is segNum.

  • CRGB getPixelColor_XY(SegmentSetPS &SegSet, uint16_t lineNum, uint16_t segNum, 
                          const CRGB &color, uint8_t colorMode);
    

    Returns the pixel color at (lineNum, segNum) (accounting for Color Modes), treating the segment set as matrix. Your "x" is lineNum and "y" is segNum. The input color will be returned unchanged if the Color Mode is 0.

Functions Used When "Showing" Pixels:

These functions deal directly with drawing pixels. None of these functions interact with static color mode vars, see Calculating Color Modes above.

  • void show(SegmentSetPS &SegSet, bool showNow);
    

    Writes out the pixel color data to your strip. It is the Pixel Strip equivalent of FastLED's show(). It also handles coloring Single Sections, hence the Segment Set argument. If showNow is false, the function will not write data to the strip. It is used to help handle multiple simultaneous effects, as explained here.

  • void handleBri(SegmentSetPS &SegSet, uint16_t pixelNum)
    

    Fades an individual pixel to match the brightness of the segment set. This is automatically called by the other color setting functions in segDrawUtils, but you must call it manually if you ever set a pixel's color manually. EX, you do SegSet.leds[5] = CRGB::Red. You must then call handleBri( SegSet, 5 ) to dim the LED. Note that FastLED doesn't track each pixel's brightness directly, so calling this twice on the same pixel will fade it twice. Therefore make sure you only call this once after you set a pixel's color. For more on brightness, see Advanced Segment Usage.

Functions for Dimming the Segment Set, or Parts of it:

These functions all fade various parts of a Segment Set towards black by a certain percentage. The percentage is out of 255, with 255 being fully black; so 127 is ~50% faded. Note that these functions use FastLED's fadeSegToBlackBy functions, and only fade the LED colors once. They do not set a general brightness. To do so you can either set a Segment Set's brightness directly, see Advanced Segment Usage, or set a global brightness using FastLED.setBrightness(uint8_t brightness).

Note that none of these functions interact with static color mode vars, see Calculating Color Modes above.

  • void fadeSegSetToBlackBy(SegmentSetPS &SegSet, uint8_t val)
    

    Fades an entire Segment Set towards black by a certain percentage.

  • void fadeSegToBlackBy(SegmentSetPS &SegSet, uint16_t segNum, uint8_t val)
    

    Fades a single segment towards black by a certain percentage.

  • void fadeSegSecToBlackBy(SegmentSetPS &SegSet, uint16_t segNum, uint8_t secNum, uint8_t val);
    

    Fades a single Section of a Segment towards black by a certain percentage.

Misc Functions:

  • void setGradOffset(SegmentSetPS &SegSet, uint16_t offsetMax);
    

    Increments/decrements a Segment Set's gradOffset to shift a Color Mode over time (if configured to do so). gradOffset wraps at offsetMax. This is automatically called by the setPixelColor() functions above, so you shouldn't ever need to touch it. For more on shifting Color Modes, see Color Modes.

    Doesn't interact with static color mode vars, see Calculating Color Modes above.