Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Ricerca personalizzata

Progettazione software per cubo LED 4x4x4

Tipologie, strumenti di sviluppo, hardware e progetti

Moderatori: Foto UtentePaolino, Foto UtenteTardoFreak, Foto Utentec1b8, Foto Utenteposta10100

1
voti

[1] Progettazione software per cubo LED 4x4x4

Messaggioda Foto UtenteGalaxi93 » 15 apr 2009, 16:19

Salve a tutti,
io sono nuovo nel forum (appena iscritto) e quindi, prima di esporre il mio problema, vorrei fare una breve presentazione:
Mi chiamo Davide, ho 16 anni e frequento il liceo scientifico tecnologico, abito in provincia di Milano e ho alcuni hobbies tra cui l’elettronica e l’informatica.


Bene, è da tempo che desidero realizzare un cubo di LED 4x4x4 controllato da un PIC che controlla i vari LED e fa eseguire a loro dei giochi di luce. Per la parte elettronica, ho scelto di non utilizzare un PIC di “grosse dimensioni”, ovvero con molti pin, ma un semplice 16F84 o, in alternativa un 16F648A che ha sempre 18pin. Siccome il cubo per funzionare ha bisogno di 20 ingressi, e i PIC in questione ne hanno solo 13, ho risolto il problema utilizzando un demultiplexer che mi controlla l’asse x e y del cubo, mentre l’asse z è comandato da 4 transistor collegati direttamente alle porte b del PIC. Insieme ad un mio amico, che mi ha aiutato molto, ho realizzato un programma di base per il controllo dei vari LED. Il programma è in C ed è stato scritto con MikroC. Premetto che non sono un esperto in programmazione, ma so qualcosa.
Codice: Seleziona tutto
//Versione finale del firmware da inserire nel PIC che controlla il cubo di LED
// 4x4x4 con demultiplexer.

char x_led, y_led, z_led;                 //Dichiarazione delle coordinate,
char tempo_effetto, tempo, gioco;         //dei tempi e del numero di gioco e
char effetto_4, effetto_8;                //del numero di effetti.
char random_16, random_4;
//Funzione fondamentale che serve ad accendere i LED date le coordinate x, y, z.
void acc_led(char x, char y, char z)
{
if (x==0, y==0, z==0)                //Se sono tutti 0,
{
porta=0x10;                          //Mette alto G1+G2 e
portb=0;                             //spegne tutti i z.
}
else                                 //altrimanti:
{
char valore_demux=y*4+x-5;
porta=valore_demux;                   //accende il LED
switch(z)                             //prende in considerazione la variabile z.
{
case 1:                               //Se è 1
portb=0x01;                           //mette alto la porta RB0.
break;                                //fine primo caso.
case 2:                               //Se è 2
portb=0x02;                           //mette alto la porta RB1.
break;
case 3:                               //Se è 3
portb=0x04;                           //mette alto la porta RB2.
break;
case 4:                               //Se è 4
portb=0x08;                           //mette alto la porta RB3.
break; }
}
}

//Funzione per accendere, uno alla volta, tutti gli assi verticali x.
void piano_vert_x()
{
if (x_led == effetto_4)               //Se y è uguale a effetto,
acc_led(x_led, y_led, z_led);         //accende i LED.
else
acc_led(0, 0, 0);                     //altrimente li spegne.
}
//Funzione per accendere, uno alla volta, tutti gli assi verticali x in senso opposto.
void piano_inv_x()
{
effetto_4=5-effetto_4;
piano_vert_x();
effetto_4=5-effetto_4;
}
//Funzione per accendere, uno alla volta, tutti gli assi verticali y.
void piano_vert_y()
{
if (y_led == effetto_4)               //Se y è uguale a effetto,
acc_led(x_led, y_led, z_led);         //accende i LED.
else
acc_led(0, 0, 0);                     //altrimente li spegne.
}
//Funzione per accendere, uno alla volta, tutti gli assi verticali x in senso opposto.
void piano_inv_y()
{
effetto_4=5-effetto_4;
piano_vert_y();
effetto_4=5-effetto_4;
}
//Funzione per accendere, uno alla volta, tutti gli assi orizzontali.
void piano_oriz()
{
if (z_led == effetto_4)               //Se z è uguale a effetto,
acc_led(x_led, y_led, z_led);         //accende i LED.
else
acc_led(0, 0, 0);                     //altrimente li spegne.
}
//Funzione per accendere, uno alla volta, tutti gli assi verticali x in senso opposto.
void piano_inv_z()
{
effetto_4=5-effetto_4;
piano_oriz();
effetto_4=5-effetto_4;
}

