2022. december 6., kedd

Gyorskeresés

Vezeték nélküli ambiens megvilágítás mindenféle kijelzőtartalomhoz

Írta: |

[ ÚJ BEJEGYZÉS ]

https://github.com/dmadison/Adalight-FastLED
Nemrégiben volt már cikk itt a logouton boblight, Ambilight témában.
A helyzet az, hogy én is régóta tervezek ilyesmit alkotni, de már a kezdetektől más irányban gondolkodtam.

Az egyik fő pont, hogy a TV tud vezeték nélküli megjelenítőként viselkedni, márpedig ezt nem rontanám el egy vezetékes soros kommunikációval a boblight érdekében.
Egy másik szempont volt, hogy nem csak Kodiból filmezésre szeretném alkalmazni, hanem akár Youtubera, vagy játékra is. Emiatt nem akartam bekorlátozódni a boblightal.
Harmadik szempont, hogy szerettem volna a TV mögötti fényeket az okosotthon rendszerembe integrálni. A nappaliban ha üvölt a TV, vagy éppen fejhallgatóval hallgatok zenét, akkor hasznosak az olyan vizuális effektek, mint amikor a kapucsengő villog a TV mögött.

Nagyon felületes keresést végeztem, de nem találtam minderre jó megoldást. Ráadásul ha lett is volna, valószínűleg ugyanúgy munkát generált volna az illesztése.

FONTOS!

Ez a bejegyzés elsősorban NEM step-by-step segédlet. Három fő okból:
- A megoldásom nem elég univerzális ahhoz, hogy általánosságban bátran ajánljam bárkinek, hogy másolja le.
- A kódjaim jelenleg még elég okádékok, így nem osztanám meg őket jelen formájukban. Ezen változtatni két esetben tervezek: 1) Ha én nem látom át. 2) Ha generálódik akkora igény, hogy egyszerűbb a kódomat publikálni, mint válaszolni a kérdésekre.
- Most, hogy összeállt annyira a rendszer, hogy egyértelmű a működőképessége, kicsit kiélvezem, majd a tapasztalatok alapján fogom folytatni a fejlesztését.

Természetesen ha valaki szeretne hasonlót, szívesen segítek neki.

De akkor mégis mit fogok leírni?
Számos tapasztalatot, ami segít olyanoknak, akik hasonlóba fognak. Főleg, mert elég sok az ellentmondás a sok boblight leírásban.
Útmutatást azoknak, akik hozzám hasonlóan maguk szeretnék megalkotni a szükséges dolgokat, de kevésbé tudják, merre induljanak, vagy hogy egyáltalán lehetséges e ez.
(Én magam sem voltam benne biztos sokáig, hogy az eredmény ilyen jól élvezhető lesz. Legnagyobb bizonytalanságom a képfeldolgozásban, a megfelelően gyors vezeték nélküli átvitelben volt.)

Gyorsan összefoglalva, hogy mi is fog történni:
A vezeték nélküli kommunikáció érdekében egy ESP modult fogunk a LED-ek vezérlőjének használni. Az ESP megkapja a hálózaton keresztül az ambiens LED-ek színértékét a képforrást adó PC-től. A PC-n pedig egy vezérlő szoftver fog futni, amiben paraméterezhető a használt kép, az ambiens fény színének és erősségének kalkulációja, és néhány parancs a mikrokontrollernek.

WS2812B és ESP8266 jelszint illesztése

Ezzel kapcsolatban a legfontosabb aggály a legtöbb oldalon az, hogy az ESP 3.3V-os logikája képtelen meghajtani a WS2812B LED adat bemenetét, ugyanis annak specifikációja szerint a tápfeszültség 70%-át el kell érnie a logikai 1 jelnek. Ennél a szalagnál 5V-ra ez 3.5V.
Ennek kiküszöbölésére több úton terveztem elindulni:
- Tápfeszültség csökkentése: A már linkelt adatlap szerint a tápfeszültség minimuma 3.5V. Eddig persze nem mennék el, 3.3/0,7=4,71V már körülbelül elég alacsony lenne, de elég magas e? Mivel gyakran tápolják ezeket a szalagokat Lítium kémiájú akksikkal, amik 4.2V körül vannak teljes töltésen, a 4,7V elégségesnek tűnik.
- Áldozati LED bevezetése: Ha valaki nagyon tart attól, hogy a teljes szalagot alulfeszelje, megoldható az, hogy csak az első LED-et koplaltatja. Ebben az esetben az első LED felfogja a 3.3V-os jelszinteket, és a kimenetén már saját tápfeszültsége szerint ad jelszinteket. Ez pedig már eléri a következő LED küszöbét.

