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

power_mgt.cpp - github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: edfb568dc12c17431907afd9660ad088d535c5b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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 );
}