21 listopada 2008, 22:33:22 - Poziom 0 [ projekt AmaLight projekty] [AmaLight] Nieliniowość CCFL

Największymi trudnościami w sterowaniu zimnymi katodami są ich wyłączanie i liniowe ściemnianie. Niewyłączanie prowadzi do efektu widzianego tu, gdy ekran wyświetla całkiem czarny obraz, a z tyłu widać niebieską poświatę. W pokazywanym projekcie MoMoLight, podłączono zimne katody w ten sposób. Przy sterowaniu PWM, obniżenie "mocy" świetlówki poniżej 10%, powoduje mruganie, także przy wypełnieniu zbliżającym się do zera. Łatwo można poprawić ten schemat, podłączając kondensator (4.7uF) między masą inwertera, a masą układu. Pozwala to zejść do 1% mocy.

Zejście to ma spore znaczenie, gdyż CCFL są nieliniowe (bądź odbieranie światła przez ludzkie oko jest nieliniowe), czyli jeśli zielonej świetlówce zwiększymy moc dwukrotnie, nie uzyskamy dwukrotnie jaśniejszego światła. Podobne zjawisko występuje w monitorach, ale jest korygowane bez wiedzy użytkownika. Reakcje CCFL jest funkcją logarytmiczną (tu jest wykres), czyli dla niskich wartości rośnie szybko, a dla wysokich powoli. Czyli różnica między 50%, a 100% mocy będzie dla nas mniej zauważalna, niż między 5%, a 10% mocy. Teraz już rozumiemy, dlaczego zwiększenie dolnego zakresu do 1% było tak ważne. Prawidłowe wykorzystanie tych możliwości, aby osiągnąć zwiększony kontrast wirtualnego ekranu (powierzchni oświetlonej przez CCFL), polega na użyciu korekcji gamma, czyli pomnożeniu funkcji logarytmicznej CCFL przez funkcję wykładniczą, co dla pewnych parametrów powinno dać liniowe odwzorowanie kolorów na CCFL.

8 komentarzy

 

Ucieszyłem się jak zobaczyłem na twoim blogu że robisz ambilighta. Ja swoja naukę programowania kontrolerów (AVR + C) zacząłem właśnie od planu zrobienia prostego ambilighta, ale napotkałem problemy które były dla mnie za duże.
Problemami było m.in. to co piszesz w przypadku CCFL, czyli nieliniowe narastanie jasności diód (bo na nich robiłem). Zrobiłem tablicę 256 docelowych jasności z już skorygowaną gammą, ale wtedy robiły się "schodki" jak się powoli zapalało (najwyraźniej 8-bitowe PWM to za mała rozdzielczość).
Ponadto, nie wiedziałem jak podłączyć USB.
Myślalem też o podpięciu więcej diód niż trzy, ale "emulacja" PWM na zwykłych wyjściach dała taki wynik, że diody co jakiś czas błyskały jasno lub gasły na ułamek sekundy, po czym wnioskuję że PWM nie był "równomierny".
Dobiło mnie na dodatek to, że z elektroniki jestem noga (zdecydowanie wolę pisać kod...) i nie wiedziałem jak podłączyć tranzystory, mimo szukania w necie informacji.
A teraz już na mojej specjalizacji (robotyka) nie mam kontrolerów, i nie za bardzo mam czas, więc póki co nie wracam do tego.

Dlatego trzymam kciuki za AmaLight, i mam szczerą nadzieję że jeśli oublikujesz źródła i płytki, to coś się z tego nauczę i uda mi się to zrobić u siebie :)
(A przy okazji przeportować to na Linuxa, bo z windowsa nie korzystam :>;)

Fluxid - 26 listopada 2008 17:29:40

Do etapu korygowania jasności do tej na ekranie nie doszedłem - niebieskie CCFL wciąż do mnie nie dotarły. Korzystam z firmwarowego PWMa, jakby nie patrzeć, nie ma AVRów ze sprzętowym PWMem na dziewięć wyjść. Dodałeś kondensator na wyjście emulowanego PWMa? Powinien wygładzić sygnał.
Robiłeś to na LEDach dużej mocy? Pewien nie jestem, ale połączenie takie jak w linku (z dodatkowym rezystorem) mogłoby zadziałać.

>A przy okazji przeportować to na Linuxa, bo z windowsa nie korzystam
Ja nie korzystam z linuksa, przynajmniej prywatnie nie.