//Funzione per generare un seme di partenza per il rand.
unsigned getseme(void)                //Crea una funzione,
{ return; }                           //che ritorna un numero casuale.
//Genera un numero casuale da 0 a 15 e da 1 a 4.
char random()
{
random_16=rand()% 15;
random_4=random_16/4+1;
return(random_16, random_4);
}
//Funzione per accendere casualmente i LED del piano x e y e li fa scorrere
//verso il basso.
void led_rand(void)
{
random();                              //Richiama la funzione random.
for (z_led=4; z_led>0; --z_led)        //Ciclo che diminuisce z_led finché
{                                      //diventa 1.
  acc_led(x_led,y_led,z_led);
  porta=random_16;                     //Il numero random viene messo su portA.
  delay_ms(100);
  portb=0;
  delay_ms(10); }
porta=0;
}


//Il main principale, dove viene coordinato tutto lo svolgimento del programma e
//quindi dei giochi di luce.
void main(void)
{
porta=0;                              //Porte A a 0.
trisa=0;                              //Porte A impostate su uscite.
portb=0;                              //Porte B a 0.
trisb=0;                              //Porte B impostate su uscite.
srand(getseme());                     //Serve ad dare il seme a rand.
effetto_4=1;                          //Mette 1 ad effetto_4.
while(1)                              //Inizio del primo ciclo infinito
{                                     //incondizionato.
gioco=0;                              //Mette a 0 il numero di gioco.
while(gioco!=6)                       //Inizio del secondo ciclo infinito,
  {                                    //che termina quando gioco==3.
  tempo_effetto =100;                  //Il tempo dell'effetto(200 = 1sec circa).
  for (tempo=1; tempo<tempo_effetto; tempo++) //Questi cicli for servono per
{ for (z_led=1; z_led<5; z_led++)      //far lampeggiare in sequenza tutti i
{ for (y_led=1; y_led<5; y_led++)      //LED in maniera velocissima.
{ for (x_led=1; x_led<5; x_led++)
{
  switch(gioco)                        //Scegli che gioco di luce svolgere.
   {
   case 0:
   piano_vert_x();
   break;
   case 1:
   piano_inv_x();
   break;
   case 2:
   piano_vert_y();
   break;
   case 3:
   piano_inv_y();
   break;
   case 4:
   piano_oriz();
   break;
   case 5:
   piano_inv_z();
   break;
   }}}}
   acc_led(0, 0, 0); }
   effetto_4++;                        //Aumenta effetto_4.
   if (effetto_4==5)                   //Se effetto_4 è uguale a 5,
   { effetto_4=1;                      //lo rimette ad 1 e
   gioco++; }                          //aumenta gioco.
  }
  for(gioco=1; gioco<60; gioco++)      //Ripete led_rand per 60 volte.
  { led_rand(); }
}
}

Questo è il programma di base che per adesso, mi permette di accendere i piani x, y e z uno alla volta e poi mi accende in modalità random dei LED per poi farli “scorrere” in basso.
Il mio problema è realizzare dei giochi di luce. Navigando su google ho trovato un sito dove spiegava come realizzare questo cubo utilizzando un Atmel al posto di un PIC e quindi senza l’uso del demux. Sul sito c’è anche il programma scritto in C e vorrei prendere spunto da quello. Il problema è che non ci capisco un H (diciamo neanche una C :mrgreen: ).
Quindi chiedo a voi, se potete aiutarmi nel “decifrare” il programma e aiutarmi ad adattarlo alle mie esigenze e se è migliorabile il mio di programma.
Questo è il link per scaricare i file del cubo realizzato su quel sito:
http://www.instructables.com/files/orig/FEM/AJUM/FJ1I6COK/FEMAJUMFJ1I6COK.zip


