Go Down

Topic: Problema software con lampada RGB (Read 1 time) previous topic - next topic

83darking83

Ciao a tutti, ho realizzato una lampada RGB, basata su Arduino 2009 standalone e LED Luxeon da 3 W, controllata solo tramite un telecomando (DTT):



La lampada, funziona perfettamente, ad esclusione della funzione fade():

Code: [Select]

/*

Nome Progetto: Arduino RGB Lamp
Versione:      0.5

Codici Telecomando DTT:

 Accensione = FFE817 = 16771095
 Muto       = FF40BF = 16728255
 Tasto 1    = FF32CD
 Tasto 2    = FF708F
 Tasto 3    = FFB24D
 Tasto 4    = FFF20D
 Tasto 5    = FF728D
 Tasto 6    = FFD02F
 Tasto 7    = FF52AD
 Tasto 8    = FF12ED
 Tasto 9    = FF50AF
 Tasto 0    = FFB04F
 Vol +      = FFA857 = 16754775
 Vol -      = FFE21D = 16769565
 PR +       = FF629D
 PR -       = FF6897
 TXT        = FF48B7
 OK         = FFAA55 = 16755285
 Menu       = FFA05F
 Exit       = FF18E7
 TV/Radio   = FFF00F
 <-PR       = FF30CF
 EPG        = FF22DD
 INFO       = FFD827
 Audio      = FFC837
 Subtitle   = FF827D
 FAV        = FF609F
 [][]       = FFE01F
 Pause      = FF906F
 Record     = FF5AA5
 Stop       = FF9867
 Rosso      = FF0AF5 = 16714485
 Verde      = FFCA35 = 16763445
 Giallo     = FF8A75 = 16747125
 Blu        = FF8877 = 16746615  
 
 Errore     = FFFFFFFF
*/

#include <IRremote.h>

#define MAX_R 190
#define MAX_GB 250
#define FADE_TIME 300    // Durata della sfumatura
#define COLOUR_TIME 1000 // Durata di ogni colore

// Dichiarazione dei pin
int PIN_2 = 2;
int PIN_3 = 3;
int PIN_4 = 4;
int PIN_5 = 5;
int RECV_PIN = 6;
int B_PIN = 11;
int G_PIN = 9;
int R_PIN = 10;

// Dichiarazione delle variabili
int mod_auto=0;

// Matrice dei colori (R,G,B)
int colours_matrix[9][4] = {
                           { MAX_R, MAX_GB, MAX_GB },
                           { MAX_R, MAX_GB, 0      },
                           { MAX_R, 0,      MAX_GB },
                           { MAX_R, 0,      0      },
                           { 0,     MAX_GB, MAX_GB },  
                           { 0,     MAX_GB, 0      },  
                           { 0,     0,      MAX_GB },  
                           { 0,     0,      0      }  
                         };
                           
int R=0, G=0, B=0, R_old=0;
int colore_attuale = 0, index = 0, i=0, j=0, count=0, uscita=0;

IRrecv irrecv(RECV_PIN);
decode_results results;

String tasto_premuto = "";
String tasto_power = String("16771095");
String tasto_rosso = String("16714485");
String tasto_verde = String("16763445");
String tasto_giallo= String("16747125");
String tasto_blu   = String("16746615");
String tasto_viola = String("16728255");
String tasto_ok    = String("16755285");
String tasto_volp  = String("16754775");
String tasto_volm  = String("16769565");

// Prototipi delle funzioni

void lamp_OFF(void);
int rnd(void);
void  wait_power_off(void);
void fade(void);

void setup()
{
 Serial.begin(9600);
 pinMode(PIN_2, OUTPUT);
 pinMode(PIN_3, OUTPUT);
 pinMode(PIN_4, OUTPUT);
 pinMode(PIN_5, OUTPUT);
 pinMode(RECV_PIN, INPUT);
 pinMode(R_PIN, OUTPUT);
 pinMode(G_PIN, OUTPUT);
 pinMode(B_PIN, OUTPUT);
 
 mod_auto=0;
 lamp_OFF();
 
 irrecv.enableIRIn(); // Start the receiver
}