A mókás az, hogy végül egyikre sem volt szükség. Programozás közben USB-ről tápoltam az ESP modult, és teszteléshez volt egy 1 ledes szalagdarabom. A programozás után világított a LED. Rá is mértem gyorsan az USB-m feszültségére, ami 5.01V-ot mutatott. Ha pedig ez első LED megy, akkor mind megy (ezt használta volna ki a második opció). Felettébb furcsa, de jó, hogy így alakult, főleg egy későbbi pont kapcsán.

Tápegység

Itt a legfontosabb az áramigény kielégítése, főleg, mert a komponensek a szokásosnál is zordabbul állnak a leeső feszültséghez, amit egy gyenge táp okozhat.
Ugyebár nem hagyományos LED-ekről beszélünk, így ha a tápfeszültség lejjebb esik, nem szimplán elhalványodik a fény, hanem a chipek belső kontrollere újraindul. Ezt nem próbáltam ki, de az adatlapból már említett 3.5V minimális tápfeszültség környékén történhet.
Itt egy újabb pluszpontját élvezhetjük a 3.3V-os vezérlésnek: Egy 5 voltos mikrokontroller szűk keresztmetszet ilyen téren, ha közös tápegységet használ a LED-ekkel. Ott vannak például az 5V-ra belőtt 16MHz-es Arduinok, amik ~3.8V minimum feszültséggel operálnak, így hamarabb kiesnek mint a LED-ek.

No persze semmiképp se célunk a tápegységnek azt az üzemállapotát használni, amikor már áramkorlátba futunk, mégis nagyon sok leírásban méretezik alul a tápegységeket a boblighthoz.

Adatlap szerint ugyanis a LED-ek 60mA-t vesznek fel amikor mindhárom színkomponens maximum fényerőn van, a projekt leírásokban azonban rendszeresen 20mA-t számolnak pixelenként.
- Ennek egyik oka lehet, hogy ritka, hogy egy filmben huzamosabb ideig full fehér fény van a képen - ezáltal kihajtva az összes LED-et.
- Egy másik oka lehet, (persze ez csak tipp) hogy a boblightban beépített korlát van a maximum fényerőre. Például amikor telibe kellene fehérrel világítani a hátteret, akkor nem 100%-os fényerős fehérrel dolgozik, hanem teszemazt 50-el. Itt egy kis előretekintésként megjegyzem, hogy nálam lesz egy hasonló dolog, de nem tápellátás megfontolásból, és azért gondolom, hogy más rendszerekben is van ilyen, mert ha én rájöttem, valószínűleg már más is rájött :)) .

Lényeg a lényeg, én semmiképp nem akartam, hogy ezen bukjon a dolog. Kiszámoltam, hogy nagyjából 256pixelt fogok elhelyezni (ez végül 244-lett) ami 15A körüli igényt mutat. Ehhez a legközelebbi egy 20A-es tápegység volt a fiókomból.

Ez a rengeteg amper viszont nem játék, főleg eldugva a TV mögé, így szerettem volna valamilyen védelmet.
Szintén itthoni készletből előkerítettem egy regenerálódó biztosítékot ami Ih = 6A-ig szabadon használható, és It = 12A-nél biztosan megszakít. Szerettem volna inkább egy 9A-18A paraméterűt, de olyan nem volt. Sebaj, legalább meglátjuk mi történik ezekkel a korlátokkal. Mivel a regenerálódó biztosítékok viszonylag lassúak (az itthon talált példánynak 20A mellett 10s kell a szakításig) ezért beiktattam egy gyors 15A-es olvadóbiztosítékot is.
Kicsit előreugorva: A tapasztalatok alapján a regenerálódó biztit jóval lejjebb lehet méretezni. Egy 3A-6A értékűben gondolkodom, ez az ami a legjobban megfelel az én 244 pixeles rendszerem karakterisztikájának: Ez 20A-t 2 másodperc után szakít, 10A-t majd' 30 másodpercig megenged, 6A-t pedig 15 percig.
Hogy ez hogy jött ki, azt később részletezem majd.

Kapcsolás