Saluti,
Galaxi93.
Avatar utente
Foto UtenteGalaxi93
2.865 3 7 13
Master
Master
 
Messaggi: 586
Iscritto il: 15 apr 2009, 15:27

0
voti

[2] Re: Progettazione software per cubo LED 4x4x4

Messaggioda Foto Utentec1b8 » 15 apr 2009, 20:52

Ciao, vedrai che qui qualche persona che ti aiuta la trovi sicuramente.
Per curiosità quali di tutti gli effetti previsti dal progetto che hai linkato come esempio vorresti riprodurre?
Fabio
Avatar utente
Foto Utentec1b8
3.350 3 8 13
G.Master EY
G.Master EY
 
Messaggi: 1766
Iscritto il: 15 gen 2009, 14:23

0
voti

[3] Re: Progettazione software per cubo LED 4x4x4

Messaggioda Foto UtenteGalaxi93 » 15 apr 2009, 21:07

Pure qui ti trovo?!?!? Terminator93 non ti dice niente? :D
Volevo avere un po' d'aiuto, visto che, a parte il tuo, nessuno mi ha aiutato molto (non su questo sito).
comunque per gli effetti volevo riprodurne solo alcuni. I principali sono questi: random_filler, boingboing e effect_spiral. Se poi riesco a mettere anche gli altri, meglio ancora!
Galaxi93.

Visita il mio sito!! E' ancora in costruzione, ma anche tu puoi contribuire a farlo crescere e darmi dei consigli per migliorarlo! Dai prova, provare non costa nulla! Vieni!
Avatar utente
Foto UtenteGalaxi93
2.865 3 7 13
Master
Master
 
Messaggi: 586
Iscritto il: 15 apr 2009, 15:27

0
voti

[4] Re: Progettazione software per cubo LED 4x4x4

Messaggioda Foto Utentec1b8 » 15 apr 2009, 21:43

Avevo capito chi eri :D
Ti assicuro che questo forum è molto, molto meglio...
Vedrai.
Fabio
Avatar utente
Foto Utentec1b8
3.350 3 8 13
G.Master EY
G.Master EY
 
Messaggi: 1766
Iscritto il: 15 gen 2009, 14:23

0
voti

[5] Re: Progettazione software per cubo LED 4x4x4

Messaggioda Foto Utenteposta10100 » 15 apr 2009, 23:24

Galaxi alias Terminator,
ho dato un occhio al codice dentro il file zip. E' scritto ordinato e ben commentato!

Non mi sembra particolarmente complesso in se, solo che stasera sono troppo cotto per guardarlo meglio!

Se non hai fretta nei prossimi giorni lo guardo con calma e vediamo cosa si può fare! Sempre se non arriva qualcuno più veloce di me!!!

Ciao,

Luca.
http://millefori.altervista.org Il mio tool gratuito per chi sviluppa su millefori.

Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa.
A. Einstein

Strumento per formule
Avatar utente
Foto Utenteposta10100
3.395 4 8 13
Master
Master
 
Messaggi: 3999
Iscritto il: 4 nov 2006, 23:09

0
voti

[6] Re: Progettazione software per cubo LED 4x4x4

Messaggioda Foto UtenteGalaxi93 » 16 apr 2009, 6:06

Si va bene, non ho fretta. Fai pure con comodo.

Grazie,

Davide.
Galaxi93.

Visita il mio sito!! E' ancora in costruzione, ma anche tu puoi contribuire a farlo crescere e darmi dei consigli per migliorarlo! Dai prova, provare non costa nulla! Vieni!
Avatar utente
Foto UtenteGalaxi93
2.865 3 7 13
Master
Master
 
Messaggi: 586
Iscritto il: 15 apr 2009, 15:27

1
voti

[7] Re: Progettazione software per cubo LED 4x4x4

Messaggioda Foto Utentephylum » 16 apr 2009, 7:14

Avatar utente
Foto Utentephylum
6.116 5 7 12
G.Master EY
G.Master EY
 
Messaggi: 3264
Iscritto il: 9 ott 2007, 11:40

0
voti

[8] Re: Progettazione software per cubo LED 4x4x4

Messaggioda Foto Utentec1b8 » 16 apr 2009, 7:58

