Problema di insufficienza di memoria per balletto con led

Salve a tutti!
Sto lavorando ad un programma per creare un "balletto" di luci colorate per accompagnare la melodia "back on track". Ho disposto 9 led in riga e li ho collegati ai pin in modo che il primo sia controllato dal pin 10 e gli altri dai pin con rispettivo numero.
Il programma per intero purtroppo non posso mostrarlo in quanto occupa più di 9000 caratteri, ma ne manderò la parte iniziale come esempio premettendo che il resto è formato allo stesso modo.

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
digitalWrite(10, HIGH);
delay(500);
digitalWrite(2, HIGH);
delay(500);
digitalWrite(3, HIGH);
delay(500);
digitalWrite(4, HIGH);
delay(500);
digitalWrite(5, HIGH);
delay(500);
digitalWrite(6, HIGH);
delay(500);
digitalWrite(7, HIGH);
delay(500);
digitalWrite(8, HIGH);
delay(500);
digitalWrite(9, HIGH);
delay(500);
digitalWrite(10, LOW);
delay(500);
digitalWrite(2, LOW);
delay(500);
digitalWrite(3, LOW);
delay(500);
digitalWrite(4, LOW);
delay(500);
digitalWrite(5, LOW);
delay(500);
digitalWrite(6, LOW);
delay(500);
digitalWrite(5, LOW);
delay(500);
digitalWrite(7, LOW);
delay(500);
digitalWrite(8, LOW);
delay(500);
digitalWrite(9, LOW);
delay(500);
}

Non riscontro problemi nel caricamento o nell'esecuzione, bensì nella lunghezza: il mio Arduino dispone di solo 32kb di memoria per i programmi e io ne ho già occupato l'88% riuscendo ad accompagnare solo 2 minuti su 3. Se non trovo un modo, forse delle funzioni che svolgono il lavoro di creare una combinazione oppure un metodo più economico in termini di spazio di usare la funzione "digitalWrite", per usare meno memoria è evidente che non riuscirò a portare a termine il mio progetto, perciò mi rivolgo cortesemente a voi nella speranza che un modo effettivamente esista.
Uranios

Usa dei for per le sequenze in fila e delle funzioni per le sequenze che si ripetono. Per quello che hai riportato:

digitalWrite(10, HIGH);
delay(500);
for(byte i=2; i<11; i++)
  {
  digitalWrite(i, HIGH); delay(500);
  }
for(byte i=2; i<10; i++)
  {
  digitalWrite(i, LOW); delay(500);
  }

Se si ripetono, puoi scrivere:

digitalWrite(10, HIGH);
delay(500);
acSeq(2, 10);
spSeq(2, 9);

-----------------------------------------------------

void acSeq(byte a, byte b)
  {
  for(byte i=a; i<b+1; i++)
    {
    digitalWrite(i, HIGH); delay(500);
    }
  }

void spSeq(byte a, byte b)
  {
  for(byte i=a; i<b+1; i++)
    {
    digitalWrite(i, LOW); delay(500);
    }
  }

Considera che, se vuoi poter interagire con il programma durante il funzionamento, dovrai chiamare una funzione di rilevamento della pressione di un pulsante dall'interno di ogni for o usare un interrupt comandato dal pulsante.

Se ho capito bene ogni 500 millisecondi fai variare i bit, forse è più facile e veloce, anche da implementare, se utilizzi un array di interi a 16 bit per identificare tutti i pin (in base alla posizione dei bit all'interno della variabile) e nel loop fai solo scorrere l'indice dell'array (per risparmiare ancora memoria potresti utilizzare un array da 10 bit, mappando correttamente la memoria, ma credo sia troppo complicato poi popolare l'array), ti allego un esempio che fa solo scorrere un bit, stile Super Car :slight_smile:

static const uint16_t _led[] PROGMEM = {
  1,
  2,
  4,
  8,
  16,
  32,
  64,
  128,
  256,
  512,
  1024,
  512,
  256,
  128,
  64,
  32,
  16,
  8,
  4,
  2
};

void setup() {
  Serial.begin(115200);
}

void loop() {
  for(int i = 0; i < (sizeof(_led) / sizeof(uint16_t)); i++) {
    uint16_t uInt = pgm_read_word_near(_led + i);
    Serial.println(uInt, BIN);
    delay(500);
  }
}

Io quoto l'imbeccata di dinodf.
Seguendo il suo consiglio puoi fare due cose:

  1. accendere e/o spegnere più led contemporaneamente in un singolo passo, ad es. accendendo alternativamente i led pari e quelli dispari.
  2. scrivere la sequenza su un supporto esterno, es. una scheda sd, così da non occupare memoria e poter creare una sequenza anche molto lunga che leggi a pezzi, esaurito un pezzo leggi il pezzo successivo e avanti finchè c'è vita nell'universo, visto che le schede sd possono essere di svariati giga.

Devi solo ragionare in binario per capire quali led accendere o spegnere e scrivere sulla sd i rispettivi valori in decimale.

ciao
Maurizio

Beh... Se fossero solo 8 uscite, la cosa più immediata sarebbe indirizzare tutta la porta D scrivendo un byte con PORT. Certo, questo si può fare anche con 9 o più uscite, usando 2 variabili a 8 bit e indirizzando all'altra porta i rimanenti bit. Se sono solo pochi LED accesi che si muovono, però, conviene gestire solo quelli, piuttosto che riscrivere tutta la porta ogni volta.