Itt csak pár apró dologra térek ki.
Egyrészt arra, hogy a LED szalag adatbemeneti pinje elé minél közelebbi elhelyezésre javasolnak egy 330Ohm körüli ellenállást. Ennek főleg hosszú kábeleknél van jelentősége a jelreflexió miatt.
Az Arduino fórumon osztotta meg valaki a méréseit ezzel kapcsolatban:

Jól látni, hogy nemcsak hogy lengést okoz a jelenség, hanem jelentős túllövést is.
A lengés miatt a jelszint magas értékre váltáskor többször visszaesik, pár alkalommal akár a feszültség 70 százalékára, amit már fentebb kitárgyaltunk.
A túllövés pedig hosszútávon károsítja a LED belső vezérlőjét, és szépen lassan tönkreteszi azt. Ne felejtsük el, az adatlap szerint 0.5V-al lehet túllépni a jelbemenet feszültségével a tápfeszültséget, és -0.5V (tehát fordított polaritással 0.5V maximum) a minimum feszültség. A képen 5V-os jelszintek vannak, és a túllövés bőven meghaladja a 10%-ot (0.5V) mind pozitív, mind negatív irányba.

Na de mi van a 3V3-al? Nos, kiderül. Egyrészt nekem nincs 12inch (30cm) jelkábelem, csupán annak a tizede. A legrosszabb esetben az első pixelt fogom megölni hosszú távon, ennyit hajlandó vagyok áldozni a kísérletezés oltárán. Másfelől attól tartottam, hogy ha beiktatom az ellenállást, akkor végetvetek a mágikus működésnek az alacsonyabb jelszintemmel. Harmadrészt pedig csak SMD ellenállást találtam 330Ohm körül, és nem akartam vele bajlódni. Ha találok egy 330R THT ellenállást 5 perc alatt - ennyit szántam a keresésre - akkor lehet, hogy beiktatom a vezetékbe.

A másik dolog, hogy a kondenzátorokkal nem érdemes spórolni. Na ebből találtam eleget :DDD .
Egyrészről az ESP is igényli, gyakorlatilag wdt resetbe vágta magát az összes ESP8266 modulom valaha, amikor elkezdtek wifi-re csatlakozni, és adatot burstölni rajta.
Másfelől, főleg ha a LED szalag hosszú, akkor az összeillesztéseknél is érdemes beilleszteni egy-egy elektrolit kondenzátort. Ennek legegyszerűbb módja, hogy a sarkokon, ahol kábellel van megtörve a szalag szöge, ott a kábelekre hasonló módon teszünk kondenzátort (sajnos a sajátomról nem csináltam fotót):

Én ezeket megtévesztő módon parazita-kondenzátoroknak hívom*, és általában egy harmadik zsugorcsővel még a kábelhez is húzom az egész testét befedve és védve.
*annak ellenére, hogy a parazita általában negatív töltetű, és a teljesen más jelentésű parazita-kapacitásra utalnak

Vezetékvastagság

A tápellátásnál már tárgyaltunk amperokat, és aki látott már ilyen LED szalagot, az lehet, hogy vakargatta is a fejét. Ezeknek a szalagoknak van egy standard csatlakozója, amiben GND-DATA-5V vonalak vannak, és az enyémeken van még egy érpár, kiegészítőleg a tápfeszültségnek. Nos, én mind a két vonalon keresztül támogatom a szalagot feszültséggel. Az érpár ugyanis olyan AWG22 forma, amit 3A-ig ajánlanak - 1M szalag - avagy 60 LED - viszont 3,6A önmagában. Nekem viszont van 244 ami ~4M szalag.
Az összekötést egészen egyszerűen úgy oldottam meg, hogy a sarokban, ahol körbeér a szalag, két irányba indítottam el a tápfeszültséget, és nem körbevittem. Illetve még egy nagyon fontos dolog: Nem csináltam zárt hurkot egy magas frekvencián változó nagyságú, viszonylag nagy áramot szállító vezetőből a TV mindenféle egyéb érzékeny kábelei köré. Így lett cca. 2-2 méterem (122-122 LED) amiket 2-2 érpárral tápláltam. Az összekötési pontokig pedig 2x1,5mm2-es hangszórókábellel mentem a tápegységtől (amire már jobban rá merem bízni azt a 15 ampert, amit az olvadóbizti még elenget).

A gyengébb idegzetűeket kérem, hogy csak saját felelősségre görgessenek tovább. Némi igénytelen Paint illusztráció következik:

