Ez a cikk a Ledes SEM logóról szól, annak megépítéséről és szoftver fejlesztésének folyamatáról. A cikkben szó lesz a hardware elkészítésétől a szoftverig a fontosabb design döntésekről.
A fizikai vázat Fusion 360-ban terveztem. Alapanyagként összeragasztottam két MDF lapot, majd a generált G kód alapján a Mach 3 kimarta a fő lapot. A talprészt később martam ki. A hátlapon kialakított vájatokba helyzetük el a LED szalagokat. Az “M” betűbe címezhető RGB szalagot, a többi karakter helyére egyszínű fehér szalagot. A vájatot viasszal öntöttük ki, ezzel elfedve a vezetékezést.
A logó ledszalagainak vezérlését egy SEMduinoval oldottuk meg, amelyre a kiegészítő áramkört egy sajátkészítésű shield formájában tettünk. (Aki esetleg nem tudná, shieldnek nevezzük az arduino jellegű fejlesztőpanelekre tüskesorral rögzíthető paneleket). Az áramkör rendkívül egyszerű, 3 kapcsoló tranzisztort, és két táphidegítő kondenzátort tartalmaz.
Az áramkör megtervezését itt nem részletezem, csak a NYÁK CNC-vel történő gyártását, ennek a lépéseit. Az áramkör gerber file-jait előállítottam, majd ezek közül a réz réteget (tipikusan GTL) megnyitottam FlatCAM-mel. (http://flatcam.org)
Megnyitjuk FlatCAM-ben a gerbert, majd kiválasztjuk a project menünől, és átváltunk a “Selected” fülre. Itt az Isolation Routing rész beállításait megadjuk, és a Generate Gemoetry-re kattintunk.
Ezután a project menüben kiválasztjuk a most generált alakzatot, és ismét a “Selected” fülre navigálunk. Itt a “Create CNC Job” részen válasszuk ki a megfelelő beállításokat és kattintsunk a “Generate”-re. Ezzel lényegében elkészült a marási útvonal, ahol majd a gravírtűvel eltávolítjuk a rezet a NYÁK-ról. Ezután azonban a g-code előállításához mégegyszer látogassunk el a project menübe, és itt a generált CNC Job-ot válasszuk ki, és a “Selected” menüből válasszuk ki a g-code exportálását.
Ezek után az elkészült g-code-ot átvittem Mach3-ba, illetve lefogtam egy kezdetleges vákuum lefogóval egy kisebb NYÁK darabot.
A marás után az elkészült NYÁK-ot beültettem, majd méretre vágtam a vezetékezést. Egyetlen módosításként még a SEMduino lineáris tápjára szereltem még egy tákolt hűtőbordát, mivel a címezhető ledszalag az általa előállított 5V-ot használta.
A 3D terveket, a shieldet tervezte és építette, illetve a cikkrészletet írta Sárközy Balázs.
Ebben a részben a szoftverről szeretnék egy kicsit részletesebben írni. Egy ATMEGA8-as mikroprocesszorral van ellátva a rendszer. A forráskód eredetileg egy c kód, ami később le lett fordítva gépi kódra (hex). A kód két főbb részre osztható PWM-es vezérlés és egyszerű Bit Banging. A processzor mindhárom PWM modulja kihasználásra kerül 8 bites módban. PWM-el az S, E és a pont van meghajtva. Az M betűnél pedig egy címezhető ledszalag (WS2811) található. A futását a programnak két főbb részre lehet szedni: Startup és Working állapot. A Startup módban inicializálja a PWM modult,beállítja a különböző GPIO lábak irányát, értékét és elindítja a kijelzést. Indítás után sorban az S, E és M betűk végül a pont indul be. Az S, E és a pont az PWM vezérlés segítségével nulla fényerőről fényesedik maximumig. Az M betűnél sorban egyesével kivilágítanak a ledek maximális fényerőre. Végül a pont is kivilágosodik. Ekkor elindul a Working állapota a programnak amikor az S és E betűk egyenlő kitöltési tényezőjű 8 bites PWM jelet kapnak, tehát egyenlően pulzálnak, a pont egy másik kitöltésű PWM jelet kap aminél nem egyezik meg a kitöltési tényező az S és E betűk kitöltési tényezőjével, ezért ez egy másik módon pulzál. Az M betűn pedig egy csóva fut végig, a címezhető ledsor alapállapotban egy megadott háttér világítással rendelkezik. A program elején egy define-t változtatva a csóva hossza változtatható. A csóva esetén a “fej” azaz a csóva eleje a legfényesebb ( majdnem maximum fényerő ) míg a további részei nemlineárisan kiseb fényerejűek. A kígyó létrehozása egy egyszerű for ciklus segítségével elérhető. A főbb algoritmus ami a kígyót szolgálja ki a következő.
for(i =0;i<NUM_OF_LEDS;i++) { setse(i); // betűk point(i); // pont vilagitasa for(k =1;k<csova;k++) { div = 2; tmp= max/div; max = tmp
Az előző programrészlet a program magja, ez fut a végtelenségig, egy while(1) miatt. Egy for ciklus adja meg, hogy megcímezze az összes ledet a címezhető ledstrip-en, meghívja az setse függvényt ami beállítja az S és E betűk fényerejét az i függvényében ( hol tart a csóva ). És meghívja a point függvényt ami pedig a pont fényerejét változtatja ( ezekről a függvényekről később részletesebben lesz írva ). Egy másik for ciklus meg beállítja a csóvát, mindig csóva hosszú lednek ( annyi db-nak ) megváltoztatja a fényerejét ( a szín konstans zöld) a háttértől erősebbre, és a for ciklus végén pedig bit bang-el elküldi a címezhető ledsornak az rgb tömböt a WS2811 makró segítségével ( ezek a makrók egy külön header fájlban vannak definiálva).
void setse(uint8_t i) // az S és E betűket beállító függvény { if(i==0) { OCR2 = 255; // változtatja a TIMER 2 és TIMER1B PWM moduljának kimenetén megjelenő PWM jel kitöltési tényezőjét OCR1B = 255;// i függvényében(duty cycle) } if(i<= 24) { OCR2 -= 7; OCR1B -= 7; } if(i>24 && i<=49) if(OCR2+2 <= 255 && OCR1B+2<=255) { OCR2 += 7; OCR1B += 7; } } void point(uint8_t i) { if(i ==0) OCR1A = 255;// változtatja a TIMER1A PWM moduljának kitöltési tényezőjét else if (i>0 && i<= 40) OCR1A = OCR1A -3; else if(i>40 && i<= 49 && OCR1A+19<=255) OCR1A = OCR1A +19; }
A fent lévő függvények a setse és point függvények, ezek végzik el az S és E és a pont fényerejének beállítását.Érdemes megfigyelni, hogy az i függvényében, tehát ahol a csóva feje jár állítja be a kitöltési tényezőt, tehát változtatja a fényerejét a pontoknak.
A program minden harmadik teljes ciklus után, tehát amikor a kígyó végig ért akkor kikapcsolja az összes PWM modult (nullára állítja a kitöltési tényezőt) és lekapcsolja a címezhető ledstrip-et is.
Ezt a kikapcs() függvénnyel éri el.
void kikapcs(void) { uint8_t j=0,i=0; for(j=0;j<27;j++) // folyamatosan fog elhalványulni. { if (OCR1A<11) OCR1A=0; else OCR1A=OCR1A-10; if (OCR1B<11) OCR1B=0; else OCR1B=OCR1B-10; if (OCR2<11) OCR2=0; else OCR2=OCR2-10; if (rgb[0].g < 11) for (i=0;i<NUM_OF_LEDS;i++) rgb[i].g=0; else for (i=0;i<NUM_OF_LEDS;i++) rgb[i].g=rgb[i].g-1; WS2811RGB(rgb, ARRAYLEN(rgb)); delayms20(); // külön függvény ami egyszerűen csak egy 20 ms-os késleltetést tartalmaz delayms20(); } }
Minden új ciklus elején(amikor vége a teljes hármas ciklusnak) meghívódik a startup függvény ami egyesével jeleníti meg a betűket. Először az S, E, M majd végül a pont jelenik meg. Az M betű különleges ebben is, mivel azon egy fény fut végig ami maximális fényerőre állítja az egyes ledeket ideiglenesen(csak a beindulás idejére).
void startup() { uint8_t k =0; for( k= 0 ;k<30;k++) // S betű { OCR1B += 1; _delay_ms(5); } for(k = 0;k<30;k++) // E betű { OCR2 += 1; _delay_ms(5); } uint8_t l = 0; for(l =0;l<NUM_OF_LEDS;l++) // M betű { rgb[l].g = 255; WS2811RGB(rgb, ARRAYLEN(rgb)); _delay_ms(15); } _delay_ms(1000); OCR1A = 0xFF; // Pont }
A szoftvert és a hozzá kapcsolódó cikkrészletet írta és tervezte Juhász Balázs.