Ukázkový projekt do MMIA: LED CUBE 8x8x8

Autoři: Petr Lecián, Ivan Macháček
Garant předmětu: Zbyněk Fedra UREL, FEEC, VUT Brno fedrazfeec.vutbr.cz

Obsah:

  1. Úvod
  2. Realizace
  3. Závěr
  4. Literatura
  5. Ke stažení

Úvod

V projektu byla realizována z LED krychle, jedna strana sestávala z osmi LED, celkem tedy krychle obsahuje 8³ = 512 LED. Pomocí multiplexování vždy osmice LED lze vyrobit jakýkoliv prostorový "obrázek" ze svítících LED. Kostka může být využita pro estetické účely, prezentace, hry (např. 3D Snake), atd.

Realizace

Pro výrobu krychle bylo potřeba celkem 512 LED diod. Z cenových důvodů byly použity červené difuzní (1Kč/ks). Pro buzení dané osmice bylo dále potřeba 72 tranzistorů PNP (typ BC640) a 8 tranzistorů NPN (typ BC338). Principiální zapojení je uvedeno na obr. 1. Pro jednoduchost je zapojení pouze pro část kostky 3x3x3.
LED krychle
Obr. 1: Princip zapojení krychle

     Pomocí portu C se nízkou úrovní napětí vybere jedna řada LED, tedy celkem 64 LED. Dále se pomocí portu B nízkou úrovní aktivuje daná osmice LED. Portem A se vysoukou úrovní spínají konkrétní diody. Proud LED diodou je omezen rezistory 10Ω, které jsou zapojeny v kolektoru NPN tranzistorů v portu A. Proud procházející použitou LED diodou je 50mA. Zapojení umožňuje použít napájení 5VDC. Pro zobrazení obecného obrázku je tedy nutné udělat celkem 8x8 = 64 taktů. Obnovovací frekvence postačuje 60Hz, při které není patrné blikání diod.

     Kostka byla po mechanické stránce vyrobena podle návodu [1], [2] a [3]. Vrstvy byly vyrobeny na překližkové šabloně, jednotlivé vrstvy pak drží pohromadě pomocí plošného spoje a drátků připájených po stranách krychle. Celá krychle je dostatečně tuhá. Plošný spoje bylo nutné realizovat jako oboustranný. Tranzistory byly použity v plastovém pouzdru s drátovými vývody (TO92). Pomocí drátových vývodů byly realizovány i propoje mezi vrstvami DPS. NPN tranzistory byly vybrány BC338, PNP jsou BC640. Propojení s řídicím obvodem je provedeno trojicí plochých kabelů. Podklady pro výrobu lze stáhnout zde.

Náhled DPS
Obr. 2: Provedení desky plošného spoje

     Ovládání kostky je zajištěno mikrokontrolérem AVR Atmel ATMEGA16. Hodinový signál 16MHz je z krystalového oscilátoru. Kostka zabírá celkem 3 porty mikrokontroléru. Pomocí dvojice multiplexorů by bylo možné porty kostky B a C řídit jen jedním portem mikrokontroléru.


Obr. 3: Fotodokumentace (kliknutím na obrázek se otevře v novém okně obrázek ve větším rozlišení)



Programové vybavení se skládá ze 3 částí:
Uložení obrázků do paměti mikrokontroléru
Vzhledem k velikosti obrázků 64B je nutné vše uložit do programové paměti mikroprocesoru, která má v případě ATMEGA16 velikost 16kB. Základním prvkem je vizualizace, což je skupina libovolného počtu po sobě jdoucích obrázků. Obsah jedné vizualizace je uložen v třírozměrném poli Cube1 v programové paměti:
  #define CUBE_ORDER 8 /*Řád krychle*/
  /*Uložení obrázků vizualizace*/
  char Cube1[/*Počet obrázků*/][CUBE_ORDER][CUBE_ORDER] = {...};
     Datový typ char má velikost 8bitů, což pro použitou kostku dostačuje. Každý bit pak slouží pro jednu LED diodu. Pokud je bit nastaven na 1, dioda svítí, pokud je nastaven na 0, dioda nesvítí. Dále k tomuto poli musí existovat další pole Time1, ve kterém jsou uloženy doby trvání jednotlivých obrázku. Obrázek pak zůstane vidět po dobu určenou jako násobek doby trvání obnovovací periody F_REFRESH.
  /*Uložení dob trvání jednotlivých obrázků*/
  char Time1[/*Počet obrázků*/] = {...};
     Aby bylo možné k těmto polím snadno přistupovat, bylo vytvořeno ještě jedno pole Data, které obsahuje počty obrázků ve vizualizacích, dále adresu prvního prvku pole s obrázky a adresu prvního prvku pole s časy. Délka adresy je 2B, je tedy nutné použit 16-ti bitový typ integer (u překladače AVR-GCC).
  #define NUM_COUNT 5   /*Počet úvodních vizualizací (číslic, ...)*/
  #define VIZ_COUNT 4   /*Počet skutečných vizualizací*/
  
  /*Pole s ukazateli na jednotlivé vizualizace*/
  const int Data[NUM_COUNT + VIZ_COUNT][3] = {
    {1,  (int) &sCube1[0][0][0], (int) &sTime1[0]}, /*Zobrazení číslice jedna*/
    {1,  (int) &sCube2[0][0][0], (int) &sTime2[0]}, /*Zobrazení číslice dva*/
    {1,  (int) &sCube3[0][0][0], (int) &sTime3[0]}, /*Zobrazení číslice tři*/
    {1,  (int) &sCube4[0][0][0], (int) &sTime4[0]}, /*Zobrazení číslice čtyři*/
    {1,  (int) &sCube5[0][0][0], (int) &sTime5[0]}, /*Zobrazení číslice pět*/
    
    {65, (int) &Cube1[0][0][0], (int) &Time1[0]}, /*Vizualizace 1: Skládání kostek*/
    {24, (int) &Cube2[0][0][0], (int) &Time2[0]}, /*Vizualizace 2: Pohybující se kostky*/
    {8,  (int) &Cube3[0][0][0], (int) &Time3[0]}, /*Vizualizace 3: Tři čáry*/
    {8,  (int) &Cube4[0][0][0], (int) &Time4[0]}  /*Vizualizace 4: "šachovnice"*/
  };
     V případě přidání/odebrání vizualizace je nutné aktualizovat pole Data. Pokud se změní počet obrázku ve vizualizaci, stačí jen aktualizovat aktualizovat první prvek v poli Data.