Itt látszik minden: A kihagyott ellenállás, a tápfeszültség elvezetése, a csatlakozók, a beiktatott kondenzátorok, a vezetékek jelképes keresztmetszet különbségei, és még egy apróság...

Ja, igen, azt elfelejtettem leírni: A szokásossal ellentétben nem egy szalaggal indultam körbe, hanem egyel felfelé körbe, és egyel az alsó élen. Ennek az a megfontolás állt a hátterében, hogy kipróbáljam, van e értelme párhuzamosítani a szalagokat, gyorsít e bármit a frissítési gyorsaságon. Ugyebár ezeknek a LED-eknek a protokolljában az egyetlen adat vezetéken szaladó jelszinteknek különböző kitartási idői adják a kommunikáció alapját. Emiatt 1 pixel feltöltése T idő, N pixelé NxT. Na de már most, miért ne tölthetnék egy másik sor pixelt, amíg az első soromon az adatvonal éppen a kötelező jelszintidejét tölti?
Nos, technikailag lehetséges, gyakorlatilag ekkora méretben szükségtelen.
1 bit átvitele 1,25 mikroszekundum - az adatvonalon 0.4us HIGH+0.85 LOW = 0 vagy 0.8us HIGH + 0.45us LOW = 1. Egy szín 8 bit -> Egy pixel 3 szín -> 8x3x1,25us = 30us. 244LED esetén ez 7,32ms azaz 136 minta másodpercenként. Ebből csinálna a párhuzamosítás többet. Hát, ugye, hogy fölösleges?

Az ESP8266 programozása

Bár már elég sok ESP8266-ot programoztam és építettem bele mindenféle kütyübe, valamiért még csak most érdekelt igazán az OTA (Over The Air) frissítés használata.
Hát uram atyám! Ahol csak lehet ezt fogom használni. Egyszerűen leírhatatlan a kényelem a vezetékes programozáshoz képest. Ezt a leírást használtam. Annyi módosítást végeztem, hogy azonnal beüzemeltem egy UDP servert rajta, és nem hagytam csupaszon a Loop-ban a ArduinoOTA.handle(); függvényt, hanem elraktam egy olyan case alá, amikor egy bizonyos üzenetet küldök UDP-n az eszköznek.

Odafigyelést igényel, ha van aktív tűzfal a gépen - engem vagy 40 percig szívatott, mire rájöttem a gondra. Az ArduinoIDE valószínűleg valamilyen portscanre hasonlító tevékenységet végez, amikor felderíti a hálózaton az OTA képes eszközöket, és ezt nem vette jónéven a tűzfalam.

Amint meggyőződtem róla, hogy a hardver működik, fogtam, és be is raktam a TV mögé a végleges helyére, és indult a programozás. Ez azért volt fontos, mert minden feltöltés után a valós környezeten tudtam tesztelni.

A kód jelenleg iszonyat puritán. A már említett UDP szerver kezeli az üzeneteket. Az első két byte utasításokat tartalmaz, amik a következőek:
- Ha az első két byte (16bites előjel nélküli szám) nem haladja meg a pixelek számát, akkor a jelentése egy úgynevezett "binning" érték. A binning azt mutatja meg, hogy a következő 3-3byteok hány pixel RGB értékét fogják tartalmazni. Binning=1 esetén a következő 3byte alapján a következő pixelt állítja be, és a következő 3 alapján a következő 1 pixelt. Binning=5 esetén a következő 3byteok 5pixeles csoportokra alkalmazhatóak. Binning=244 esetén a következő 3byte mind a 244 pixelre ugyanazt a színt helyezi ki. Ez a beállítás az adatátviteli sebességgel kapcsolatos szkepticizmusom miatt volt. Felkészítettem a rendszert arra, hogy a "felbontását" rontani lehessen kisebb hálózati csomagok küldése érdekében. Az én 244 pixelemhez 732byte+overhead mozgatására van szükség, az ESP UDP puffere viszont 512byte, amiből ugyan tud többet kezelni és láncolni, de ezek a trükkök már időigényes szoftveres mutatványok a motorháztető alatt. Meg akartam tehát teremteni a lehetőséget, hogy akár csak felezzem a felbontást, és minden 2 egymás melletti pixel azonos színt kapjon - esetleg minden köztes pixel interpolálódjon.
Erre sem volt szükségem végül.
- Ha az első két byte értéke 0x5050 akkor programozói módba lép a modul, és várja a kódfeltöltést 30másodpercig - eközben animációt játszik a LED-eken.
- További eseteket különböző beépített animációk meghívására használok - ilyenek: tűzlobogás effekt, kapucsengő vizualizáció, fake-tv-szimulátor, Eglo állítható fényerejű és színhőmérsékletű mennyezeti lámpa beállításainak lekövetése, betörővakító stroboszkóp éjszakai riasztás esetén, és még amik majd eszembe jutnak.