void loop() {
 if (irrecv.decode(&results)) {
   Serial.println(results.value);
   tasto_premuto = String(results.value);
   if( !tasto_premuto.compareTo(tasto_rosso) ){
     analogWrite(R_PIN, MAX_R);
     digitalWrite(G_PIN, LOW);
     digitalWrite(B_PIN, LOW);
     colore_attuale = 3;
   }
   if( !tasto_premuto.compareTo(tasto_verde) ){
     digitalWrite(R_PIN, LOW);
     digitalWrite(G_PIN, MAX_GB);
     digitalWrite(B_PIN, LOW);
     colore_attuale = 5;
   }
   if( !tasto_premuto.compareTo(tasto_blu) ){
     digitalWrite(R_PIN, LOW);
     digitalWrite(G_PIN, LOW);
     digitalWrite(B_PIN, MAX_GB);
     colore_attuale = 6;
   }
   if( !tasto_premuto.compareTo(tasto_viola) ){
     analogWrite(R_PIN, MAX_R);
     digitalWrite(G_PIN, LOW);
     digitalWrite(B_PIN, MAX_GB);
     colore_attuale = 2;
   }
   if( !tasto_premuto.compareTo(tasto_giallo) ){
     analogWrite(R_PIN, MAX_R);
     digitalWrite(G_PIN, MAX_GB);
     digitalWrite(B_PIN, LOW);
     colore_attuale = 1;
   }
   if( !tasto_premuto.compareTo(tasto_volp) ){
     index = (colore_attuale + 1);
     if(index>7)
       index = 0;
     
     analogWrite(R_PIN, colours_matrix[index][0]);
     digitalWrite(G_PIN, colours_matrix[index][1]);
     digitalWrite(B_PIN, colours_matrix[index][2]);
     colore_attuale = index;
   }
   if( !tasto_premuto.compareTo(tasto_volm) ){
     index = (colore_attuale - 1);
     if(index<0)
       index = 7;
     
     analogWrite(R_PIN, colours_matrix[index][0]);
     digitalWrite(G_PIN, colours_matrix[index][1]);
     digitalWrite(B_PIN, colours_matrix[index][2]);
     colore_attuale = index;
   }
   if( !tasto_premuto.compareTo(tasto_power) ){
     lamp_OFF();
     mod_auto=0;
     colore_attuale = 7;
   }
   if( !tasto_premuto.compareTo(tasto_ok) )
     mod_auto=1;
   
   irrecv.resume(); // Receive the next value
 }
 if(mod_auto==1)
   fade();
}

// Funzioni

void lamp_OFF(void){
 digitalWrite(R_PIN, LOW);
 digitalWrite(G_PIN, LOW);
 digitalWrite(B_PIN, LOW);
 return;
}

int rnd(){
 int rand = random(0,7);
 return rand;
}

void  wait_power_off(void){
 for(int k=0;k<5;k++){
   if (irrecv.decode(&results)) {
     tasto_premuto = String(results.value);
     if( !tasto_premuto.compareTo(tasto_power) ){
       lamp_OFF();
       irrecv.resume(); // Receive the next value
       uscita=1;
       return;
     }      
   }
   delay(10);
 }
 return;  
}

void fade(void){
 uscita=0;
 mod_auto=0;
 count=0;
 while(1){ // Modalità loop, si esce solo con power_off
   j = rnd();
   R = colours_matrix[j][0];
   G = colours_matrix[j][1];
   B = colours_matrix[j][2];
   
   if(count){
     if(R_old > R){
       for(i=R_old; i>50; i=i-20){
         analogWrite(R_PIN, i);
         digitalWrite(G_PIN, G);
         digitalWrite(B_PIN, B);
         wait_power_off();
         if(uscita)
           return;
         delay(FADE_TIME);
         R_old = R;
       }
     }
     else if(R_old < R){
        for(i=80; i<R; i= i+20){
         analogWrite(R_PIN, i);
         digitalWrite(G_PIN, G);
         digitalWrite(B_PIN, B);
         wait_power_off();
         if(uscita)
           return;
         delay(FADE_TIME);
         R_old = R;
       }
     }
    else if(R_old==R){
      analogWrite(R_PIN, R);
      digitalWrite(G_PIN, G);
      digitalWrite(B_PIN, B);
      R_old = R;
    }
   }
   else{    
     analogWrite(R_PIN, R);
     digitalWrite(G_PIN, G);
     digitalWrite(B_PIN, B);
     count = 1;
     R_old = R;
   }
   
   colore_attuale = j;

   for(i=0; i<(COLOUR_TIME/100); i++){
     wait_power_off();
     if(uscita)
       return;
     delay( COLOUR_TIME / (COLOUR_TIME/100) );
   }
 }
}


In pratica, nella maggior parte dei tentativi, non riesco ad uscire dal loop della stessa funzione fade(), nonostante prema numerose volte il tasto power (che funziona perfettamente al di fuori di questa funzione).

A nulla è servito, "spargere" controlli sulla ricezione del tasto power prima di ogni delay()...  :0

leo72

Uscendo dalla funzione Fade dovresti mettere mod_auto=0 altrimenti, al prossimo ciclo (ricorda che chiami fave dentro a loop(), quindi viene fatto all'infinito), ci rientri dentro.
Code: [Select]

if(mod_auto==1) {
    fade();
    mod_auto=0;
}

83darking83

L'avevo già inserito all'inizio della funzione fade():

Code: [Select]

void fade(void){
  uscita=0;
  mod_auto=0;
...

leo72

Ah, è vero... non l'avevo visto  :D

Hai provato a fare un po' di debug, mettendo un po' di Serial.print in diversi punti della funzione Fade per vedere da quale ciclo non esce?

83darking83

#4
Feb 28, 2011, 03:25 pm Last Edit: Feb 28, 2011, 06:41 pm by 83darking83 Reason: 1
Ciao, si ho provato ma non cavo il ragno dal buco!  :~

Ho modificato la funzione in versione debug così:

Code: [Select]

void fade(void){
 uscita=0;
 mod_auto=0;
 count=0;
 int nCicli=0;
 while(1){ // Modalità loop, si esce solo con power_off
   j = rnd();
   ++nCicli;
   Serial.print(nCicli, DEC);
   Serial.print(") j = ");
   Serial.println(j, DEC);
   R = colours_matrix[j][0];
   G = colours_matrix[j][1];
   B = colours_matrix[j][2];
   
   if(count){
     if(R_old > R){
       Serial.println("R_old>R");
       for(i=R_old; i>50; i=i-20){
         analogWrite(R_PIN, i);
         digitalWrite(G_PIN, G);
         digitalWrite(B_PIN, B);
         wait_power_off();
         if(uscita)
           return;
         delay(FADE_TIME);
         R_old = R;
       }
     }
     else if(R_old < R){
       Serial.println("R_old<R");
       for(i=80; i<R; i= i+20){
         analogWrite(R_PIN, i);
         digitalWrite(G_PIN, G);
         digitalWrite(B_PIN, B);
         wait_power_off();
         if(uscita)
           return;
         delay(FADE_TIME);
         R_old = R;
       }
     }
    else if(R_old==R){
      Serial.println("R_old=R");
      analogWrite(R_PIN, R);
      digitalWrite(G_PIN, G);
      digitalWrite(B_PIN, B);
      wait_power_off();
      if(uscita)
        return;
      R_old = R;
    }
   }
   else{    
     analogWrite(R_PIN, R);
     digitalWrite(G_PIN, G);
     digitalWrite(B_PIN, B);
     count = 1;
     R_old = R;
   }
   
   colore_attuale = j;

   for(i=0; i<(COLOUR_TIME/100); i++){
     wait_power_off();
     if(uscita)
       return;
     delay( COLOUR_TIME / (COLOUR_TIME/100) );
   }
 }
}


Code: [Select]

void  wait_power_off(void){
 for(int k=0;k<5;k++){
   if (irrecv.decode(&results)) {
     tasto_premuto = String(results.value);
     if( !tasto_premuto.compareTo(tasto_power) ){
       lamp_OFF();
       irrecv.resume(); // Receive the next value
       uscita=1;
       Serial.println("Uscita dalla funzione fade()!");
       return;
     }      
   }
   delay(10);
 }
 return;  
}


Ottenendo il seguente output:

Code: [Select]

1) j = 1
2) j = 1
R_old=R
3) j = 5
R_old>R
4) j = 2
R_old<R
5) j = 4
R_old>R
6) j = 2
R_old<R
7) j = 0
R_old=R
8) j = 2
R_old=R
9) j = 5
R_old>R
10) j = 1
R_old<R
11) j = 0
R_old=R
12) j = 5
R_old>R
13) j = 0
R_old<R
14) j = 2
R_old=R
15) j = 3
R_old=R
16) j = 5
R_old>R
17) j = 1
R_old<R
18) j = 1
R_old=R
19) j = 4
R_old>R
20) j = 4
R_old=R
21) j = 3
R_old<R
22) j = 1
R_old=R
23) j = 3
R_old=R
24) j = 5
R_old>R
25) j = 4
R_old=R
26) j = 3
R_old<R
27) j = 3
R_old=R
28) j = 0
R_old=R
29) j = 2
R_old=R
30) j = 1
R_old=R
31) j = 1
R_old=R
32) j = 2
R_old=R
33) j = 2
R_old=R
34) j = 1
R_old=R
35) j = 2
R_old=R
36) j = 3
R_old=R
37) j = 1
R_old=R
38) j = 1
R_old=R


Non c'è verso di far terminare la funzione fade() !

EDIT: ho risolto, semplificando così la funzione d'uscita:

Code: [Select]

void  wait_power_off(void){
  if (irrecv.decode(&results)) {
        lamp_OFF();
        irrecv.resume(); // Receive the next value
        uscita=1;
        Serial.println("Uscita dalla funzione fade()!");
        return;
   }     
  return; 
}


uwefed

vedi; Ti ha aiutato chiedercelo.  ;) ;) ;)

Spesso quando devi pensare come spiegare il problema agli altri per chiedere aiuto ti fa capire meglio il problema e spesso porta questo a una soluzione.

Comunque siamo quá per il prossimo Tuo problema.

Ciao Uwe

83darking83


vedi; Ti ha aiutato chiedercelo.  ;) ;) ;)


In che modo?  :)
Chiaramente ringrazio comunque leo72 per i suoi interventi...

Non mancherò di aprire un topic anche per gli eventuali "problemi" futuri...  :)

Go Up