phylum ha scritto:http://tinyurl.com/dayajw :-"

Ma non ti si può proprio nascondere nulla.... :mrgreen:
Fabio
Avatar utente
Foto Utentec1b8
3.350 3 8 13
G.Master EY
G.Master EY
 
Messaggi: 1766
Iscritto il: 15 gen 2009, 14:23

2
voti

[9] Re: Progettazione software per cubo LED 4x4x4

Messaggioda Foto Utenteposta10100 » 16 apr 2009, 21:54

Galaxi,
sto leggendo il tuo codice ma sto facendo una fatica immane... un buon programma deve essere indentato altrimenti si diventa matti a capire dove iniziano e finiscono i blocchi!!!!

Di seguito il tuo codice indentato:
Codice: Seleziona tutto
//Versione finale del firmware da inserire nel PIC che controlla il cubo di LED
// 4x4x4 con demultiplexer.
char x_led, y_led, z_led;                 //Dichiarazione delle coordinate,
char tempo_effetto, tempo, gioco;         //dei tempi e del numero di gioco e
char effetto_4, effetto_8;                //del numero di effetti.
char random_16, random_4;
//Funzione fondamentale che serve ad accendere i LED date le coordinate x, y, z.
void acc_led(char x, char y, char z) {
    if (x==0, y==0, z==0) {               //Se sono tutti 0,
   porta=0x10;                          //Mette alto G1+G2 e
       portb=0;                             //spegne tutti i z.
    } else {                                //altrimanti:
       char valore_demux=y*4+x-5;
       porta=valore_demux;                   //accende il LED
       switch(z) {                            //prende in considerazione la variabile z.
          case 1:                               //Se è 1
             portb=0x01;                           //mette alto la porta RB0.
             break;                                //fine primo caso.
          case 2:                               //Se è 2
             portb=0x02;                           //mette alto la porta RB1.
             break;
          case 3:                               //Se è 3
             portb=0x04;                           //mette alto la porta RB2.
             break;
          case 4:                               //Se è 4
             portb=0x08;                           //mette alto la porta RB3.
             break;
   }
    }
}

//Funzione per accendere, uno alla volta, tutti gli assi verticali x.
void piano_vert_x() {
    if (x_led == effetto_4)               //Se y è uguale a effetto,
       acc_led(x_led, y_led, z_led);         //accende i LED.
    else
       acc_led(0, 0, 0);                     //altrimente li spegne.
}

//Funzione per accendere, uno alla volta, tutti gli assi verticali x in senso opposto.
void piano_inv_x() {
    effetto_4=5-effetto_4;
    piano_vert_x();
    effetto_4=5-effetto_4;
}

//Funzione per accendere, uno alla volta, tutti gli assi verticali y.
void piano_vert_y() {
    if (y_led == effetto_4)               //Se y è uguale a effetto,
       acc_led(x_led, y_led, z_led);         //accende i LED.
    else
       acc_led(0, 0, 0);                     //altrimente li spegne.
}

//Funzione per accendere, uno alla volta, tutti gli assi verticali x in senso opposto.
void piano_inv_y() {
    effetto_4=5-effetto_4;
    piano_vert_y();
    effetto_4=5-effetto_4;
}

//Funzione per accendere, uno alla volta, tutti gli assi orizzontali.
void piano_oriz() {
    if (z_led == effetto_4)               //Se z è uguale a effetto,
       acc_led(x_led, y_led, z_led);         //accende i LED.
    else
       acc_led(0, 0, 0);                     //altrimente li spegne.
}

//Funzione per accendere, uno alla volta, tutti gli assi verticali x in senso opposto.
void piano_inv_z() {
    effetto_4=5-effetto_4;
    piano_oriz();
    effetto_4=5-effetto_4;
}

//Funzione per generare un seme di partenza per il rand.
unsigned getseme(void) {               //Crea una funzione,
    return;                            //che ritorna un numero casuale.
}

//Genera un numero casuale da 0 a 15 e da 1 a 4.
char random() {
    random_16=rand()% 15;
    random_4=random_16/4+1;
    return(random_16, random_4);
}