A kliensoldal programozása

Amennyire egyszerű a kód a mikrokontrolleren, itt akkora a bonyodalom. De jól van ez így. Ambilight módban szerettem volna, ha a PC végez minden matekot, hogy a lokális kontrollernek mindenféle utófeldolgozás nélkül csak ki kelljen tolnia a LED-ekre az adatot. Ugyanis egy dolog az átviteli sebesség, egy másik késleltetés. Képzeljük el ugyanis, hogy megy egy film, vagy egy játék 40-60FPS-el, és nekünk
- Be kell rántanunk a képkockát memóriába
- Ki kell találni, hogy az a képkocka milyen ambiens fényt indikál az adott pozíciókban
- El kell küldeni a lokális vezérlőre
- Ott meg kell érkezni az adatnak, és ki kell zavarni a LED-ekre
És mindezt úgy, hogy már jön a következő képkocka, ami lehet, hogy teljesen eltérő.

Lecsökkentendő az utómunkát, és figyelembe véve a tényt, hogy a PC mindenféle számolás terén jobb, mint az ESP, mindenképpen itt kell a munkát elvégezni.

Most pedig jöjjön egy pár Screenshot az applikációról, mert úgy könnyebb mihez kötnöm az egyes funkciókat.

Ez az, amit a használandó terület előnézeteként látok. A kép a Graphics.CopyFromScreen metódus eredménye. Kiválasztható, hogy melyik monitorra ugorjon alapból.
Az alatta lévő numericUpDown egy szépséghiba: Jelenleg nem találtam jó módot arra, hogy a Windowsban beállított alapnagyítást korrekciózzam. Esetemben a 4K-s kijelző 300x nagyításra van téve, ezért a .Net függvények 4K/3 felbontású grafikaként kezelik a kép tartalmát, akkor is, ha valójában nem az. Ezért jelenleg kézzel adom meg a nagyítási paramétert.
Alatta a 4-es csoportban X-Y pozíció-, illetve méretoffszeteket tudok megadni. Ezzel például kiküszöbölhető a keskenyvásznú, vagy 4:3 képarányú tartalmak fekete pereme, vagy a vertikális mobilvideók megjelenése.
Az alatta lévő hármas csoport a függőleges és vízszintes ambiens pixelek számát határozza meg, illetőleg azt, hogy milyen mélyen a középpont felé legyenek figyelembe véve a pixelek. A 100-as érték azt jelenti, hogy a peremen kiadódó mérettel megegyező a másik irányú kiterjedése, tehát négyzetek vannak szubpixellé tömörítve. Ezekből az ambiens pixelszámokból, és a felbontásból nem adódik szükségszerűen egész szám, ezért úgy járom körbe a képet, hogy minden osztási veszteséget lefedjek. A bal sáv tehát pontosan a bal alsó sarokból indul, és így a bal felsőből maradnak ki az osztási maradékkal járó pixelek. A felső sáv viszont a bal felső sarokból indul, így a jobb felsőben veszítek infót, amit pótol az onnan induló jobb sáv, és így körbe.
Valós működés közben nem a teljes képet használom, csupán az előzőekben meghatározott sávokat. Így sokkal kevesebb számítást igényel a feladat, és egyszerűbben is megoldható. A következő kép után el is magyarázom, mi történik.

Amennyiben a legördülő menün kiválasztom a Top (azaz felső) élet, az előnézet csak azt a sávot mutatja, amit felsőként mentünk.
Ez szélesség tekintetében: A teljes kép pixelei, minusz a vertikális ambiens pixelek számával végzett osztás maradéka. Ha például 1920pixel a kép, és 100 ambiens pixel van, akkor ez 1900 széles kép lesz, és a fentiek alapján a jobb oldaláról fog hiányozni a 20 pixel.
Magasság tekintetében: Mivel egy szegmens 1900/100=19 pixel. Ennek vesszük a beállításban jelzett százalékát (ami most 100) ezért 19pixel magas lesz.

