Преобразование температуры в цвет

Ezheka
Offline
Зарегистрирован: 09.03.2018

делаю термометр на базе MLX90614 с выводом температуры на дисплей в виде цвета. Диапазон измерения от -30 до +50. Примерно -30 это темно синий, а +50 это темно красный. Градация - чем меньше, тем лучше.

Вопрос: как преобразовать температуру в цвет, если цвет выводится HEX значением из трех компонентов RGB, т.е. например белый это FFFFFF, красный FF0000. Пока в голове только вариант с кучей swith  - case, но может есть способ проще?

Upper
Offline
Зарегистрирован: 23.06.2020
синий = map(температура, -30, 50, 255, 0);
красный = map(температура, -30, 50, 0, 255);
зеленый = по вкусу.
 
Может быть я не так вас понял, т.к. не представляю вариант с кучей swith - case
 
Добавлено позже. Посмотрел. Получается не красиво. Мой совет не годится.
Почитал HSV to RGB (Arduino), понял про  swith - case
rkit
Offline
Зарегистрирован: 23.11.2016

Это делается в шкале HSV.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Это можно делать в шкале HSV, это можно делать непосредственным цветовым клином как у Upper'а, это можно делать еще 100500 способами.

Вопрос лишь в том, который из этих 100500 способов интересует ТС.

(из точки (0,0,255) в точку (255,0,0) можно пройти почти бесконечным количеством траекторий. А если разрешить циклы - то и совсем бесконечным)

b707
Offline
Зарегистрирован: 26.05.2017

Ezheka пишет:

но может есть способ проще?

цвет в шкале HSV - это прямая от красного до красного через все цвета

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

b707 пишет:

Ezheka пишет:

но может есть способ проще?

цвет в шкале HSV - это прямая от красного до красного через все цвета

Нужно не от красного до красного, а от синего до красного. Если S=const и V=const, то сделать это можно двумя способами: через фиолетовый (как предложил Upper) и через зеленый (как, вероятнее всего, подразумевал rkit).

Ezheka
Offline
Зарегистрирован: 09.03.2018

Нашел либу ColorConverterLib которая занимается преобразованием HSV - RGB 

Только она работать отказывается, даже пример который с нею идет, выдает

RGBConverterLib.h: No such file or directory

Погуглил, имя либы изменилось с RGB на ColorConverter, но переименование не помогает. В имени файла библиотеки Color, в тексте файла RGB, муть какая то. Нашел у Гайвера алгоритм перевода 

// включить цвет в HSV, принимает 0-255 по всем параметрам
void setHSV(uint8_t h, uint8_t s, uint8_t v) {
  float r, g, b;
  byte _r, _g, _b;
  float H = (float)h / 255;
  float S = (float)s / 255;
  float V = (float)v / 255;
  int i = int(H * 6);
  float f = H * 6 - i;
  float p = V * (1 - S);
  float q = V * (1 - f * S);
  float t = V * (1 - (1 - f) * S);
  switch (i % 6) {
    case 0: r = V, g = t, b = p; break;
    case 1: r = q, g = V, b = p; break;
    case 2: r = p, g = V, b = t; break;
    case 3: r = p, g = q, b = V; break;
    case 4: r = t, g = p, b = V; break;
    case 5: r = V, g = p, b = q; break;
  }
  _r = r * 255;
  _g = g * 255;
  _b = b * 255;

буду пробовать...

b707
Offline
Зарегистрирован: 26.05.2017

Ezheka - сколько вам градаций цвета надо? Может проще заранее палитру создать?

rkit
Offline
Зарегистрирован: 23.11.2016

В fastled есть все возможные и невозможные инструменты для работы с цветом.

Ezheka
Offline
Зарегистрирован: 09.03.2018

Мне нужно чтобы разница в 0,5 градуса в температуре уже была различима на экране.

Ezheka
Offline
Зарегистрирован: 09.03.2018

Вот получил я нужный цвет в трех разных цифрах -  r,g,b, как мне его склеить в формат HEX? Преобразовать из десятичного в 16, потом в строку и строку склеить? 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А у Вас какая глубина цвета? 16-разрядная? 18-разрядная? 24-разрядная?

 

PS. Посмотрел в исходном сообщении, там 24. Тогда просто каждый цвет переводится независимо от других в свой байт (кроме старшего) четырехбайтового числа.

Ezheka
Offline
Зарегистрирован: 09.03.2018

В общем, что HSV, что колесо цветов дает очень грубое преобразование, неинформативное. +20 и +23 градуса визуально не отличаются. Скорее всего надо все данные писать в массив, вычислять минимум и максимум и раскидывать  результаты по всей цветовой шкале. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ezheka пишет:

В общем, что HSV, что колесо цветов дает очень грубое преобразование, неинформативное. +20 и +23 градуса визуально не отличаются.

Ну и кто мешает сделать +20 синим, а +23 красным? Будут очень даже сильно различаться.

Могу посоветовать формировать каждый цвет при помощи ДПСЧ, тогда два соседних цвета практически наверняка будет заметно различаться.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ezheka пишет:

В общем, что HSV, что колесо цветов дает очень грубое преобразование, неинформативное. +20 и +23 градуса визуально не отличаются. Скорее всего надо все данные писать в массив, вычислять минимум и максимум и раскидывать  результаты по всей цветовой шкале. 

Ну -30  -  +50  это всего 81 цвет если шаг в 1 градус. Попробуй просто руками выбрать цвета чтобы визуально отличались и запихни в массив. 

Ezheka
Offline
Зарегистрирован: 09.03.2018

как сохранить в массив цвета в nex? Записываю красный 0xff0000 он выдает его как синий. 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Может надо байты местами поменять ?

b707
Offline
Зарегистрирован: 26.05.2017

Ezheka пишет:

как сохранить в массив цвета в nex? Записываю красный 0xff0000 он выдает его как синий. 

кроме формата RGB бывает еще GRB, BRG... и так далее - все 6 комбинаций. Если у вас 0xff0000 - не красный. значит у вас не RGB

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

чо вы гадаете, кода то нет.  я вот думаю, у него переменная не того типа. 

Ezheka
Offline
Зарегистрирован: 09.03.2018

В общем, в описании к библиотеке имеющаяся ссылка на цвета неверная, цвета описываются форматом 

#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0  
#define WHITE   0xFFFF

поэтому у меня половина цветов и плывет, только синий совпадает.

Это, я так понимаю, 16 бит глубина. Понять бы еще как ею управлять.

 

b707
Offline
Зарегистрирован: 26.05.2017

Ezheka пишет:

Это, я так понимаю, 16 бит глубина. Понять бы еще как ею управлять.

Скорее всего формат Color565 - то есть Red - 5 бит, Green- 6 бит, Blue - 5 бит

Переводится в 24 бита и обратно элементарно битовыми сдвигами

Ну или можете в инете готовую функцию найти, перевод из 565 в 888 есть почти в любой графической библиотеке, даже в моей для RGB матриц есть :)

Ezheka
Offline
Зарегистрирован: 09.03.2018

эээ, нельзя ли пример или ссылку? Не у всех тут есть опыт в сдвигании бит ))

b707
Offline
Зарегистрирован: 26.05.2017

Ezheka пишет:

эээ, нельзя ли пример или ссылку? Не у всех тут есть опыт в сдвигании бит ))

вам в какую сторону надо? Вот 888 -> 565

// Color 8/8/8 to Adafruit_GFX 5/6/5
// If no gamma flag passed, assume linear color
uint16_t Color888(uint8_t r, uint8_t g, uint8_t b) {
	return ((uint16_t)(r & 0xF8) << 8) | ((uint16_t)(g & 0xFC) << 3) | (b >> 3);
}

 

сорри, просьба дубль выше стереть

 

Ezheka
Offline
Зарегистрирован: 09.03.2018

Воть как склеивают в NEX из RGB

color = ((long)_r << 16) | ((long)_g << 8) | _b;

как это переделать в 16 бит?

А, вижу пример, пробую

Ezheka
Offline
Зарегистрирован: 09.03.2018

Все пошло, спасибо преогромное!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

b707 пишет:

Ezheka пишет:

как сохранить в массив цвета в nex? Записываю красный 0xff0000 он выдает его как синий. 

кроме формата RGB бывает еще GRB, BRG... и так далее - все 6 комбинаций. Если у вас 0xff0000 - не красный. значит у вас не RGB

BGR.

Честно говоря, других комбинаций кроме RGB и BGR не встречал, но это не значит, что их не может быть.