diff options
Diffstat (limited to 'Библиотеки/FastLED-master/power_mgt.cpp')
-rw-r--r-- | Библиотеки/FastLED-master/power_mgt.cpp | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/Библиотеки/FastLED-master/power_mgt.cpp b/Библиотеки/FastLED-master/power_mgt.cpp new file mode 100644 index 0000000..e197755 --- /dev/null +++ b/Библиотеки/FastLED-master/power_mgt.cpp @@ -0,0 +1,185 @@ +#define FASTLED_INTERNAL +#include "FastLED.h" +#include "power_mgt.h" + +FASTLED_NAMESPACE_BEGIN + +//// POWER MANAGEMENT + +// These power usage values are approximate, and your exact readings +// will be slightly (10%?) different from these. +// +// They were arrived at by actually measuing the power draw of a number +// of different LED strips, and a bunch of closed-loop-feedback testing +// to make sure that if we USE these values, we stay at or under +// the target power consumption. +// Actual power consumption is much, much more complicated and has +// to include things like voltage drop, etc., etc. +// However, this is good enough for most cases, and almost certainly better +// than no power management at all. +// +// You're welcome to adjust these values as needed; there may eventually be an API +// for changing these on the fly, but it saves codespace and RAM to have them +// be compile-time constants. + +static const uint8_t gRed_mW = 16 * 5; // 16mA @ 5v = 80mW +static const uint8_t gGreen_mW = 11 * 5; // 11mA @ 5v = 55mW +static const uint8_t gBlue_mW = 15 * 5; // 15mA @ 5v = 75mW +static const uint8_t gDark_mW = 1 * 5; // 1mA @ 5v = 5mW + +// Alternate calibration by RAtkins via pre-PSU wattage measurments; +// these are all probably about 20%-25% too high due to PSU heat losses, +// but if you're measuring wattage on the PSU input side, this may +// be a better set of calibrations. (WS2812B) +// static const uint8_t gRed_mW = 100; +// static const uint8_t gGreen_mW = 48; +// static const uint8_t gBlue_mW = 100; +// static const uint8_t gDark_mW = 12; + + +#define POWER_LED 1 +#define POWER_DEBUG_PRINT 0 + + +// Power consumed by the MCU +static const uint8_t gMCU_mW = 25 * 5; // 25mA @ 5v = 125 mW + +static uint8_t gMaxPowerIndicatorLEDPinNumber = 0; // default = Arduino onboard LED pin. set to zero to skip this. + + +uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds ) //25354 +{ + uint32_t red32 = 0, green32 = 0, blue32 = 0; + const CRGB* firstled = &(ledbuffer[0]); + uint8_t* p = (uint8_t*)(firstled); + + uint16_t count = numLeds; + + // This loop might benefit from an AVR assembly version -MEK + while( count) { + red32 += *p++; + green32 += *p++; + blue32 += *p++; + count--; + } + + red32 *= gRed_mW; + green32 *= gGreen_mW; + blue32 *= gBlue_mW; + + red32 >>= 8; + green32 >>= 8; + blue32 >>= 8; + + uint32_t total = red32 + green32 + blue32 + (gDark_mW * numLeds); + + return total; +} + + +uint8_t calculate_max_brightness_for_power_vmA(const CRGB* ledbuffer, uint16_t numLeds, uint8_t target_brightness, uint32_t max_power_V, uint32_t max_power_mA) { + return calculate_max_brightness_for_power_mW(ledbuffer, numLeds, target_brightness, max_power_V * max_power_mA); +} + +uint8_t calculate_max_brightness_for_power_mW(const CRGB* ledbuffer, uint16_t numLeds, uint8_t target_brightness, uint32_t max_power_mW) { + uint32_t total_mW = calculate_unscaled_power_mW( ledbuffer, numLeds); + + uint32_t requested_power_mW = ((uint32_t)total_mW * target_brightness) / 256; + + uint8_t recommended_brightness = target_brightness; + if(requested_power_mW > max_power_mW) { + recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW)); + } + + return recommended_brightness; +} + +// sets brightness to +// - no more than target_brightness +// - no more than max_mW milliwatts +uint8_t calculate_max_brightness_for_power_mW( uint8_t target_brightness, uint32_t max_power_mW) +{ + uint32_t total_mW = gMCU_mW; + + CLEDController *pCur = CLEDController::head(); + while(pCur) { + total_mW += calculate_unscaled_power_mW( pCur->leds(), pCur->size()); + pCur = pCur->next(); + } + +#if POWER_DEBUG_PRINT == 1 + Serial.print("power demand at full brightness mW = "); + Serial.println( total_mW); +#endif + + uint32_t requested_power_mW = ((uint32_t)total_mW * target_brightness) / 256; +#if POWER_DEBUG_PRINT == 1 + if( target_brightness != 255 ) { + Serial.print("power demand at scaled brightness mW = "); + Serial.println( requested_power_mW); + } + Serial.print("power limit mW = "); + Serial.println( max_power_mW); +#endif + + if( requested_power_mW < max_power_mW) { +#if POWER_LED > 0 + if( gMaxPowerIndicatorLEDPinNumber ) { + digitalWrite(gMaxPowerIndicatorLEDPinNumber, LOW); // turn the LED off + } +#endif +#if POWER_DEBUG_PRINT == 1 + Serial.print("demand is under the limit"); +#endif + return target_brightness; + } + + uint8_t recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW)); +#if POWER_DEBUG_PRINT == 1 + Serial.print("recommended brightness # = "); + Serial.println( recommended_brightness); + + uint32_t resultant_power_mW = (total_mW * recommended_brightness) / 256; + Serial.print("resultant power demand mW = "); + Serial.println( resultant_power_mW); + + Serial.println(); +#endif + +#if POWER_LED > 0 + if( gMaxPowerIndicatorLEDPinNumber ) { + digitalWrite( gMaxPowerIndicatorLEDPinNumber, HIGH); // turn the LED on + } +#endif + + return recommended_brightness; +} + + +void set_max_power_indicator_LED( uint8_t pinNumber) +{ + gMaxPowerIndicatorLEDPinNumber = pinNumber; +} + +void set_max_power_in_volts_and_milliamps( uint8_t volts, uint32_t milliamps) +{ + FastLED.setMaxPowerInVoltsAndMilliamps(volts, milliamps); +} + +void set_max_power_in_milliwatts( uint32_t powerInmW) +{ + FastLED.setMaxPowerInMilliWatts(powerInmW); +} + +void show_at_max_brightness_for_power() +{ + // power management usage is now in FastLED.show, no need for this function + FastLED.show(); +} + +void delay_at_max_brightness_for_power( uint16_t ms) +{ + FastLED.delay(ms); +} + +FASTLED_NAMESPACE_END |