Azzal, hogy csak ezt a képet veszem ki, amellett, hogy memóriát és időt spórolok a beolvasással, megteremtem azt a lehetőséget, hogy elkészítsem a kivetítendő 100x1 pixeles színsort: Az 1900x19-es képet egyszerűen a new Bitmap(Image original, int width, int height) overloaddal 100x1-re méretezem át. Ez az átméretezés kiválóan elvégzi a matekot, hogy hogyan vegye a szegmensből a legjellemzőbb színt és intenzitást. Ezt látni akkor, ha bekapcsoljuk a "Show processed" opciót:

Itt már homogén pixeleket látni - kissé megnyújtva, hogy azért mégis lehessen őket látni, és ne 1-1pixelek legyenek.
Közben pedig, ha valamelyik pixel RGB értéke kimondottan érdekel, a legalsó numericUpDown segítségével illusztrálni és mellé kiírni is tudom.
Ezt az opciót akkor tettem be, amikor az első tesztfutásoknál furcsaságokat láttam. Szinte egészen sötét képek esetén is derengő kék fényeket láttam, néha pedig közepesen fényes hátterek mellett is erősebb és így másnak ható színeket láttam. Azt hittem bug van a rendszerben, de igazából elvi hiba volt, és itt újabb fontos, keveset emlegetett tapasztalatra tettem szert: A WS2812B LED-ek R,G,B értékei félrevezetőek. RGB-nek RGB kódolású. 24 bitesnek 24 bites. De az adott kódok nem a megjelenítendő szín RGB értékei, hanem rendre az R,G,B beépített LED-ek PWM kitöltései. Az meg nagyon nem az az RGB, mint amit a TV vagy a monitor mutat. Elég egy ilyen pixelre tetszőleges kicsi értéket kiküldeni: 0,0,1 esetén például a monitoron jószerével semmi különbséget nem látunk a feketétől, a LED azonban erre a parancsra szép kéken pilácsol. Homályos, gyenge, de egy egyértelmű kék szín.
Ennek a hatásnak az elnyomására szolgál a GammaX és GammaC táblázat. A GammaC-vel konstans értékkel tudjuk csökkenteni az RGB értékeket, amik a monitorról a LED-ekre mennek. Ezzel gyakorlatilag fényerő is csökkenthető konstans értékben. A GammaX értéke azt mutatja meg, hogy a maximumnál gyengébb szaturációkat mennyire büntetem. Ez annyit takar, hogy a maximumtól való eltérést a GammaX arányával növelem. Tehát ha az egyik szín intenzitása 235 a monitoron, a GammaX értéke pedig 1, akkor a neki megfelelő LED-re 205 értéket küldök (235 - (255-235)*GammaX). Tehát minél nagyobb a GammaX, annál világosabbnak kell lenni egy színnek, hogy az kijusson a TV mögé. Ezzel megakadályozhatom, hogy sötétebb, de nem fekete éleknél pilácsoljon bármi is, ugyanakkor erősebb effekteknél megmarad a LED-ek magas fénye.
Aki még emlékszik, említettem, hogy végeredményben jóval kisebb áramigény lépett fel, és jeleztem azt is, hogy csökkenteni fogok a fényerőn, de nem spórolás céllal. Ellenkezőleg, így igazán élvezhetővé válik az eredmény, mert ha mindig világít valami a háttérben, akkor az impulzív effekteknek nincs akkora súlya. Plusz amikor egy sötét környezet van a filmben/játékban, annak célja van, és ilyenkor kizökkentő a TV mögül érkező indokolatlan fény.
A többi beállítás a kommunikációért illetve az időzítésért felel. Az alkalmazás könnyűszerrel fut 20ms-es ciklussal - ami 50FPS-t tud kiszolgálni. Megy lejjebb is, de változást már szemmel nem látok. Tervben van, hogy berakok egy vibráló fekete-fehér képet, és GoProval 240FPS-el rákamerázok, hogy lássam, mi az a frekvencia amit tudok követni, mennyi a késés, stb. De ez persze csak tudományos célt szolgál, ugyanis az eredmény igazán élvezhető így is.
Megjelenik a képen a BoblightStramRead gomb is. Nos, talán sejthető mire szolgál: A bobligh szolgáltatás ugyebár soros kapcsolaton utasítja a LED-eket. A com0com segítségével null-modem emulátorral meg tudom tenni, hogy a boblight COM10-re beszél, én meg az alkalmazással olvasom a másik oldalát a COM11-et, majd proxyzom az UDP-re az adatokat. Ezt azért csináltam, ha esetleg egyszer kipróbálnám a boblightot.

