Sto utilizzando da poco tempo la libreria EDB su una microSD, ho fatto tutte le prove sui tipi di dati e ricerche che poi mi serviranno nell'applicazione e funziona egregiamente.
Naturalmente per popolare il database di prova ho creato i dati in maniera estemporanea all'interno del programma stesso.
Adesso il problema è il seguente: devo popolare il database con dati prelevati da un file .TXT, posso aprire contemporaneamente il file .TXT e il file di database o devo continuamente aprire e chiudere i due file per popolare il database?
Se non ricordo male è possibile aprire un solo file alla volta su Arduino, sbaglio?
crc57:
Se non ricordo male è possibile aprire un solo file alla volta su Arduino, sbaglio?
Il problema è la SRAM dove vengono allocati i buffers ...
... se ben ricordo, ogni file su SD alloca minimo un buffer da 512 Bytes ... e finire la SRAM è un attimo ... :
Guglielmo
gpb01:
Il problema è la SRAM dove vengono allocati i buffers ...
... se ben ricordo, ogni file su SD alloca minimo un buffer da 512 Bytes ... e finire la SRAM è un attimo ... :Guglielmo
La lunghezza del record del file .TXT è lunga solo 39 bytes + CR + LF sono 41 bytes. E quindi anche il record del EDB ha +o- le stesse dimensioni.
Però se il buffer che la libreria alloca è comunque 512 bytes sono problemi.
Comunque non bagniamoci prima che piova. Vi farò sapere.
P.s. I metodi: EDB_Status EDB::open(unsigned long head_ptr) e
EDB_Status EDB::create(unsigned long head_ptr, unsigned long tablesize, unsigned int recsize)
perché hanno il primo parametro = 0 ?
Qual'é il suo significato?
Grazie
crc57:
La lunghezza del record del file .TXT è lunga solo 39 bytes + CR + LF sono 41 bytes. E quindi anche il record del EDB ha +o- le stesse dimensioni.
Però se il buffer che la libreria alloca è comunque 512 bytes sono problemi.Comunque non bagniamoci prima che piova. Vi farò sapere.
P.s. I metodi: EDB_Status EDB::open(unsigned long head_ptr) e
EDB_Status EDB::create(unsigned long head_ptr, unsigned long tablesize, unsigned int recsize)
perché hanno il primo parametro = 0 ?
Qual'é il suo significato?Grazie
Intendi dire che il parametro head_ptr è sempre uguale a 0 negli esempi d'uso della libreria?
Se interpreto bene, e non sono sicuro visto che la libreria è scarsamente documentata (i commenti questi sconosciuti), quel parametro specifica il numero della tabella che intendi creare / leggere / scrivere.
db.create(0, TABLE_SIZE, (unsigned int)sizeof(logEvent));
In un esempio come quello sopra riportato: 0 è la prima tabella del database, il secondo e il terzo parametro sono rispettivamente le dimensioni della tabella e del record.
Se devo dirti tecnicamente come viene realizzato ciò, non l'ho capito quindi non so dirti :D.
krypton18:
Intendi dire che il parametro head_ptr è sempre uguale a 0 negli esempi d'uso della libreria?Se interpreto bene, e non sono sicuro visto che la libreria è scarsamente documentata (i commenti questi sconosciuti), quel parametro specifica il numero della tabella che intendi creare / leggere / scrivere.
db.create(0, TABLE_SIZE, (unsigned int)sizeof(logEvent));
In un esempio come quello sopra riportato: 0 è la prima tabella del database, il secondo e il terzo parametro sono rispettivamente le dimensioni della tabella e del record.
Se devo dirti tecnicamente come viene realizzato ciò, non l'ho capito quindi non so dirti :D.
Si, negli esempi d'uso della libreria è sempre = 0 ma provando a dargli il valore = 1 il programma non ha funzionato quindi dubito che sia quello che tu dici e che io speravo significasse.
Per quanto riguarda i parametri successivi sono d'accordo con te.
Ci sto ancora lavorando, a spizzichi e bocconi, un giorno se ho novità vi saprò dire.
Per adesso grazie e arrivederci.
crc57:
Però se il buffer che la libreria alloca è comunque 512 bytes sono problemi.
Parlo del buffer allocato dalla libreria SD per ogni file aperto ...
Guglielmo
crc57:
Si, negli esempi d'uso della libreria è sempre = 0 ma provando a dargli il valore = 1 il programma non ha funzionato quindi dubito che sia quello che tu dici e che io speravo significasse.
Per quanto riguarda i parametri successivi sono d'accordo con te.
Ci sto ancora lavorando, a spizzichi e bocconi, un giorno se ho novità vi saprò dire.
Per adesso grazie e arrivederci.
Ho trovato la discussione di un altro utente che chiedeva più o meno la stessa cosa, cioè se fosse possibile creare tabelle multiple usando la libreria EDB, a questo indirizzo:
La sua conclusione è stata che "si era scordato di incrementare l'indirizzo nell'EDB header". Poi se sia vero che ha provato e ha funzionato, non lo so.
Nel tuo caso "non ha funzionato" vuol dire che andava in errore la chiamata del metodo db.create, non faceva quello che doveva fare o che scriveva dati a caso?
Hai provato a sostituire l'indirizzo 0 con 1 senza cambiare nessun'altra istruzione nel codice? Oppure hai semplicemente aggiunto la creazione di un'ulteriore tabella con indirizzo 1 oltre allo 0?
Se posti lo sketch possiamo guardarci e fare dei test.
Per esempio ci sono dei flag che ti restituiscono lo stato del metodo utilizzato:
enum EDB_Status {
EDB_OK,
EDB_ERROR,
EDB_OUT_OF_RANGE,
EDB_TABLE_FULL
};
EDB_Status create(unsigned long, unsigned long, unsigned int);
Con le istruzioni sottocitate, si potrebbe avere qualche indizio in più su cosa succede effettivamente dopo l'utilizzo del metodo db.create :
EDB_Status result = db.create(1, TABLE_SIZE, RECORD_SIZE);
switch (result)
{
case EDB_OUT_OF_RANGE:
Serial.println("Recno out of range");
break;
case EDB_TABLE_FULL:
Serial.println("Table full");
break;
cae EDB_ERROR:
Serial.println("Error");
break;
case EDB_OK:
default:
Serial.println("OK");
break;
}
Chiaramente dovresti usare il monitor seriale per poter visualizzare l'output.
Grazie krypton18, per il momento avevo la necessità di popolare una tabella EDB con i campi presi da un file .TXT.
Sono riuscito nel mio intendo.
- Ho preparato il file .txt di 1000 record 3 campi per un totale di 40 byte preordinati rispetto al campo che poi avrei utilizzato come chiave di ricerca.
- Ho popolato la tabella EDB, approssimativamente, in 15 minuti.
- Le ricerche, in modalità dicotomica, sono invece eccezionali, in meno di 60 ms si riescono a trovare i records cercati. (come da manuale il numero di ricerche = Logaritmo in base 2 del numero degli elementi, nel caso di 1000 elementi il massimo è 10 ricerche).
- Se la tabella EDB invece è già creata devo solo aprirla ed utilizzarla.
Prossime prove: Arduino DUE e aprire più tabelle.
Grazie a tutti
Per popolare ho utilizzato ...
const char PIPE = 124;
...
Serial.print(F("Popolamento DB ... "));
String StrLet;
StrLet.reserve(TxtLunRec);
txFile.seek(0);
while (txFile.available()) {
StrLet = txFile.readStringUntil(LF);
RecToCampo(StrLet);
NewRecord();
}
dbFile.close();
...
void RecToCampo(String StrRic) { // Riceve una stringa e riempie la struttura da riempire
int pospip;
pospip = StrRic.indexOf(PIPE);
strcpy(Record.BoloRum, (StrRic.substring(0, pospip)).c_str());
StrRic.remove(0, pospip + 1);
pospip = StrRic.indexOf(PIPE);
strcpy(Record.CodAur, (StrRic.substring(0, pospip)).c_str());
StrRic.remove(0, pospip + 1);
strcpy(Record.CodAzi, StrRic.c_str());
}
...
boolean NewRecord(void){
EDB_Status result = db.appendRec(EDB_REC Record);
if (result == EDB_OK) return true;
printError(result);
return false;
}
log21000=9,965...
Mentre la ricerca dicotomica ...
unsigned long CercaBoloBin(String Cerca) {
unsigned long Min, Max, Med;
unsigned long Start = millis();
int NumRic = 0;
Serial.print(F("Ricerca del bolo ... "));
Serial.print(Cerca);
Min = 1;
Max = db.count();
while (Min <= Max){
Med = int((Min + Max) / 2);
EDB_Status result = db.readRec(Med, EDB_REC Record);
NumRic++;
if (result == EDB_OK) {
if (String(Record.BoloRum) == Cerca) {
Serial.print(F(" ["));
Serial.print(millis() - Start);
Serial.print(F("]"));
Serial.print(F(" {"));
Serial.print(NumRic);
Serial.print(F("}"));
Serial.print(F(" ...record n° "));
Serial.println(Med);
return Med;
}
if (String(Record.BoloRum) > Cerca) {
Max = Med - 1;
}
else {
Min = Med + 1;
}
}
}
Serial.println(F(" ... NON trovato"));
return 0;
}