Go Down

Topic: SRAM piena e metodi alternativi di memorizzazione (Read 409 times) previous topic - next topic

Matteo_beg

Ciao a tutti! Vi espongo il mio problema: Ho necessità di memorizzare 4 array di interi piuttosto ingombranti che mi portano in saturazione la SRAM dell'arduino UNO.. a questo punto ho cercato metodi alternativi quali la memorizzazione su SD e la lettura solo in caso di necessità, la lettura da EEPROM e la memorizzazione su FLASH... MA... per quanto riguarda la prima soluzione sforo la  dimensione della flash dal momento che il codice utilizza delle stringhe per memorizzare la variabile in locale e poi la deve maneggiare per portarla prima in "char" e poi in "int"... quindi troppo lungo, piuttosto complesso e poco efficiente, la 2a potrebbe andare bene ma ho alcuni problemi con il codice di scrittura che mi dà un errore di tipo "copy_array:22: error: expected primary-expression before '.' token" che sinceramente non capisco... Se poteste darmi una mano ve ne sarei grato :) grazie!

Quote

/*Lo sketch permette di scrivere su EEPROM un vettore di 
interi e di stampare successivamente su seriale l'array*/

#define EEPROM.h

unsigned int on_0[] = {4400,4300,550,1600,500,1600,550,1600,550,1600,550,500,550,550,500,1600,550,550,550,500,550,500,550,550,550,500,550,1600,550,1600,550,500,550,1600,550,500,550,550,500,550,550,500,550,550,550,500,550,1600,550,1600,500,1600,550,1600,550,1600,550,1600,500,1600,550,1600,550,550,500,550,550,500,550,550,550,500,550,500,550,550,550,500,550,550,500,1600,550,1600,550,500,550,550,550,500,550,550,500,550,550,500,550,550,550,500,550,500,550,500,600,500,550,550,500,550,550,500,550,1600,550,500,550,550,550,500,550,550,500,550,550,500,550,550,550,500,550,1600,550,500,550,550,500,550,550,500,550,550,550,500,550,550,500};

int a=0;
int value=0;
int vect=0;
int i=0;

void setup()
{
 Serial.begin(9600);
 Serial.print(F("Dimensione dell'array:"));
 Serial.print(F("\t"));
 Serial.print(sizeof(on_0));
 Serial.println();
for(i=0 ; i < (sizeof(on_0)/sizeof(int))-1 ; i++){
  vect=on_0;
  EEPROM.write(i,vect);
}
}
void loop(){
value = EEPROM.read(a);
Serial.print(a);
Serial.print("\t");
Serial.print(value);
Serial.println();
a++;
if(a==1024){
  a=0;
}
  delay(500);
}


pablos

no comment

pippo72

ciao
Se ho visto bene tu memorizzi un array di (credo) 5 valori diversi che si ripetono.
Potresti memorizzare i 5 valori diversi su 5 int e nell'array memorizzi solo l'indice del valore che ti serve.
così andresti a risparmiare quasi metà memoria.

esempio:
Code: [Select]

int valori[]={4400,4300,550,1600,500};
byte on_0[]={0,1,2,3,4,3,2,.......eccetera....};


ciao
pippo72

nid69ita

#3
Jul 21, 2014, 03:41 pm Last Edit: Jul 21, 2014, 03:54 pm by nid69ita Reason: 1
@pippo72, se serve alla send_raw della IRRemote, purtroppo non può farlo. La funzione vuole l'array in quella maniera.

@matteo, con IRRemote non riesci a capire il modello del telecomando?
Per il codice DEVI usare i tag code, vedi sezione 7 del regolamento, spiega bene come fare. Infatti parte del tuo codice è visualizzato male, mancano le quadre quando leggi una cella da on_0

MA !!!! Nella EEPROM si scrive un byte alla volta (la write richiede un byte) mentre il tuo array è di interi (2 byte) !!! OCCHIO
Nel codice l'errore indica che stai cercando di mandare un valore intero (2 byte) mentre la write vuole 1 byte
my name is IGOR, not AIGOR

nid69ita

#4
Jul 21, 2014, 03:58 pm Last Edit: Jul 21, 2014, 11:24 pm by nid69ita Reason: 1
Code: [Select]
#define VDIM(v)  (sizeof(v)/sizeof(v[0]))

Code: [Select]
byte lowval,highval;
for(int i=0,int x=0; i < VDIM(on_0) ; i++)
{ lowval=lowByte(on_0[i]);
 highval=highByte(on_0[i]);
 EEPROM.write(x,lowval);
 EEPROM.write(x+1,highval);
 x=x+2;
}


Tra l'altro mi pare che non serva il -1 sulla dimensione del vettore, esempio 10 elementi, i va da 0 ad  <10 quindi 9.
my name is IGOR, not AIGOR

Matteo_beg

Quote
cos'è il codice raw di un telecomando IR?

Si esatto!
Quote
Se ho visto bene tu memorizzi un array di (credo) 5 valori diversi che si ripetono.
Potresti memorizzare i 5 valori diversi su 5 int e nell'array memorizzi solo l'indice del valore che ti serve.
così andresti a risparmiare quasi metà memoria.

Si è vero potrei fare così.. effettivamente non ci avevo pensato ma io questo segnale devo mandarlo quindi devo comunque ricostruire l'array prima o poi durante lo sketch..

Quote
@pippo72, se serve alla send_raw della IRRemote, purtroppo non può farlo. La funzione vuole l'array in quella maniera.

Si lo utilizzo per la IRRemote

Quote
@matteo, con IRRemote non riesci a capire il modello del telecomando?

No... la libreria non riconosce alcun formato "standard" con quella codifica!

Quote
Per il codice DEVI usare i tag code, vedi sezione 7 del regolamento, spiega bene come fare. Infatti parte del tuo codice è visualizzato male, mancano le quadre quando leggi una cella da on_0

Li avevo inseriti i tag code ma in preview non mi dava i colori e quindi ho semplicemente fatto "Copia per il forum" dall'IDE di Arduino e non ho inserito i tag... Cosa intendi con mancano le quadre quando leggo da on_0? Il codice che ho scritto è proprio questo quindi credo che io abbia fatto un errore di sintassi.. in ogni caso la prossima volta le inserisco! :)

Quote
MA !!!! Nella EEPROM si scrive un byte alla volta (la write richiede un byte) mentre il tuo array è di interi (2 byte) !!! OCCHIO
Nel codice l'errore indica che stai cercando di mandare un valore intero (2 byte) mentre la write vuole 1 byte

Eccolo il problema!! Ma se voglio scrivere un byte alla volta come posso fare? avrei bisogno di un array di byte che va solo da 0 a 255 e a me servono valori fino a 4000 e fischia... :( C'è un metodo per aggirare l'ostacolo?
Grazie a tutti per l'aiuto!

nid69ita

http://forum.arduino.cc/index.php?topic=256236.msg1812510#msg1812510
my name is IGOR, not AIGOR

Matteo_beg


http://forum.arduino.cc/index.php?topic=256236.msg1812510#msg1812510


Non avevo letto bene :( tuttavia continua a darmi lo stesso errore in compilazione in questa fase:
Code: [Select]

  EEPROM.write(x, lowval);


Ma questo:
Code: [Select]
  EEPROM.write(x+1, lowval);
non è:   
Code: [Select]
EEPROM.write(x+1, highval);
o sto prendendo un abbaglio?

pablos

Quote
la libreria non riconosce alcun formato "standard" con quella codifica!

Guarda che in giro ci sono le decodifiche non comprese nella libreria, bisogna solo cercarle e  aggiungerle, ma almeno il modello dovresti conoscerlo
Ne ho viste 2 non molto tempo fa su questo forum per condizionatori che avevano codifica non riconosciuta
no comment

Matteo_beg

#9
Jul 21, 2014, 06:01 pm Last Edit: Jul 21, 2014, 06:07 pm by Matteo_beg Reason: 1

Quote
la libreria non riconosce alcun formato "standard" con quella codifica!

Guarda che in giro ci sono le decodifiche non comprese nella libreria, bisogna solo cercarle e  aggiungerle, ma almeno il modello dovresti conoscerlo
Ne ho viste 2 non molto tempo fa su questo forum per condizionatori che avevano codifica non riconosciuta


Immagino che qualcosa ci sia ma... se io ipoteticamente riuscissi ad utilizzare una codifica conosciuta avrei effettivamente qualche vantaggio in termini di memoria? Ora provo a cercare se qualcuno ha già fatto questo tipo di lavoro..
EDIT: effettivamente ci sono molti che provano a farlo e molti che non riescono semplicemente per il fatto che la libreria di Ken Shriff originale ha un RAWbuff troppo basso... quella che ho utilizzato è già stata modificata per i clima e permette di memorizzare un numero di valori superiore :)

nid69ita


Non avevo letto bene :( tuttavia continua a darmi lo stesso errore in compilazione in questa fase:
Code: [Select]

  EEPROM.write(x, lowval);


Strano, non ho provato a compilare, ma qui: http://arduino.cc/en/Reference/EEPROMWrite
Sintassi: EEPROM.write(address, value)
Parameters:  address: the location to write to, starting from 0 (int)    value: the value to write, from 0 to 255 (byte)



Ma questo:
Code: [Select]
  EEPROM.write(x+1, lowval);
non è:   
Code: [Select]
EEPROM.write(x+1, highval);
o sto prendendo un abbaglio?

Corretto, sbaglio di copia-incolla.  :smiley-mr-green:

my name is IGOR, not AIGOR

Matteo_beg

Quote
Strano, non ho provato a compilare, ma qui: http://arduino.cc/en/Reference/EEPROMWrite
Sintassi: EEPROM.write(address, value)
Parameters:  address: the location to write to, starting from 0 (int)    value: the value to write, from 0 to 255 (byte)


L'avevo letto infatti... strana come cosa..

Quote
Corretto, sbaglio di copia-incolla.  smiley-mr-green


Nessun problema ;)

gpb01

Posso dare un suggerimento ?  XD

Ma perché non usate le funzioni ORIGINALI messe a disposizione, come sempre, dalla libreria AVR libc (che, vi ricordo, essere SEMPRE inclusa) per la gestione della eeprom ?

Basta includere <avr/eeprom.h> per avere tutte le funzioni che vi servono per scrivere/leggere : byte, word, dword, float e array ...  :smiley-mr-green: :smiley-mr-green: :smiley-mr-green:

Che volete di più ???  :smiley-eek:

Guglielmo
Search is Your friend ... or I am Your enemy !

nid69ita


Posso dare un suggerimento ?  XD
Ma perché non usate le funzioni ORIGINALI messe a disposizione, come sempre, dalla libreria AVR libc (che, vi ricordo, essere SEMPRE inclusa) per la gestione della eeprom ?
Basta includere <avr/eeprom.h> per avere tutte le funzioni che vi servono per scrivere/leggere : byte, word, dword, float e array ...  :smiley-mr-green: :smiley-mr-green: :smiley-mr-green:
Che volete di più ???  :smiley-eek:
Guglielmo

Un amaro lucaaaano !!!  :smiley-mr-green:    (pubblicità italiana famosa, non sò se in Svizzera gira)

Non sapevo. Al che mi viene una domanda. A che serve allora la libreria/comandi eeprom dati dal IDE/core ?
(Premetto che non ho quasi mai usato la EEPROM)
my name is IGOR, not AIGOR

Matteo_beg


Posso dare un suggerimento ?  XD

Ma perché non usate le funzioni ORIGINALI messe a disposizione, come sempre, dalla libreria AVR libc (che, vi ricordo, essere SEMPRE inclusa) per la gestione della eeprom ?

Basta includere <avr/eeprom.h> per avere tutte le funzioni che vi servono per scrivere/leggere : byte, word, dword, float e array ...  :smiley-mr-green: :smiley-mr-green: :smiley-mr-green:

Che volete di più ???  :smiley-eek:

Guglielmo


Detto sinceramente ho sempre visto:
Code: [Select]
#include <EEPROM.h>
e non mi sono mai posto il problema se ci fosse o meno un'altra libreria atta allo scopo :(
Sembra il ragionamento di un cavallo col para-occhi ma non pensavo proprio ci fosse un alternativa alla EEPROM.h!
A questo punto grazie :) darò un'occhiata anche a quella!

Go Up