FastLED  3.1
power_mgt.cpp
1 #define FASTLED_INTERNAL
2 #include "FastLED.h"
3 #include "power_mgt.h"
4 
5 FASTLED_NAMESPACE_BEGIN
6 
8 
9 // These power usage values are approximate, and your exact readings
10 // will be slightly (10%?) different from these.
11 //
12 // They were arrived at by actually measuing the power draw of a number
13 // of different LED strips, and a bunch of closed-loop-feedback testing
14 // to make sure that if we USE these values, we stay at or under
15 // the target power consumption.
16 // Actual power consumption is much, much more complicated and has
17 // to include things like voltage drop, etc., etc.
18 // However, this is good enough for most cases, and almost certainly better
19 // than no power management at all.
20 //
21 // You're welcome to adjust these values as needed; there may eventually be an API
22 // for changing these on the fly, but it saves codespace and RAM to have them
23 // be compile-time constants.
24 
25 static const uint8_t gRed_mW = 16 * 5; // 16mA @ 5v = 80mW
26 static const uint8_t gGreen_mW = 11 * 5; // 11mA @ 5v = 55mW
27 static const uint8_t gBlue_mW = 15 * 5; // 15mA @ 5v = 75mW
28 static const uint8_t gDark_mW = 1 * 5; // 1mA @ 5v = 5mW
29 
30 // Alternate calibration by RAtkins via pre-PSU wattage measurments;
31 // these are all probably about 20%-25% too high due to PSU heat losses,
32 // but if you're measuring wattage on the PSU input side, this may
33 // be a better set of calibrations. (WS2812B)
34 // static const uint8_t gRed_mW = 100;
35 // static const uint8_t gGreen_mW = 48;
36 // static const uint8_t gBlue_mW = 100;
37 // static const uint8_t gDark_mW = 12;
38 
39 
40 #define POWER_LED 1
41 #define POWER_DEBUG_PRINT 0
42 
43 
44 // Power consumed by the MCU
45 static const uint8_t gMCU_mW = 25 * 5; // 25mA @ 5v = 125 mW
46 
47 static uint8_t gMaxPowerIndicatorLEDPinNumber = 0; // default = Arduino onboard LED pin. set to zero to skip this.
48 
49 
50 uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds ) //25354
51 {
52  uint32_t red32 = 0, green32 = 0, blue32 = 0;
53  const CRGB* firstled = &(ledbuffer[0]);
54  uint8_t* p = (uint8_t*)(firstled);
55 
56  uint16_t count = numLeds;
57 
58  // This loop might benefit from an AVR assembly version -MEK
59  while( count) {
60  red32 += *p++;
61  green32 += *p++;
62  blue32 += *p++;
63  count--;
64  }
65 
66  red32 *= gRed_mW;
67  green32 *= gGreen_mW;
68  blue32 *= gBlue_mW;
69 
70  red32 >>= 8;
71  green32 >>= 8;
72  blue32 >>= 8;
73 
74  uint32_t total = red32 + green32 + blue32 + (gDark_mW * numLeds);
75 
76  return total;
77 }
78 
79 
80 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) {
81  return calculate_max_brightness_for_power_mW(ledbuffer, numLeds, target_brightness, max_power_V * max_power_mA);
82 }
83 
84 uint8_t calculate_max_brightness_for_power_mW(const CRGB* ledbuffer, uint16_t numLeds, uint8_t target_brightness, uint32_t max_power_mW) {
85  uint32_t total_mW = calculate_unscaled_power_mW( ledbuffer, numLeds);
86 
87  uint32_t requested_power_mW = ((uint32_t)total_mW * target_brightness) / 256;
88 
89  uint8_t recommended_brightness = target_brightness;
90  if(requested_power_mW > max_power_mW) {
91  recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW));
92  }
93 
94  return recommended_brightness;
95 }
96 
97 // sets brightness to
98 // - no more than target_brightness
99 // - no more than max_mW milliwatts
100 uint8_t calculate_max_brightness_for_power_mW( uint8_t target_brightness, uint32_t max_power_mW)
101 {
102  uint32_t total_mW = gMCU_mW;
103 
105  while(pCur) {
106  total_mW += calculate_unscaled_power_mW( pCur->leds(), pCur->size());
107  pCur = pCur->next();
108  }
109 
110 #if POWER_DEBUG_PRINT == 1
111  Serial.print("power demand at full brightness mW = ");
112  Serial.println( total_mW);
113 #endif
114 
115  uint32_t requested_power_mW = ((uint32_t)total_mW * target_brightness) / 256;
116 #if POWER_DEBUG_PRINT == 1
117  if( target_brightness != 255 ) {
118  Serial.print("power demand at scaled brightness mW = ");
119  Serial.println( requested_power_mW);
120  }
121  Serial.print("power limit mW = ");
122  Serial.println( max_power_mW);
123 #endif
124 
125  if( requested_power_mW < max_power_mW) {
126 #if POWER_LED > 0
127  if( gMaxPowerIndicatorLEDPinNumber ) {
128  digitalWrite(gMaxPowerIndicatorLEDPinNumber, LOW); // turn the LED off
129  }
130 #endif
131 #if POWER_DEBUG_PRINT == 1
132  Serial.print("demand is under the limit");
133 #endif
134  return target_brightness;
135  }
136 
137  uint8_t recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW));
138 #if POWER_DEBUG_PRINT == 1
139  Serial.print("recommended brightness # = ");
140  Serial.println( recommended_brightness);
141 
142  uint32_t resultant_power_mW = (total_mW * recommended_brightness) / 256;
143  Serial.print("resultant power demand mW = ");
144  Serial.println( resultant_power_mW);
145 
146  Serial.println();
147 #endif
148 
149 #if POWER_LED > 0
150  if( gMaxPowerIndicatorLEDPinNumber ) {
151  digitalWrite( gMaxPowerIndicatorLEDPinNumber, HIGH); // turn the LED on
152  }
153 #endif
154 
155  return recommended_brightness;
156 }
157 
158 
159 void set_max_power_indicator_LED( uint8_t pinNumber)
160 {
161  gMaxPowerIndicatorLEDPinNumber = pinNumber;
162 }
163 
164 void set_max_power_in_volts_and_milliamps( uint8_t volts, uint32_t milliamps)
165 {
166  FastLED.setMaxPowerInVoltsAndMilliamps(volts, milliamps);
167 }
168 
169 void set_max_power_in_milliwatts( uint32_t powerInmW)
170 {
171  FastLED.setMaxPowerInMilliWatts(powerInmW);
172 }
173 
175 {
176  // power management usage is now in FastLED.show, no need for this function
177  FastLED.show();
178 }
179 
181 {
182  FastLED.delay(ms);
183 }
184 
185 FASTLED_NAMESPACE_END
Representation of an RGB pixel (Red, Green, Blue)
Definition: pixeltypes.h:90
Base definition for an LED controller.
Definition: controller.h:38
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)
calculate_max_brightness_for_power_mW tells you the highest brightness level you can use and still st...
Definition: power_mgt.cpp:80
void setMaxPowerInVoltsAndMilliamps(uint8_t volts, uint32_t milliamps)
Set the maximum power to be used, given in volts and milliamps.
Definition: FastLED.h:440
void set_max_power_in_volts_and_milliamps(uint8_t volts, uint32_t milliamps)
Set the maximum power used in milliamps for a given voltage.
Definition: power_mgt.cpp:164
void delay_at_max_brightness_for_power(uint16_t ms)
Similar to FastLED.delay, but pre-adjusts brightness to keep below the power threshold.
Definition: power_mgt.cpp:180
void set_max_power_indicator_LED(uint8_t pinNumber)
Select a ping with an led that will be flashed to indicate that power management is pulling down the ...
Definition: power_mgt.cpp:159
uint8_t calculate_max_brightness_for_power_mW(const CRGB *ledbuffer, uint16_t numLeds, uint8_t target_brightness, uint32_t max_power_mW)
calculate_max_brightness_for_power_mW tells you the highest brightness level you can use and still st...
Definition: power_mgt.cpp:84
void setMaxPowerInMilliWatts(uint32_t milliwatts)
Set the maximum power to be used, given in milliwatts.
Definition: FastLED.h:444
CLEDController * next()
get the next controller in the chain after this one. will return NULL at the end of the chain ...
Definition: controller.h:100
CRGB * leds()
Pointer to the CRGB array for this controller.
Definition: controller.h:120
uint32_t calculate_unscaled_power_mW(const CRGB *ledbuffer, uint16_t numLeds)
calculate_unscaled_power_mW tells you how many milliwatts the current LED data would draw at brightne...
Definition: power_mgt.cpp:50
central include file for FastLED, defines the CFastLED class/object
void show_at_max_brightness_for_power()
Similar to FastLED.show, but pre-adjusts brightness to keep below the power threshold.
Definition: power_mgt.cpp:174
void show(uint8_t scale)
Update all our controllers with the current led colors, using the passed in brightness.
Definition: FastLED.cpp:42
virtual int size()
How many leds does this controller manage?
Definition: controller.h:117
void set_max_power_in_milliwatts(uint32_t powerInmW)
Set the maximum power used in watts.
Definition: power_mgt.cpp:169
static CLEDController * head()
get the first led controller in the chain of controllers
Definition: controller.h:98
void delay(unsigned long ms)
Delay for the given number of milliseconds.
Definition: FastLED.cpp:120