Skip to content

Allow control of more than one on-board pixel via led commands #245

@henrygab

Description

@henrygab

Worst case power draw from Pixels

_(A pixel is the hardware unit, which contains three leds ... one red, one green, one blue. Avoids ambiguity between per-pixel vs. per-LED values)_

Note that these calculations are all estimates. For original WS2812 5050 pixels, a rule of thumb was 60mA current per pixel. The BusPirate 5, for example, uses SK6812 ... where the last two digits indicate 12mA per led, with ~1mA overhead (idle power draw) per pixel, giving maximum power draw per pixel of ~38mA. I'll show values for both below.

The buspirate system configuration settings only support three LED brightness scales:

  • 1/3 brightness
  • 1/5 brightness
  • 1/10 brightness

Thus, for worst case / highest power draw calculations, we'll consider 1/3 brightness. The brightness reduction in the buspirate code is a linear reduction ... which is to say, no gamma is applied anywhere in the current buspirate code. Therefore, the maximum value for R, G, and B is 255 / 3 == 81.

Pixel Type Per-Pixel mA Pixel Count Max Brightness approx max mA Notes
WS2812 5050 60 18 255 1080 No reduction
WS2812 5050 60 18 81 ~344 1/3 brightness
WS2812 5050 60 18 51 ~216 1/5 brightness
WS2812 5050 60 18 25 ~106 1/10 brightness
SK6812 38 18 255 684 No reduction
SK6812 38 18 81 ~218 1/3 brightness BP5 Target
SK6812 38 18 51 ~137 1/5 brightness
SK6812 38 18 25 ~67 1/10 brightness

Even at the maximum 1/3 brightness configuration, all pixels at 100% white would still leave > 150mA (> 280mA) for the rest of the system.

I encourage setting to 1/5 or 1/10 brightness in the settings ... reduces the power fluctuations, even if your eyes don't hurt from the brightness at the default 1/3 power. ;-)


Based on the above calculations, I think it'd be safe to allow updates to more than one onboard pixel, so long as the total current is below a pre-selected threshold.


Pseudo-code

bool estimated_to_exceed_power_limit(CPIXEL_COLOR* buffer, const size_t buffer_count) {
    bool result = true; // exceeds result unless calculations will show otherwise

    static const uint8_t LEDS_PER_PIXEL = 3u; // implied by CPIXEL_COLOR structure
    static const uint8_t MAX_DRAW_PER_LED_mA = 12u; // SK6812 may be adjusted to 12mA after confirmation
    static const uint8_t MAX_DRAW_PER_PIXEL_mA = LEDS_PER_PIXEL * MAX_DRAW_PER_LED_mA;
    static const uint8_t IDLE_DRAW_PER_PIXEL_mA = 2u; // SK6812 datasheet lists 1mA, real-world suggests 2mA
    static const uint8_t OVERALL_MARGIN_mA = 20u; // safety margin, slop, manufacturing tolerances, etc.
    static const uint32_t SYSTEM_POWER_BUDGET_mA = 500u - 150u; // USB 500mA; 150mA by non-plank items?

    uint16_t PLANK_OUTPUT_LIMIT_mA = 0; // NOTE: should be updated via events from `W` and `w`

    // TODO: avoid overflow in subtractions (if (X - Y > X) then underflow occurred...)
    uint32_t pixel_power_budget_mA = SYSTEM_POWER_BUDGET_mA -  PLANK_OUTPUT_LIMIT_mA;
    pixel_power_budget -= OVERALL_MARGIN_mA;
    pixel_power_budget -= (IDLE_DRAW_PER_PIXEL_mA * COUNT_OF_PIXELS);

    uint32_t color_data_sum = 0; // simple sum works for SK6812
    for (uint_fast8_t i = 0; i < buffer_count; ++i) {
        color_data_sum += buffer[i].r;
        color_data_sum += buffer[i].g;
        color_data_sum += buffer[i].b;
    }
    if ((UINT32_MAX / MAX_DRAW_PER_LED) >= color_data_sum) {
        // no overflow when multiplying ... can continue
        uint32_t estimated_power_draw = (color_data_sum * MAX_DRAW_PER_LED) / 255;
        if (estimated_power_draw < pixel_power_budget_mA) {
            result = false;  // Estimated to be within power budget
        }
    }
    // todo: logging when result is true (exceeding budget)
    return result;
}
// todo: automatic brightness limiter ... automatically reduce values to fit the current limit

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpixelsrelated to onboard SK6812 pixels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions