You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
devices/apa102/temperature.go

361 lines
6.6 KiB
Go

// Copyright 2016 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
// Marc-Antoine Ruel hereby grants a license to The Periph Authors under the
// the appropriate license.
// This code originates from https://github.com/maruel/temperature. Please keep
// in sync.
package apa102
// Leveraging http://www.vendian.org/mncharity/dir3/blackbody/ which is using
// D65.
// TODO(maruel): Convert to 256 steps with a base at 1024K, this would help
// optimize toRGBFast.
const step = 200
const lookUpRedStart = 6400
var lookUpRed = []uint8{
0xFF, // 6400K
0xFF, // 6600K
0xF9, // 6800K
0xF5, // 7000K
0xF0, // 7200K
0xED, // 7400K
0xE9, // 7600K
0xE6, // 7800K
0xE3, // 8000K
0xE0, // 8200K
0xDD, // 8400K
0xDA, // 8600K
0xD8, // 8800K
0xD6, // 9000K
0xD3, // 9200K
0xD1, // 9400K
0xCF, // 9600K
0xCE, // 9800K
0xCC, // 10000K
0xCA, // 10200K
0xC9, // 10400K
0xC7, // 10600K
0xC6, // 10800K
0xC4, // 11000K
0xC3, // 11200K
0xC2, // 11400K
0xC1, // 11600K
0xC0, // 11800K
0xBF, // 12000K
0xBE, // 12200K
0xBD, // 12400K
0xBC, // 12600K
0xBB, // 12800K
0xBA, // 13000K
0xB9, // 13200K
0xB8, // 13400K
0xB7, // 13600K
0xB7, // 13800K
0xB6, // 14000K
0xB5, // 14200K
0xB5, // 14400K
0xB4, // 14600K
0xB3, // 14800K
0xB3, // 15000K
0xB2, // 15200K
0xB2, // 15400K
0xB1, // 15600K
0xB1, // 15800K
0xB0, // 16000K
0xAF, // 16200K
0xAF, // 16400K
0xAF, // 16600K
0xAE, // 16800K
0xAE, // 17000K
0xAD, // 17200K
0xAD, // 17400K
0xAC, // 17600K
0xAC, // 17800K
0xAC, // 18000K
0xAB, // 18200K
0xAB, // 18400K
0xAA, // 18600K
0xAA, // 18800K
0xAA, // 19000K
0xA9, // 19200K
0xA9, // 19400K
0xA9, // 19600K
0xA9, // 19800K
0xA8, // 20000K
0xA8, // 20200K
0xA8, // 20400K
0xA7, // 20600K
0xA7, // 20800K
0xA7, // 21000K
0xA7, // 21200K
0xA6, // 21400K
0xA6, // 21600K
0xA6, // 21800K
0xA6, // 22000K
0xA5, // 22200K
0xA5, // 22400K
0xA5, // 22600K
0xA5, // 22800K
0xA4, // 23000K
0xA4, // 23200K
0xA4, // 23400K
0xA4, // 23600K
0xA4, // 23800K
0xA3, // 24000K
0xA3, // 24200K
0xA3, // 24400K
0xA3, // 24600K
0xA3, // 24800K
0xA3, // 25000K
0xA2, // 25200K
0xA2, // 25400K
0xA2, // 25600K
0xA2, // 25800K
0xA2, // 26000K
0xA2, // 26200K
0xA1, // 26400K
0xA1, // 26600K
0xA1, // 26800K
0xA1, // 27000K
0xA1, // 27200K
0xA1, // 27400K
0xA1, // 27600K
0xA0, // 27800K
0xA0, // 28000K
0xA0, // 28200K
0xA0, // 28400K
0xA0, // 28600K
0xA0, // 28800K
0xA0, // 29000K
0xA0, // 29200K
0x9F, // 29400K
0x9F, // 29600K
0x9F, // 29800K
0x9F, // 30000K
}
const lookUpGreenStart = 1000
var lookUpGreen = []uint8{
0x38, // 1000K
0x53, // 1200K
0x65, // 1400K
0x73, // 1600K
0x7E, // 1800K
0x89, // 2000K
0x93, // 2200K
0x9D, // 2400K
0xA5, // 2600K
0xAD, // 2800K
0xB4, // 3000K
0xBB, // 3200K
0xC1, // 3400K
0xC7, // 3600K
0xCC, // 3800K
0xD1, // 4000K
0xD5, // 4200K
0xD9, // 4400K
0xDD, // 4600K
0xE1, // 4800K
0xE4, // 5000K
0xE8, // 5200K
0xEB, // 5400K
0xEE, // 5600K
0xF0, // 5800K
0xF3, // 6000K
0xF5, // 6200K
0xFF, // 6400K
0xFF, // 6600K
0xF6, // 6800K
0xF3, // 7000K
0xF1, // 7200K
0xEF, // 7400K
0xED, // 7600K
0xEB, // 7800K
0xE9, // 8000K
0xE7, // 8200K
0xE6, // 8400K
0xE4, // 8600K
0xE3, // 8800K
0xE1, // 9000K
0xE0, // 9200K
0xDF, // 9400K
0xDD, // 9600K
0xDC, // 9800K
0xDB, // 10000K
0xDA, // 10200K
0xD9, // 10400K
0xD8, // 10600K
0xD8, // 10800K
0xD7, // 11000K
0xD6, // 11200K
0xD5, // 11400K
0xD4, // 11600K
0xD4, // 11800K
0xD3, // 12000K
0xD2, // 12200K
0xD2, // 12400K
0xD1, // 12600K
0xD1, // 12800K
0xD0, // 13000K
0xD0, // 13200K
0xCF, // 13400K
0xCF, // 13600K
0xCE, // 13800K
0xCE, // 14000K
0xCD, // 14200K
0xCD, // 14400K
0xCC, // 14600K
0xCC, // 14800K
0xCC, // 15000K
0xCB, // 15200K
0xCB, // 15400K
0xCA, // 15600K
0xCA, // 15800K
0xCA, // 16000K
0xC9, // 16200K
0xC9, // 16400K
0xC9, // 16600K
0xC9, // 16800K
0xC8, // 17000K
0xC8, // 17200K
0xC8, // 17400K
0xC7, // 17600K
0xC7, // 17800K
0xC7, // 18000K
0xC7, // 18200K
0xC6, // 18400K
0xC6, // 18600K
0xC6, // 18800K
0xC6, // 19000K
0xC6, // 19200K
0xC5, // 19400K
0xC5, // 19600K
0xC5, // 19800K
0xC5, // 20000K
0xC5, // 20200K
0xC4, // 20400K
0xC4, // 20600K
0xC4, // 20800K
0xC4, // 21000K
0xC4, // 21200K
0xC3, // 21400K
0xC3, // 21600K
0xC3, // 21800K
0xC3, // 22000K
0xC3, // 22200K
0xC3, // 22400K
0xC3, // 22600K
0xC2, // 22800K
0xC2, // 23000K
0xC2, // 23200K
0xC2, // 23400K
0xC2, // 23600K
0xC2, // 23800K
0xC2, // 24000K
0xC1, // 24200K
0xC1, // 24400K
0xC1, // 24600K
0xC1, // 24800K
0xC1, // 25000K
0xC1, // 25200K
0xC1, // 25400K
0xC1, // 25600K
0xC1, // 25800K
0xC0, // 26000K
0xC0, // 26200K
0xC0, // 26400K
0xC0, // 26600K
0xC0, // 26800K
0xC0, // 27000K
0xC0, // 27200K
0xC0, // 27400K
0xC0, // 27600K
0xC0, // 27800K
0xBF, // 28000K
0xBF, // 28200K
0xBF, // 28400K
0xBF, // 28600K
0xBF, // 28800K
0xBF, // 29000K
0xBF, // 29200K
0xBF, // 29400K
0xBF, // 29600K
0xBF, // 29800K
0xBF, // 30000K
}
const lookUpBlueStart = 1000
var lookUpBlue = []uint8{
0x00, // 1000K
0x00, // 1200K
0x00, // 1400K
0x00, // 1600K
0x00, // 1800K
0x12, // 2000K
0x2C, // 2200K
0x3F, // 2400K
0x4F, // 2600K
0x5E, // 2800K
0x6B, // 3000K
0x78, // 3200K
0x84, // 3400K
0x8F, // 3600K
0x99, // 3800K
0xA3, // 4000K
0xAD, // 4200K
0xB6, // 4400K
0xBE, // 4600K
0xC6, // 4800K
0xCE, // 5000K
0xD5, // 5200K
0xDC, // 5400K
0xE3, // 5600K
0xE9, // 5800K
0xEF, // 6000K
0xF5, // 6200K
0xFF, // 6400K
0xFF, // 6600K
}
// toRGBFast returns an RGB representation of the temperature in Kelvin using
// internal lookup tables, linear interpolation and no floating point
// calculation.
func toRGBFast(kelvin uint16) (r, g, b uint8) {
if kelvin == 6500 {
// Hard fit at 6500K.
return 255, 255, 255
}
if kelvin < 1000 {
kelvin = 1000
}
if kelvin >= 30000 {
kelvin = 29999
}
d := kelvin - lookUpGreenStart
i := d / step
ratio := uint32((d % step) * 255 / step)
g = uint8((ratio*uint32(lookUpGreen[i]) + (255-ratio)*uint32(lookUpGreen[i+1])) / 255)
if kelvin < 6500 {
r = 255
d = kelvin - lookUpBlueStart
i = d / step
ratio = uint32((d % step) * 255 / step)
b = uint8((ratio*uint32(lookUpBlue[i]) + (255-ratio)*uint32(lookUpBlue[i+1])) / 255)
return
}
d = kelvin - lookUpRedStart
i = d / step
ratio = uint32((d % step) * 255 / step)
r = uint8((ratio*uint32(lookUpRed[i]) + (255-ratio)*uint32(lookUpRed[i+1])) / 255)
b = 255
return
}