remiq - 26 listopada 2008 20:02:39

hej,
dlaczego nie zrobić tego na paskach LED? 3 krotkie listwy RGB laczane z kazdej strony dalyby piorunujacy efekt
jak w philips

wtedy latwobyloby zrobic tak potrzebne funkcje jak regulacja sily swiecenia

zrealizowanie pobierania kolorow pod VISTA jest stosunkowo proste (o ile wlaczone jest aero) spokojnie mozna sie posluzyc metodami getpixel
w przypadku odtwarzania przez directX trzeba uzywac odpowiedniego filtra

system musi byc koniecznie konfigurowalny tak aby nie mial opoznien, jesli beda opozniania bedzie denerwujacy, swiatlo nei moze byc zbyt dynamiczne i mrugac po pokoju co by sie na ekranie dzialo ma sie delikatnie zmieniac i najwazniejsze by w sytuacji ciemnosci na ekranie swiatlo sei znacznie zmiejszalo, reszta nie ejst tak naprawde wazna

kolejna sprawa to opracowac system oswietlenia ktory dzialalby niezaleznie od systemu, ambilight nie steroweany przez komputer
czyli prosty system szarego oswietlenia ktore ma regulowana jasnosc za pomoca jakiegos fotodetektora, np. fotorezystora ktory mierzylby natezenie swiatla z monitora i uzaleznial od tego sile swiecenia podswietlenia tv

co sadzisz o moich pomyslach remiq?
daj znac, moge pomoc, wiem jak oprogramowac to

jacie - 27 listopada 2008 18:40:30

> dlaczego nie zrobić tego na paskach LED?
Jak zaczynałem planować, nie widziałem jeszcze telewizora z ambilight. Zdecydowałem się na CCFL, bo przy ich użyciu światło jest równomierne, nie jak przy LEDach punktowe. Telewizory, które oglądałem, miały paski LEDów RGB, ale miały one połączenie każdy osobno, a nie jedno na cały pasek (połowa zmieniała kolor, druga połowa nie). LEDy też są nieliniowe.

Pobieranie kolorów już jest, screeny są tutaj: http://remiq.jogger.pl/2008/11/16/amalight-czym-jest-amalight/

Co do oświetlenia białego, nowe monitory mają DCR, czyli dynamiczny kontrast. Działa to w ten sposób, że CCFLe, które podświetlają ekran, dostają sygnał wewnątrz monitora. Najprostszy mod, to podpięcie się pod to i sterowanie tym sygnałem dodatkowymi CCFLami na zewnątrz.

W razie problemów, napiszę na blogu.

remiq - 27 listopada 2008 20:59:20

nie widzę tam informacji w jaki sposób softwarowo to rozwiązałeś? rozumiem że to działa w każdym windowsie? w Vista też?

rozwiązanie które proponujesz dla wielu będzie nie do zniesienia, ja wolałbym prosty układ z czujnikiem światła co delikatnie podświetla tył telewizora, odpowidnio rozproszone listwy led (jakikolwiek filtr, papier chociaż) dają naprawdę ładne równomierne światło

jacie - 28 listopada 2008 01:09:47

Korzystam z GDI, ale nie po pojedynczych pikselach, tylko kopiuje cały ekran do bufora. Wszystkie aktualnie wspierane windowsy mają GDI, Vista również.

remiq - 28 listopada 2008 12:13:21

GDI jest dosc wolne pod Vista - jesli jest wlaczone Aero w Vista to juz wogole jest problem.

[DllImport("User32.dll";)]
public static extern IntPtr GetDC(int hWnd);

GlobalVariables.DeskDC = User32.GetDC(0);
temp = GDI32.GetPixel(GlobalVariables.DeskDC, PixelX + MyScreen.Bounds.Left, PixelY + MyScreen.Bounds.Top);

GetPixel z GDI32 pod Vista dziala strasznie topornie...

