Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kriegsman <kriegsman@tr.org>2014-08-05 22:16:00 +0400
committerMark Kriegsman <kriegsman@tr.org>2014-08-05 22:16:00 +0400
commit4a21223dc36253f7e798bd6ed9036e46edd1ad6f (patch)
tree20ae24034caba22ca51f4e4004c44eb6b1f42d9d /power_mgt.cpp
parent76840c0dfb92a8ce783abb87fbfe565f9dda26c5 (diff)
Adding power management code, with global interfaces ONLY at this point.
Diffstat (limited to 'power_mgt.cpp')
-rw-r--r--power_mgt.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/power_mgt.cpp b/power_mgt.cpp
new file mode 100644
index 00000000..edfb568d
--- /dev/null
+++ b/power_mgt.cpp
@@ -0,0 +1,144 @@
+#include "FastLED.h"
+#include "power_mgt.h"
+
+//// POWER MANAGEMENT
+
+// These power usage values 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
+static const uint8_t gGreen_mW = 14 * 5; // 14mA @ 5v
+static const uint8_t gBlue_mW = 14 * 5; // 14mA @ 5v
+static const uint8_t gDark_mW = 1 * 5; // 1mA @ 5v
+
+// Power consumed by the MCU
+static const uint8_t gMCU_mW = 25 * 5; // 25mA @ 5v
+
+
+uint32_t gMaxPowerInMilliwatts = (uint32_t)(400) * (uint32_t)(5); // 400mA @ 5v default to avoid USB bricking
+uint8_t gMaxPowerIndicatorLEDPinNumber = 13; // default = Arduino onboard LED pin. set to zero to skip this.
+
+
+
+uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds )
+{
+ uint32_t red32 = 0, green32 = 0, blue32 = 0;
+ const CRGB* firstled = &(ledbuffer[0]);
+ uint8_t* p = (uint8_t*)(firstled);
+
+ uint16_t count = numLeds;
+
+ for( byte loop256 = (count >> 8) + 1; loop256; loop256--) {
+ uint16_t red16 = 0, green16 = 0, blue16 = 0;
+ while( count) {
+ red16 += *p++;
+ green16 += *p++;
+ blue16 += *p++;
+ count--;
+ }
+ red32 += red16;
+ green32 += green16;
+ blue32 += blue16;
+ }
+
+ 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;
+}
+
+
+
+#define POWER_LED 1
+
+// 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();
+ }
+
+ uint32_t requested_power_mW = ((uint32_t)total_mW * target_brightness) / 256;
+ //Serial.print("requested scaled power mW = ");
+ //Serial.println( requested_power_mW);
+ //Serial.print("max power mW = ");
+ //Serial.println( max_power_mW);
+
+ if( requested_power_mW < max_power_mW) {
+#if POWER_LED > 0
+ if( gMaxPowerIndicatorLEDPinNumber ) {
+ digitalWrite(gMaxPowerIndicatorLEDPinNumber, LOW); // turn the LED off
+ }
+#endif
+ return target_brightness;
+ }
+
+ uint8_t recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW));
+ //Serial.print("recommended brightness = ");
+ //Serial.println( recommended_brightness);
+#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)
+{
+ gMaxPowerInMilliwatts = (uint32_t)((uint32_t)(volts) * milliamps);
+}
+
+void set_max_power_in_milliwatts( uint32_t powerInmW)
+{
+ gMaxPowerInMilliwatts = powerInmW;
+}
+
+void show_at_max_brightness_for_power()
+{
+ uint8_t targetBrightness = FastLED.getBrightness();
+ uint8_t max = calculate_max_brightness_for_power_mW( targetBrightness, gMaxPowerInMilliwatts);
+
+ FastLED.setBrightness( max );
+ FastLED.show();
+ FastLED.setBrightness( targetBrightness );
+}
+
+void delay_at_max_brightness_for_power( uint16_t ms)
+{
+ uint8_t targetBrightness = FastLED.getBrightness();
+ uint8_t max = calculate_max_brightness_for_power_mW( targetBrightness, gMaxPowerInMilliwatts);
+
+ FastLED.setBrightness( max );
+ FastLED.delay( ms);
+ FastLED.setBrightness( targetBrightness );
+}
+