Re: Фоновая подсветка телевизора Ambilight
вот, выкладываю сурсы.
Соединение такое:
PortD Pin7 (Arduino digital 7) соединен с RCK 74hc595 (Pin 12)
PortB Pin3 (Arduino digital 11) соединен с SI 74hc595 (Pin 14)
PortB Pin5 (Arduino digital 13) соединен с SCK 74hc595 (pin 11)
Код выполнен в AVR Studio, поэтому в нем нет
void Setup(void)
и
void loop(void)
вместо них единый
void main(void)
Brightness[48] - массив яркостей, который нужно показать.
Для примера яркость меняется по циклическому закону - увеличивается.
for (i=0;;i++)
{
_delay_ms(1);
for (uint8_t j=0;j<48;j++)
Brightness[j]++;
}
bitdata[6] (48 бит) побитово хранит то, что нужно выдать в 595-ые. Параллельно подключенные светодиоды одного цвета одной зоны соответствуют одному биту.
Когда начинается новая итерация ШИМ (PWM_Counter==0) bitdata заполняется битовыми единицами - 0xFF.
if (PWM_Counter==0)
{
// по умолчанию при PWM_Counter==0 все светодиоды горят, а затем гаснут по мере необходимости.
for (uint8_t l=0;l<6;l++)
bitdata[l]=0xff;
Затем, каждый элемент Brightness[] проверяется и если он меньше или равен PWM_Counter, то соответствующий бит в bitdata[] сбрасывается и этим гасится одна зона одного цвета.
Таким образом, из 256 итераций цикла (PWM_Counter от 0 до 255) каждый из 48 битов в bitdata[] установлен в 1 ровно столько итераций, сколько установлено в байтах яркости Brightness[].
Код тут оптимизирован, но несмотря на это код из таймера жрет порядка 70% процессорного времени. _delay_ms(1) реально длится 2.5 мс.
Если же повторяющийся кусок убрать в цикл, то быстродействие падает еще почти в полтора раза - _delay_ms(1) ждет уже 3.5 мс...
Замеры производились при оптимизации -O3.
Если же проводить замеры со стандартной для Arduino оптимизации -O2
то приведенный код дает
3.5 мс вместо _delay_ms(1)
а в случае замены повторяющегося куска циклом, таймер начинает потреблять 100% процессорного времени.
PHP код:
#define TCNT2_Const 256-9
uint8_t volatile PWM_Counter_v;
uint8_t Brightness[48];
uint8_t bitdata[6];
void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDRB |= (1<<3)|(1<<5);
/* Enable SPI, Master, set clock rate fck/2 */
SPSR =(1<<SPI2X);
SPCR = (1<<SPE)|(1<<MSTR);
}
void SPI_MasterTransmit(char cData)
{
uint8_t a=SPSR;
a=SPDR; // очищаем SPIF перед отправкой данных, чтобы этот бит выставился только после завершения отправки
SPDR = cData;
}
void Out(void)
{
while(!(SPSR & (1<<SPIF)));// ждем пока не завершится передача данных
uint8_t a=SPDR;
PORTD |= (1<<PIN7);
PORTD &= ~(1<<PIN7);
PORTD = PORTD ^ (1<<PIN3);
}
SIGNAL(TIMER2_OVF_vect)
{
TCNT2 = TCNT2_Const;
Out();
uint8_t PWM_Counter=PWM_Counter_v;
{
if (PWM_Counter==0)
{
// по умолчанию при PWM_Counter==0 все светодиоды горят, а затем гаснут по мере необходимости.
for (uint8_t l=0;l<6;l++)
bitdata[l]=0xff;
}
uint8_t * Bright;
Bright= &Brightness[0];
for (uint8_t j=0;j<6;j++)
{
uint8_t CurrData=bitdata[j];
uint8_t bit=1;
// for (uint8_t k=0;k<8;k++)
// 0
{
if (*Bright<=PWM_Counter)
CurrData &= ~bit;
bit=bit<<1;
Bright++;
}
// 1
{
if (*Bright<=PWM_Counter)
CurrData &= ~bit;
bit=bit<<1;
Bright++;
}
// 2
{
if (*Bright<=PWM_Counter)
CurrData &= ~bit;
bit=bit<<1;
Bright++;
}
// 3
{
if (*Bright<=PWM_Counter)
CurrData &= ~bit;
bit=bit<<1;
Bright++;
}
// 4
{
if (*Bright<=PWM_Counter)
CurrData &= ~bit;
bit=bit<<1;
Bright++;
}
// 5
{
if (*Bright<=PWM_Counter)
CurrData &= ~bit;
bit=bit<<1;
Bright++;
}
// 6
{
if (*Bright<=PWM_Counter)
CurrData &= ~bit;
bit=bit<<1;
Bright++;
}
// 7
{
if (*Bright<=PWM_Counter)
CurrData &= ~bit;
bit=bit<<1;
Bright++;
}
bitdata[j]=CurrData;
SPI_MasterTransmit(CurrData); // выводим очередные 8 бит
}
}
PWM_Counter_v++;
}
int main(void)
{
PWM_Counter_v=255;// первым делом копируем данные в CurrBrihgtness
uint8_t i;
for (i=0;i<48;i++)
{
Brightness[i]=(1<<(i&7));
// Brightness[i]=0;
}
PORTB = 0;
PORTD = 0;
DDRD |= (1<<PIN3);
DDRD |= (1<<PIN7);
SPI_MasterInit();
TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
TCCR2B |= (1<<CS22);
ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора
TCNT2 = TCNT2_Const; // 16000000/256/100/64=8 tcnt2=256-8=248.
TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.
sei();
for (;;)
{
_delay_ms(1);
for (uint8_t j=0;j<48;j++)
Brightness[j]++;
}
}
UPD: код я у себя тут еще оптимизировал, но выигрыш копеечный.
Re: Фоновая подсветка телевизора Ambilight
Цитата:
Сообщение от
Chip
Я тут подумал , нужно все таки делать на одной плате все делать, а к разьемам подключать лены светодиодные.
Предлагаю свой вариант разбивки Ambilight подсветки на зоны
Вложение 7747
Моя одобряет ! :-)
Вложений: 2
Re: Фоновая подсветка телевизора Ambilight
Какой из вариантов подключения предпочтительней? Я склоняюсь к последнему
Вложение 7759
Вложение 7760
Re: Фоновая подсветка телевизора Ambilight
второй вариант почти правильный. Почти - потому, что когда я использовал 12-й вывод, были проблемы. Этот вывод является выводом SPI, видимо поэтому не получается им дергать когда хочется. Вот я и переключил на 7 вывод.
Еще бы надо найти аналог uln2003 на полевиках. Я посмотрел, у них при токе в районе 500 мА, на ключах падает порядка вольта. Надо считать токи и тепловыделение.
Вложений: 1
Re: Фоновая подсветка телевизора Ambilight
По токам , если использовать светодиодную ленту двойной плотности, то 800мА на 1 метр , я думаю что такой зоны у тебя не будет.
Вот смотри что нашел Вложение 7769
и вот еще драйвер светодиодов с ШИМ и на 24 канала
Еще один драйвер
Re: Фоновая подсветка телевизора Ambilight
tle6020 - какая-то хитрая штука, пока не вкурил
драйверы светодиодов - штука прикольная, надо посмотреть, может есть такие с мощными выходами. У них наоборот - светодиоды включаются не параллельно, а последовательно.
По поводу uln2x03: несмотря на заявленные 500мА на каждый вывод, у этой микрухи есть ограничение на 1W суммарного тепловыделения. И получается, что максимум, что можно протащить - примерно по 100мА на каждый канал одновременно при 100% яркости.
По твоей схеме расположения линеек, получаем порядка 25-30 см на каждую полоску. Это согласуется только с линейкой однократной плотности и то на пределе :-(.
Паять 42 транзистора (и развести плату еще) - это пипец. Но, что самое интересное, если взять банальные самые дешевые bc817, то можно на каждую линию отвести уже более 400мА, хотя транзисторы в мелком корпусе - sot23.
Вложений: 1
Re: Фоновая подсветка телевизора Ambilight
Цитата:
По поводу uln2x03: несмотря на заявленные 500мА на каждый вывод, у этой микрухи есть ограничение на 1W суммарного тепловыделения. И получается, что максимум, что можно протащить - примерно по 100мА на каждый канал одновременно при 100% яркости.
По твоей схеме расположения линеек, получаем порядка 25-30 см на каждую полоску. Это согласуется только с линейкой однократной плотности и то на пределе :-(.
Согласен.
При падении 1в х 0,5А=0,5Ватт тепла на один канал умножаем на 7 и получаем 3,5 ватта.
Вот микруха TLE 6244X на 18 каналов при токе 1.1А, работает с SPI. Только у нас в России они под заказ :(
Re: Фоновая подсветка телевизора Ambilight
Выложил в шапке программу работающую от 1 до 42 каналов, в зависимости от настроек
Re: Фоновая подсветка телевизора Ambilight
я как-бы на форуме нечесно - ни ардуины нету, ни машины, но рискну поспрашивать ;)
тоже ношусь давно с идеей задней подсветки для телевизора, подошел совсем близко (нашел rgb-светодиоды, сделал лампу с подсветкой, которая плавно меняет цвет со временем и подошел плотно к тестам с источниками света), и встает вопрос с софтом; можно у автора поста узнать принцип, по которому его программа работает?
когда обдумывал - как бы я это делал - то пока придумал только вариант с direct-show фильтром, который бы ставился перед рендерером, анализировал бы зоны и передавал бы инфу для подсветки
только тут вижу 2 проблемы: всю эту светотень хочу добавить к хтпс-компьютеру, который подключен к 32" тв
На компе стоит W7 + xbmc + eventGhost для управления пультом; xbmc - кросплатформенный проект, который не использует directshow для проигрывания - вот и первая моя проблема
Но последнее время стали появлятся сборки, в которых на винде используется directshow - для того, чтобы использовать возможности видеокарт для аппаратного декодирования видео, т.е. теоретически идея с фильтром как-бы срабатывает - но тут свои заморочки - между фильтром-декодером и рендерером нельзя вставлять ничего (видимо декодер работает прямо с памятью видеокарты, не курил сильно причину) - т.е. если есть ускорение (а я комп специально собирал со встроенным видео, которое умеет аппаратно декодить), то снова мой план не срабатывает
Т.е. пока вариант только такой - использовать ds-сборки и отказаться от ускорения; собственно комп и так тянет 720p, ускорение вроде не очень и надо - но во-1, "заплачено уже ж", во-2 проц грузится сильнее -> кулер его крутится быстрее -> а летом так еще быстрее, а значит шумит
В общем, самому изобретать велосипед не обязательно, если (я тему очень бегло по диагонали пока просмотрел и все) протокол программы топикстартера документирован, то можно и ею попользоваться - но уже интерес взыграл, у меня приятель (работает с 3д в игрушках) говорит, что в directX не так просто влезть.. Так что стало просто интересно, тычек бы в нужную сторону..
спсб
Re: Фоновая подсветка телевизора Ambilight
Использую BitBlt и ScanLine