8 bitový čítač/časovač 0
Čítač pracuje v režimu CTC (Clear Timer on Compare), využívá se vektor přerušení TIMER0_COMP. Po vyvolání přerušení dojde k nastavení osmice LED. Aktuální pozice osmice LED je určena globálními proměnnými currentX a currentY, které mohou nabývat hodnot 0, 1, 2, ..., 7. V dvourozměrné poli Img o velikosti 8x8 je uložen konkrétní obrázek. Z pole se však vybírají hodnoty pomocí ukazatele *pImg = &Img[0][0]. Mezi změnami výstupních portů jsou vloženy časové prodlevy 10μs pomocí funkcí delay_us(time) [6].

     Protože celkový počet osmic LED je 64 a obnovovací frekvence by měla být minimálně 60Hz, je potřeba nastavit registry čítače/časovače tak, aby k přerušení docházelo s frekvencí 64*60Hz = 3840Hz. Pro dosažení této frekvence byla nastavena předdělička čítače na 256 a následně dopočítána hodnota porovnávacího registru OCR0 podle [4].
  /* definice kmitočtů */
  #define F_OSC 12000000	/*Frekvence hodinovéhu kmitočtu MCU [Hz]*/
  #define F_REFRESH 60    /*Frekvence obnovení obrázku [Hz]*/
  #define REG_OCR0(x)  ((char)((uint32_t)F_OSC/((uint32_t)x*F_REFRESH*CUBE_ORDER*CUBE_ORDER))) /*Registr OCR0*/

  /* definice směru registrů */
  #define KOSTKA_DDR_A DDRC
  #define KOSTKA_DDR_B DDRB
  #define KOSTKA_DDR_C DDRA
  
  /* definice výstupních registrů */
  #define KOSTKA_PORT_A PORTC
  #define KOSTKA_PORT_B PORTB
  #define KOSTKA_PORT_C PORTA
  
  /*Nastavení refistrů čítače/časovače 0*/
  TIMSK |= (1 << OCIE0);
  TCCR0 = (1 << WGM01)|(1<< WGM01)|(1 << CS02)|(0 << CS01)|(0 << CS00);
  OCR0 = REG_OCR0(256);	//256 je hodnota předdělička čítače/časovače 0
  
  /*refresh obrázku*/
  ISR(TIMER0_COMP_vect) {
  	KOSTKA_PORT_A = 0x00;
  	delay_us(10);				//čekej 10us
  	KOSTKA_PORT_B = ~(1 << currentY);
  	delay_us(10);				//čekej 10us
  	KOSTKA_PORT_C = ~(1 << currentX);
  	delay_us(10);				//čekej 10us
  	
  	KOSTKA_PORT_A = Img[currentY][currentX];
  
  /*výběr další osmice LED
  	if (++currentX > 7) {
  		currentX = 0;
  		if (++currentY > 7) {
  			currentY = 0;
  			zmena = 1;
  		}
  	}
  }

     Čítač/časovač 0 rovněž zajišťuje změnu obrázků. Základní perioda je dána (přibližně) hodnotou F_REFRESH. Skutečná doba trvání obrázku je pak dána součinem této periody a délkou trvání jednoho obrázku. Přepínání mezi obrázky je realizovano funkcí void changeImg(char refresh). Funkce se stará o přepis hodnot z programové paměti do globálního pole Img. Protože čas potřebný pro vykonání funkce trvá delší dobu než je prodleva mezi přerušeními čítače/časovače 0, je nutné ji volat z hlavní funkce int main(void) (když není mikroprocesor v obsluze přerušení). Proto byla přidána proměnná zmena. Pokud je její hodnota různá od 0, dojde k zavolání funkce changeImg(0). V případě, že by se funkce void changeImg(char refresh volala v přerušení docházelo by k problikávání určitých LED diod. Pokud je parametr refresh) různý od 0, dojde vždy k přepsání pole Img.
  /*Změna obrázku*/
  void changeImg(char refresh) {
  	char i;
  	char *pImg = &Img[0][0];
  
  	while (1) {
  		if (time == 0 || refresh) {
  			/*nacteni obrazku z Flash do RAM*/
  			time = pgm_read_byte((char*) (Data[currentViz][2] + currentImg));
  			if (time != 0) {
  				for (i = 0; i < 64; i++) {
  					*pImg = pgm_read_byte(Data[currentViz][1] + 64*currentImg + i);
  					pImg++;
  				}
  			}
  			if (currentImg > Data[currentViz][0] - 2) {
  				currentImg = 0;
  			} else {
  				currentImg++;
  			}
  		}
  		if (time != 0) {
  			time --;
  			return;
  		}
  	}
  }


Ovládání kostky
Kostka je ovládána trojicí tlačítek: Start/Stop, Další (NEXT) a Předchozí (PREV). Tlačítkem Start/Stop se přepíná mezi úvodní vizualizací (např. číslo vizualizace) a skutečnou vizualizací. Tlačítky Další a Předchozí se vybírá příslušná vizualizace. Kontrola stavu tlačítek je zahrnuta do nekonečné smyčky v hlavní části programu. Zákmity kontaktů tlačítek jsou ošetřeny softwarově. Stisknutím tlačítka se změní úroveň napětí na daném pinu z vysoké úrovně na nízkou úroveň.

Závěr

Vytvořená kostka je plně funkční, použitý mikrokontrolér je výkonově zcela postačující, programová paměť umožňuje nahrání asi 200 obrázků. S obnovování obrázku není problém, blikání LED diod není patrné. Bohužel použité LED diody nevynikají vysokou svítivostí a nejsou čiré. Při přímém denním světle je těžko rozeznatelné, zda LED svítí nebo nikoli, za šera je 3D obrázek již dobře vidět. Dalším pokračováním projektu by mohlo být připojení kostky k PC, využití paměti EEPROM pro uložení vlastních animací, jednoduché hry, např. 3D Snake, apod.

Literatura

[1] 5³ LED CUBE Controller : for PIC16F688 [online]. 2009 [cit. 2009-05-10]. Dostupný z WWW: <http://picprojects.org.uk/projects/lc/index.htm>
[2] The 3D LED Cube [online]. 2009 [cit. 2009-05-10]. Dostupný z WWW: <http://www.lomont.org/Projects/LEDCube/LEDCube.php>
[3] bit-tech.net: Help with LED cube wiring [online]. 2009 [cit. 2009-05-10]. Dostupný z WWW: <http://forums.bit-tech.net/showthread.php?t=76578>
[4] Datasheet ATMEGA16 [online]. 2009 [cit. 2009-05-10]. Dostupný z WWW: <http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf>
[5] Manuál AVR-libc-1.6.5 [online]. 2009 [cit. 2009-05-10]. Dostupný z WWW: <http://www.nongnu.org/avr-libc/>
[6] Precise Delay Functions [online]. 2009 [cit. 2009-05-10]. Dostupný z WWW: <http://motivecvs.tux-project.de/cgi-bin/viewcvs.cgi/doc/Source_Bsp/CAN_AVR_TESTPRJ/>
[7] MANN, B. C pro mikrokontroléry. BEN technická literatura, 2003. ISBN 80-7300-077-6

Ke stažení