Pages: [1] 2   Go Down
Author Topic: Come usare tanti Switch Case (o If) [Problemi memoria?]  (Read 2223 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti,
ho alcuni grossi problemi, nel caricare uno sketch su Arduino UNO / DUEMILANOVE.

il mio progetto prevede una serie di lezioni progressive, che al momento ho provato a inserire mediante vari metodi, che vanno da 0 a 139.

Code:
  switch(progress)
  {
case 0:TestRx= "U";break;
case 1:TestRx= "A";break;
case 2:TestRx= "UAU";break;
case 3:TestRx= "AAU";break;
case 4:TestRx= "AUA";break;
case 5:TestRx= "UAA";break;
case 6:TestRx= "V";break;
etc etc etc....fino al case 139.

Oppure ho provato con:

Code:
if (progress==1) {TestRx= "U";}
else if (progress==1) {TestRx= "A";}
else if (progress==2) {TestRx= "UAU";}
else if (progress==3) {TestRx= "AAU";}
else if (progress==4) {TestRx= "AUA";}
else if (progress==5) {TestRx= "UAA";}
else if (progress==6) {TestRx= "V";}
else if (progress==7) {TestRx= "VUA";}
etc etc...

e anche con:

Code:
  PROGMEM prog_char *strings[] ={
//"U",
//"A",
//"UAU",
//"AAU",
//"AUA",
//"UAA",
//"V",
... etc etc
 TestRx=strings[progress];


Il mio problema è che non appena assegno un valore a "progress" attivando la relativa funzione, Arduino impazzisce completamente.

Sul mega tutto funziona benissimo, ma io ho necessità di caricare questo set di 139 lezioni progressive.
Per essere precisi avrei bisogno di caricare 2 set da 139 lezioni.

Vi viene in mente qualche metodo per caricare questi 139 stati in maniera più risparmiosa possibili in termini di ram?
Utilizzando PROGMEM nel modo in cui l'ho utilizzato al momento di caricare lo sketch e farlo partire va tutto bene, ma Arduino impazzisce non appena assegno un valore a "progress".

Sarebbero ben accette ottime idee smiley per poter caricare questi set di lezioni su un Arduino Uno o Duemilanove.

grazie
Giorgio
 
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Gestire tutte quelle variabili e stringhe differenti può saturare la memoria.
L'Arduino UNO non ha tutta la RAM che servirebbe. Sappi che ogni stringa contenuta nello sketch, prima di poter essere usata, viene copiata nella RAM, che è di soli 2 kB.

Inoltre tutti i salti degli if e degli switch..case creano anch'essi dati che vengono memorizzati nello stack di sistema per i salti di rientro dalle subroutine, e lo stack "vive" anch'esso nella RAM.

Logged


Riva del Garda, TN / Forlì
Offline Offline
Edison Member
*
Karma: 8
Posts: 2246
Il piu' modesto al mondo
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

esiste un sistema per caricare le variabili in rom invece che ram.

comunque dai una letta a
http://arduino.cc/en/Reference/Volatile
e
http://arduino.cc/en/Reference/PROGMEM
Logged

Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Lui ha già detto di aver usato Progmem. Il problema sono comunque anche i vari case dello switch. Ogni salto salva nello stack l'indirizzo del PC (Program Counter) per riprendere l'esecuzione una volta terminata l'esecuzione della subroutine chiamata. Poi bisogna anche vedere il resto dello sketch cosa fa, se ad esempio vengono caricate librerie esterne, viene usata la seriale, vengono stampati dati su un LCD ecc... tutte cose che possono aumentare il consumo di memoria.
Logged


0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si, ho 2-3 librerie e scrivo su LCD.
Mi ritrovo a sketch partito SENZA lezioni, con 641 bytes di memoria liberi.
Se carico un set di lezioni, parto con 120, praticamente appena introduco un carattere Arduino impazzisce...letteralmente...
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

E' la memoria, te lo garantisco.
Non puoi usare la MEGA?
Logged


Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lui ha già detto di aver usato Progmem. Il problema sono comunque anche i vari case dello switch. Ogni salto salva nello stack l'indirizzo del PC (Program Counter) per riprendere l'esecuzione una volta terminata l'esecuzione della subroutine chiamata. Poi bisogna anche vedere il resto dello sketch cosa fa, se ad esempio vengono caricate librerie esterne, viene usata la seriale, vengono stampati dati su un LCD ecc... tutte cose che possono aumentare il consumo di memoria.
dove le vedi le call??  smiley-grin i case son delle jump,o se è furbo usa una jump table a va velocissimo..
lo so,sono un rompi****e che mette i puntini sulle i
« Last Edit: September 13, 2012, 05:46:08 pm by m_ri » Logged

Riva del Garda, TN / Forlì
Offline Offline
Edison Member
*
Karma: 8
Posts: 2246
Il piu' modesto al mondo
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

comunque se sono librerie esterne magari prova ad ottimizzarle eliminando cose inutili (ad esempio nell'lcd la funzione per creare caratteri custom se non la usi ec...) forse riesci a recuperare quel che ti serve smiley-grin
Logged

Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

dove le vedi le call??  smiley-grin i case son delle jump
Probabilmente hai ragione.
E vista l'ora, non ho voglia di disassemblare un firmware per vedere come il compilatore traduce gli switch..case  smiley-razz
Logged


Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

io invece vado direttamente a dormire...
buonanotte guys!!
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 129
Posts: 9468
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dove le vedi le call??  smiley-grin i case son delle jump,o se è furbo usa una jump table a va velocissimo..
lo so,sono un rompi****e che mette i puntini sulle i

La switch case viene codificata come una serie di chiamate a subroutine, una per ogni funzione invocata, e ovviamente sono delle call, i jump sono esclusivamente per la break che salta direttamente alla fine della switch.
Ovviamente di call ne viene eseguita solo una, ovvero quella della condizione valida, e occupa nello stack solo lo spazio riservato ad una singola chiamata a subroutine,  però a livello di flash viene utilizzata una word (call) per ogni funzione inserita nella switch che va a pesare sull'impiego della memoria di programma, ma non sulla ram.
Da notare che la riga "case 0:TestRx= "U";break; " viene totalmente memorizzata nella flash, la "U" viene considerata come rom constant e posta direttamente nella flash senza necessità di usare progmem.
« Last Edit: September 14, 2012, 04:21:38 am by astrobeed » Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ottimo.
Logged


Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 112
Posts: 7113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

E se provassi a registrare le sigle nella Eprom o in una eprom esterna o in una SD?
Dovresti fare solo una funzione per richiamare il dato in base all'indice.
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@astrobeed: solitamente,gli switch vengono tradotti in una serie di cmp/test e jump..ho provato a fare un po' di disassemblaggio adesso,ed è così...
altrimenti,come ho detto prima,in alcuni casi,e se l'ottimizzazione è buona,lo switch viene tradotta in jump table..ossia usa l'argomento dello switch come indice in un vettore di puntatori a codice(ossia la cella i-esima del vettore contiene il puntatore al codice da eseguire nel caso la variabile valesse i,più alcune ottimizzazioni)..può essere che in alcuni casi usi la call,ma non mi vengono i mente..
EDIT: anche perchè il compilatore come fa a fare le call condizionate?al massimo può usare call + branch table,ma direi che ha più overhead di una jump table ..
« Last Edit: September 14, 2012, 04:50:43 am by m_ri » Logged

Firenze
Offline Offline
Jr. Member
**
Karma: 2
Posts: 65
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma invece provare qualcosa di questo tipo:

se la prima lettera e' "U" allora
---se la seconda e' una "A" allora
------se la terza e' una "U" allora
---------azione da fare per la combinazione UAU
------else la terza e' una "A" allora
---------azione da fare per la combinazione UAA

non migliorerebbe l'occupazione di memoria? forse ancora meglio sarebbe definendo le lettere possibili come constanti (si puo'?) e poi fare le varie combinazioni con le constanti...
Logged

"Cosi non si va avanti..." disse il gambero

Pages: [1] 2   Go Up
Jump to: