Miglior approccio per cambiare funzione?

Ok, ho incontrato una piccola difficoltà che sicuramente in molti hanno già affrontato.

Ho una matrice 8x8 che voglio illuminare in una serie di modi, a questo proposito ho diversi metodi che illuminano la matrice in maniera differente.

Dato un pulsante vorrei che l'utente possa cambiare funzione ad ogni clic. Ho provato inizialmente leggendo il valore all'inizio del loop ma in questo modo il pulsante deve essere premuto più o meno all'inizio. Dato che alcune funzioni durano più di altre questo rende il comportamento "strano" e poco real-time.

Qualche semplice soluzione che non mi è venuta in mente? O devo leggere il valore prima di ogni delay?

la cosa piú semplice é non usare delay()
vedi http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Ciao Uwe

uwefed:
la cosa piú semplice é non usare delay()
vedi http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Ciao Uwe

Perfetto, credo sia proprio la soluzione ideale! :smiley:
Thanksss!

Ok, stavo provando ad implementare qualche funzione con questo approccio ed in effetti funziona benissimo, riesco a premere il bottone senza problemi ed a cambiare funzione immediatamente. Però non riesco a scrivere del codice "pulito", mi sembrano sempre degli hack per far funzionare le cose.

Ad esempio, se una funzione deve effettuare un mini-loop sono dovuto ricorrere ad un delaytime / 2 per poter "spezzare" il tempo fra i due mini-loop, e inoltre non so dove infilare il clearDisplay (che venendo richiamato tutte le volte mi causa un leggero (e fastidioso) sfarfallio.

Una mano?

Qui il codice:

void points(long currentMillis) {
  if((currentMillis - previousMillis) < (delaytime / 2)) {
  
  for(int col=0;col<8;col++) {
    for(int row=0;row<8;row++) {
      if(col == 0 || col == 3 || col == 4 || col == 7 || row == 0 || row == 3 || row == 4 || row == 7) {
        lc.setLed(0,col,row,true);
      }
    }
  }
  
  } else {
      if((currentMillis - previousMillis) > delaytime) {
        previousMillis = currentMillis;
      }
  
  for(int col=0;col<8;col++) {
    for(int row=0;row<8;row++) {
      if((row == 1 || row == 2) && (col == 1 || col == 2)) {
        lc.setLed(0,col,row,true);
      }
      if((row == 5 || row == 6) && (col == 1 || col == 2)) {
        lc.setLed(0,col,row,true);
      }
      if((row == 5 || row == 6) && (col == 5 || col == 6)) {
        lc.setLed(0,col,row,true);
      }
      if((row == 1 || row == 2) && (col == 5 || col == 6)) {
        lc.setLed(0,col,row,true);
      }
    }
  }
  }
  lc.clearDisplay(0);
}

ciao,

spero di riuscire a spiegarmi. In effetti l'obiettivo è quello di non interrompere troppo a lungo il loop principale (quello creato dalla funzione standard loop()).

Non hai postato tutto il codice ma immagino che la funzione points() che hai postato venga richiamata da loop() e che ce ne sia una diversa per ogni effetto da visualizzare selezionato con la pressione del tasto.

Ti suggerirei allora di non inserire dei cicli all'interno di points ma di rendere globali le variabili col e row e di utilizzare dei while. Ogni volta che loop() chiama points tu esegui soltanto un ciclo degli attuali for, incrementi la/e variabile/i col e row ed eventualmente le azzeri attraverso degli if per vedere se sei arrivato a fine ciclo.

Sembra complicato, e non sono sicuro di essere stato sufficientemente chiaro (ma, nel caso, chiedi pure ulteriori info). In questo modo però riesci a leggere lo stato del pulsante anche durante l'esecuzione dei cicli.

Ciao.
Vittorio.