Znalazlem inny sposob ktory pod Aero przynajmniej dziala:
public void GetDesktop()
{
int screenLeft = Screen.AllScreens[GlobalVariables.SelectedDisplay].Bounds.Left;
int screenTop = Screen.AllScreens[GlobalVariables.SelectedDisplay].Bounds.Top;

int screenX = Screen.AllScreens[GlobalVariables.SelectedDisplay].Bounds.Width + screenLeft;
int screenY = Screen.AllScreens[GlobalVariables.SelectedDisplay].Bounds.Height + screenTop;

IntPtr hBmp;
IntPtr hdcScreen = User32.GetDC(0);
// IntPtr hdcScreen = GetDC(GetDesktopWindow());
IntPtr hdcCompatible = GDI32.CreateCompatibleDC(hdcScreen);

// Bitmap bmp;

hBmp = GDI32.CreateCompatibleBitmap(hdcScreen, screenX, screenY);

if (hBmp != IntPtr.Zero)
{
IntPtr hOldBmp = (IntPtr)GDI32.SelectObject(hdcCompatible, hBmp);
// BitBlt(hdcCompatible, 0, 0, screenX, screenY, hdcScreen, 0, 0, 13369376);
GDI32.BitBlt(hdcCompatible, 0, 0, screenX, screenY, hdcScreen, 0, 0, 13369376);

GDI32.SelectObject(hdcCompatible, hOldBmp);
GDI32.DeleteDC(hdcCompatible);
User32.ReleaseDC(User32.GetDC(0), hdcScreen);

// bmp = System.Drawing.Image.FromHbitmap(hBmp);
myBitmap = System.Drawing.Image.FromHbitmap(hBmp);

GDI32.DeleteObject(hBmp);
GC.Collect();
// return bmp;
}

// return null;


}
private uint ColorToUIntBGR(Color color)
{
return (uint)((color.A << 24) | (color.B << 16) |
(color.G << 8) | (color.R << 0));
}

GetDesktop(); // -> myBitmap
myColor = myBitmap.GetPixel(PixelX + MyScreen.Bounds.Left, PixelY + MyScreen.Bounds.Top);
temp = ColorToUIntBGR(myColor);

ale niestety nadal rewelacja to nie jest...
teoretycznie GDI dziala dobrze pod XP - szybko... i na tym koniec.

czy ma ktos lepsze rozwiazanie?

SiLAS - 23 marca 2009 03:06:54

Poniższy kod działa całkiem szybko:

int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
int loop = 1;
int loopi=0;
HDC hdc=NULL;
DWORD *pBuf=NULL;
BITMAPINFO bmpInfo;
// to save as bmp
BITMAPFILEHEADER bmpFileHeader;
FILE* fp=NULL;

COLORREF crColorLeft, crColorTop, crColorRight;
HBITMAP hCaptureBitmap;
HWND hDesktopWnd = GetDesktopWindow();
HDC hDesktopDC = GetDC(hDesktopWnd);
HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
hdc=GetDC(NULL);
ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

int pasek = 200;
hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight);
SelectObject(hCaptureDC,hCaptureBitmap);
BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,hDesktopDC,0,0,SRCCOPY);

GetDIBits(hdc,hCaptureBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
if(bmpInfo.bmiHeader.biSizeImage<=0)
bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
//pBuf = malloc(bmpInfo.bmiHeader.biSizeImage);
pBuf = malloc(nScreenWidth*nScreenHeight*(32+7)/8);
bmpInfo.bmiHeader.biCompression=BI_RGB;
GetDIBits(hdc,hCaptureBitmap,0,nScreenHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);

// czesc 4 (patrz numpad)
crColorLeft = avgFromRect3(pBuf, nScreenWidth, 0, (nScreenHeight/3) , (nScreenWidth/3), (nScreenHeight/3) );


---

COLORREF avgFromRect3(DWORD *pSource, int nScreenWidth, int x, int y, int width, int height)
{
int divide = 4;
int divcount = 0;
unsigned int iR = 0;
unsigned int iG = 0;
unsigned int iB = 0;
unsigned int iC = 0;
int i,j,k;
k=0;
for(i=x+width ; i>x ; i--)
for(j=y+height ; j>y ; j--)
{
//printf("%i <- %i\n", (i+(width*j)), (x+(nScreenWidth*y)) );
iR += (long)GetRValue( pSource[i+(nScreenWidth*j)] );
iG += (long)GetGValue( pSource[i+(nScreenWidth*j)] );
iB += (long)GetBValue( pSource[i+(nScreenWidth*j)] );
iC++;
}
iR = iR / iC;
iG = iG / iC;
iB = iB / iC;
return RGB(iR, iG, iB);
}

Przy włączonym Aero, nie ma problemu z przetwarzaniem obrazu w rozdzielczości 1680x1050.

remiq - 23 marca 2009 13:30:31

Podpis:
Treść:
Strona WWW (opcjonalnie):
Wpisz kod:code

Powrót na główną

head Main Jogger. jajc. remiq.net. chrome. Notes headlines. bookmarks.
odstep.!Ona (0/0)
odstep.Przyjaciele (4/5)
odstep.CTD (Wiktor)
odstep.eR
odstep.Jade
odstep.Lobo
odstep.Kategorie
odstep.embeded [5]
odstep.niepoprawne [13]
odstep.o remiqu [91]
odstep.14.03.2007 - 13.04.2009 [2]
odstep.Ogólne [927]
odstep.Politycznie [103]
odstep.projekt Libraria [13]
odstep.projekty [7]
odstep.Irony Projects [1]
odstep.projekt AmaLight [12]
odstep.projekt Fud [48]
odstep.remiq.net [21]
odstep.YPA [1]
odstep.Rodzinnie [4]
odstep.Szczecin [3]
odstep.Techblog [4]
odstep.Uczelnia [25]
odstep.z eksportu [20]
odstep.Jogger (7/7)
odstep.Kobieta z pingwinem
odstep.Zlota betatesterka
odstep.RKlisowski
odstep.Aaaa to kto?
odstep.ZdzichuBG
odstep.WIPS (3/3)
odstep.Kasprzol
odstep.Xycu
odstep.Bookmarks
odstep.Łosoś?
odstep.JAJC Plugins
odstep.Biblionetka
odstep.Login
odstep.Zalogowano jako:
odstep.
odstep.Archiwum
odstep.Styczeń 2004
odstep.Luty 2004
odstep.Marzec 2004
odstep.Kwiecień 2004
odstep.Maj 2004
odstep.Czerwiec 2004
odstep.Lipiec 2004
odstep.Sierpień 2004
odstep.Wrzesień 2004
odstep.Październik 2004
odstep.Listopad 2004
odstep.Grudzień 2004
odstep.Styczeń 2005
odstep.Luty 2005
odstep.Marzec 2005
odstep.Kwiecień 2005
odstep.Maj 2005
odstep.Czerwiec 2005
odstep.Lipiec 2005
odstep.Sierpień 2005
odstep.Wrzesień 2005
odstep.Październik 2005
odstep.Listopad 2005
odstep.Grudzień 2005
odstep.Styczeń 2006
odstep.Luty 2006
odstep.Marzec 2006
odstep.Kwiecień 2006
odstep.Maj 2006
odstep.Czerwiec 2006
odstep.Lipiec 2006
odstep.Sierpień 2006
odstep.Wrzesień 2006
odstep.Październik 2006
odstep.Listopad 2006
odstep.Grudzień 2006
odstep.Styczeń 2007
odstep.Luty 2007
odstep.Marzec 2007
odstep.Kwiecień 2007
odstep.Maj 2007
odstep.Czerwiec 2007
odstep.Lipiec 2007
odstep.Sierpień 2007
odstep.Wrzesień 2007
odstep.Październik 2007
odstep.Listopad 2007
odstep.Grudzień 2007
odstep.Styczeń 2008
odstep.Luty 2008
odstep.Marzec 2008
odstep.Kwiecień 2008
odstep.Maj 2008
odstep.Czerwiec 2008
odstep.Lipiec 2008
odstep.Sierpień 2008
odstep.Wrzesień 2008
odstep.Październik 2008
odstep.Listopad 2008
odstep.Grudzień 2008
odstep.Styczeń 2009
odstep.Luty 2009
odstep.Marzec 2009
odstep.Kwiecień 2009
odstep.Maj 2009
odstep.Czerwiec 2009
odstep.Lipiec 2009
odstep.Sierpień 2009
odstep.Wrzesień 2009
odstep.Październik 2009
odstep.Listopad 2009
odstep.Grudzień 2009
odstep.Styczeń 2010
odstep.Luty 2010
odstep.Marzec 2010
odstep.Kwiecień 2010
odstep.Maj 2010
odstep.Czerwiec 2010
odstep.Lipiec 2010
odstep.Sierpień 2010
odstep.Październik 2010
odstep.Listopad 2010
odstep.Marzec 2011
odstep.Kwiecień 2011
odstep.Maj 2011
odstep.Lipiec 2011
odstep.Wrzesień 2011
odstep.Październik 2011
odstep.Listopad 2011
odstep.Marzec 2012
odstep.
odstep.
odstep.

Powered by Jogger