A körbejárás végéhez közeledve a tesztvideó előtt egy dolgot kell lezárnom: Miből jött ki a fogyasztási karakterisztika? Nos, a SendSUM engedélyezésével fogom az összes kiküldött LED byte összegét, és kiküldöm a COM11-re, aminek a másik oldalát, a COM10-et figyelem putty-al, és elmentem a terminál logot. Ezzel a módszerrel - minden más funkciót kikapcsolva - lecsökkentettem a ciklust 1ms-re, és lejátszottam pár filmet 20x sebességgel. Ezután megfogtam az eredményeket, betöltöttem excelbe, és kikerestem az összes filmből adódó legintenzívebb 10másodpercet, 30másodpercet, meg még pár jellegzetes idő integrálját. A beállított gamma értékekkel a legintenzívebb 10 másodperces integrál ezen az ablakon belül van:

Persze vannak ennél jóval nagyobb peakek, de azok rövidebb ideig tartanak. Átlagban ez a trend a jellemző, amikor esemény van 3A körül ugrál a terhelés, kicsit fölé, kicsit alá.

... és akkor a megérdemelt demo videó a kitartó olvasóknak:

Itt még nincs korrekció (gamma) a pixeleken, lehet is látni, hogy mi a zavaró benne.

A következő dolog, amit megcsinálok a rendszerhez, az egy teljesen független, de ugyancsak vezeték nélküli rendszer lesz, közvetlenül a tápegység után: A feladata az lesz, hogy méri az áramot a tápegység vezetékén, miközben kapja az üzeneteket (valószínűleg UDP-n és nem a mostani Serialon) összeveti a valós fogyasztást a tervezettel - így amennyiben rendellenességet tapasztal, jelezni, vagy akár egy relével közbelépni is tud. Ez azért is jó lesz, mert jelenleg egy Sonoff basic-et "pocsékolok" a táp ki-be kapcsolására, amikor nem használom.

Hozzászólások

(#1) DanielLong


DanielLong
senior tag

Hasznos és részletes írás lett! Már régóta tervezem, hogy egyszer összehozom a Boblightot, de ez a megoldás azért így jóval menőbb és van is ESP32 a fiókomban. Külön öröm, hogy kitértél a LED-ek vs. TV RGB problémára, mert ezen már gondolkoztam korábban is, így akkor megvan a megoldás.

A késleltetésre mondjuk kíváncsi lennék, de nem hiszem, hogy számottevő volna, főleg, hogy egy átlagos 60Hz-es kijelzőnek is van vagy 15ms válaszideje.

A LED színeinek számításához esetleg nem lenne egyszerűbb, ha a kezdeti 4K képet átméreteznéd rögtön mondjuk 100x50-re, amit aztán a tartalom képarányának megfelelően croppolsz és utána csak kiolvasod az első és utolsó sort/oszlopot? Annyira nem vagyok képben a képfeldolgozás számítási igényével, így lehet, hogy felesleges optimalizálni...

Amúgy mi ismerjük egymást az egyetemről, KTK 834 HD :)

(#2) razorbenke92 válasza DanielLong (#1) üzenetére


razorbenke92
senior tag

Igen-igen, megismertelek a másik topic alatt már :D

ha a kezdeti 4K képet átméreteznéd rögtön mondjuk 100x50-re

Az első nekifutás így nézett ki, ahogyan leírtad. A sebességgel nem is volt baj, viszont jelentősen pörgette a processzort, amire igazából a laptop felbőgő ventije hívta fel a figyelmem.

Némi debug után megtaláltam, hogy az átméretezés ilyen számításigényes, és a terhelés együtt nő a képmérettel. Ezért hatékonyabb még külön-külön egymás után 4 kisebb képet egyenként átméretezni, mert a középső - jelentős méretű - területet nem kell feldolgozni.

Persze a legmenőbb lenne ezt a részt kiszervezni a GPU-ra, mert annak ezek a műveletek szerintem meg sem kottyannának.

[ Szerkesztve ]

Mások számára a kondi fáradós, nekem farad-os...

További hozzászólások megtekintése...
Copyright © 2000-2022 PROHARDVER Informatikai Kft.