//Funzione per accendere casualmente i LED del piano x e y e li fa scorrere
//verso il basso.
void led_rand(void) {
    random();                              //Richiama la funzione random.
    for (z_led=4; z_led>0; --z_led) {      //Ciclo che diminuisce z_led finché
                                           //diventa 1.
      acc_led(x_led,y_led,z_led);
      porta=random_16;                     //Il numero random viene messo su portA.
      delay_ms(100);
      portb=0;
      delay_ms(10);
    }
    porta=0;
}

//Il main principale, dove viene coordinato tutto lo svolgimento del programma e
//quindi dei giochi di luce.
void main(void) {
    porta=0;                              //Porte A a 0.
    trisa=0;                              //Porte A impostate su uscite.
    portb=0;                              //Porte B a 0.
    trisb=0;                              //Porte B impostate su uscite.
    srand(getseme());                     //Serve ad dare il seme a rand.
    effetto_4=1;                          //Mette 1 ad effetto_4.
    while(1) {                            //Inizio del primo ciclo infinito
                                          //incondizionato.
        gioco=0;                              //Mette a 0 il numero di gioco.
        while(gioco!=6) {                     //Inizio del secondo ciclo infinito,
                                              //che termina quando gioco==3.
          tempo_effetto =100;                 //Il tempo dell'effetto(200 = 1sec circa).
          for (tempo=1; tempo<tempo_effetto; tempo++) { //Questi cicli for servono per
              for (z_led=1; z_led<5; z_led++) {     //far lampeggiare in sequenza tutti i
                  for (y_led=1; y_led<5; y_led++) {     //LED in maniera velocissima.
                      for (x_led=1; x_led<5; x_led++) {
                          switch(gioco) {                       //Scegli che gioco di luce svolgere.
                              case 0:
                                  piano_vert_x();
                                  break;
                              case 1:
                                  piano_inv_x();
                                  break;
                              case 2:
                                  piano_vert_y();
                                  break;
                              case 3:
                                  piano_inv_y();
                                  break;
                              case 4:
                                  piano_oriz();
                                  break;
                              case 5:
                                  piano_inv_z();
                                  break;
                          }
            }
             }
         }
              acc_led(0, 0, 0);
          }
          effetto_4++;                        //Aumenta effetto_4.
          if (effetto_4==5) {                   //Se effetto_4 è uguale a 5,
              effetto_4=1;                      //lo rimette ad 1 e
              gioco++;                          //aumenta gioco.
          }                   
        }
        for(gioco=1; gioco<60; gioco++) {      //Ripete led_rand per 60 volte.
            led_rand();
        }
    }
}


Adesso vedo come aggiungere il resto dei giochi!
http://millefori.altervista.org Il mio tool gratuito per chi sviluppa su millefori.

Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa.
A. Einstein

Strumento per formule
Avatar utente
Foto Utenteposta10100
3.395 4 8 13
Master
Master
 
Messaggi: 3999
Iscritto il: 4 nov 2006, 23:09

2
voti

[10] Re: Progettazione software per cubo LED 4x4x4

Messaggioda Foto Utenteposta10100 » 16 apr 2009, 22:05

Inanzitutto dovresti modificare la funzione
Codice: Seleziona tutto
//Funzione fondamentale che serve ad accendere i LED date le coordinate x, y, z.
void acc_led(char x, char y, char z) {
...
}


in

Codice: Seleziona tutto
//Funzione fondamentale che serve ad accendere o spegnere i LED date le coordinate x, y, z e lo stato
void acc_led(char x, char y, char z, char stato) {
...
}


In pratica, se stato è uguale a 1 accende il LED, se è uguale a 0 lo spegne.

Questa funzione è fondamentale per far funzionare tutto. Se la modifichi tu ci metti 3 minuti, se devo farlo io devo studiare prima come funziona l'hw... :wink:

D'ora in avanti considero la funzione fatta come ti ho chiesto :mrgreen:
http://millefori.altervista.org Il mio tool gratuito per chi sviluppa su millefori.

Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa.
A. Einstein

Strumento per formule
Avatar utente
Foto Utenteposta10100
3.395 4 8 13
Master
Master
 
Messaggi: 3999
Iscritto il: 4 nov 2006, 23:09

Prossimo

Torna a Realizzazioni, interfacciamento e nozioni generali.

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti