Понял тут с неделю назад, что ламповая подсветка в мониторе начала сдыхать и решил поставить светодиодную, естественно, с авторегулировкой яркости.
Купил на митинском рынке пару светодиодных полосок шириной около 3 мм, длина - 30 см, на каждой располагается 48 светодиодов, цена 300р. Есть и с 24 светодиодами, 150р за штуку.
Разобрал матрицу.
Внутри - П-образная лампа. Разбирается аккуратно легко, граблей нет. Но все же надо аккуратно.
Заменил лампу на два куска ленты. Одна - целиковая, ее хватило на длинную и короткую стороны, от другой отрезал кусок и поставил на оставшуюся длинную, собрал обратно. Никакой гребенки от светодиодов нет. При полной яркости светодиодам явно внутри жарко, внешняя поверхность разогревается градусов до 60, а у нее тепловой контакт со светодиодами ужасный.
Собрал все примерно как в первом сообщении, единственное - не на ардуине, а на меге48 (валялась), но суть абсолютно та же.
Я несколько изменил способ изменения яркости, сделав изменение яркости плавным и попытался убрать лишние колебания яркости подсветки.
В начале определяются значения с датчика и соответствующие значения яркостей. Единственное, у меня использовался АЦП в 8-битном режиме, поэтому все значения меньше 256.
Код:
#define BrCount 6 // количество элементов в обоих массивах чуть ниже
uint8_t BrIn[BrCount]={43,60,100,140,213,240}; // значения с датчика, должны возрастать!
uint8_t BrOut[BrCount]={154,77,41,20,10,5}; // соответствующие значения для ШИМ. У меня в схеме значение датчика 240 соответствует яркости 5.
volatile uint16_t CurrentBrightness=0; // текущая яркость*256.
volatile uint8_t DestBrightness; // яркость, с которой надо светить (обычная, не умноженная на 255)
uint8_t BrIndex; - текущий индекс режима яркости - индекс из массивов BrIn и BrOut
затем инициализация
Код:
BrIndex=0; // текущий режим- 0
DestBrightness=600; //стартуем с яркостью 60. Можно выставить минимальную.
CurrentBrightness=DestBrightness*256;
Теперь то, что повторяется
Код:
uint16_t br=0;
for (uint8_t i=0;i<32;i++) // в цикле считаем среднее значение с датчика за некоторое время (около секунды). Складываем 32 значения.
{
br+=analogRead(0);
// а еще - плавно меняем яркость.
//А вот здесь делаем интересное. DestBrightness - та яркость, с которой нам надо светить. Но мы на текущий момент светим с яркостью
CurrentBrightness. Нам надо плавно поменять яркость.
//для этого мы меняем CurrentBrightness на CurrentBrightness/32 за шаг.
// такое изменение сделано потому, что человеческие чувства экспоненциальны. Для нас яркость в 30 и 60 кандел отличаются также как и 60 и 120 кд.
//всякие +1 в формулах для того, чтобы при целочисленном делении 20/32 получить не 0, а 1 и все же изменить яркость.
uint16_t destb=DestBrightness*256;
TimerCounter2=0;
if (destb>cbr) // надо увеличить яркость?
{
uint16_t db=cbr/32+1;
if ((cbr+db)<cbr) //переполнение?
cbr=0xFFFF;
else
cbr=cbr+db;
if (destb<cbr)
cbr=destb;
CurrentBrightness=cbr;
}
else
if (destb<cbr) // надо уменьшить?
{
uint16_t db=cbr/32+1;
if (cbr>0)
cbr=cbr-db;
if (destb>cbr)
cbr=destb;
CurrentBrightness=cbr;
}
AnalogWrite(Pin,CurrentBrightness/256);// тут, собственно, задаем яркость
_delay_ms(1000/32); // повторяем 32 раза, значит цикл будет выполняться примерно 1 секунду.
}
uint8_t cbr=br/4/32; // .. делим сумму на 32 (цикл складывает 32 значения) и на 4 - у меня в массиве BrIn значения датчика до 255, а не 1023.
// далее в цикле изменяем BrIndex (индекс текущего режима яркости). Принцип такой - меняем текущий режим только если показания с датчика отклонились от текущего режима настолько, что дошли как минимум до соседнего режима.
// пример - значения в массиве датчика 10,20,40,80. Значения яркостей - 110,120,140,180. Текущий иднекс 2 (датчик выдавал ранее около 40).
// яркость подсветки - 140. Пока датчик не выдаст 20 (или менее) или 80 (или более), яркость подсветки не изменится и режим останется вторым.
// Если датчик выдаст <=20, то режим сменится на 1-й (яркость - 120), если выдаст >=80, то режим сменится на 3-й.
//ну а цикл нужен на случай, если значения с датчика резко поменялась более чем на 1 режим. К примеру - был режим 2 (датчик около 40), а вдруг стало 5. Тогда на первом проходе режим сменится на 1, а потом на 0.
for (uint8_t i=0;i<5;i++)
{
if ( (BrIndex>0) && (BrIn[BrIndex-1]>cbr) )
BrIndex--;
if ( (BrIndex<BrCount-1) && (BrIn[BrIndex+1]<cbr) )
BrIndex++;
DestBrightness=BrOut[BrIndex];
}