Due cose, EEPROM e SD

Ciao a tutti, sono ancora qui con un po' di domande stupide ]:smiley:
In particolare ho un paio di questioni sulle quali vorrei capirne un po' di più per evitare di scrivere codice per niente.

  1. Avrei necessità di salvare in eeprom dei numeri da 0 a 24 che però possono essere anche negativi.
    Ho fatto delle prove, e se metto numeri positivi nessun problema, se metto i negativi, in fase di lettura mi da
    valori diversi (problemi di segno sulla notazione binaria?).
    Per esempio, ho messo -8 e quando vado a leggere, mi restituisce 248 (256-8).
    Ho usato come tipo di dato BYTE.
    Ora, ho aggirato il problema scrivendo qualche riga di codice, però non credo sia la strada più giusta da percorrere.

  2. Come faccio a far calcolare ad arduino i numeri grrrrrrrrrrrandi???
    Devo scrivere su un display lo spazio libero disponibile di una SD che può essere da 4 o da 8Gb.
    Quindi, usando SdFat ho usato questa formula:

Serial.print(long(long(BYTEPERBLOCK)*long(vol.blocksPerCluster())*long(vol.freeClusterCount())));
Rispettivamente: 512*64*125599=4115628032 (circa 4Gb).

Il problema sta nel risultato, perchè sul display vedo un totale di: -179339264
Mi sembra che oltre a long e double non ci siano altri tipi di dati che possono rappresentare numeri di grrrrrrrrrrrandi dimensioni.
C'è una soluzione al problema oppure aspetto Arduino a 64bit? :smiley:
Grazie.
Ciao.

Stiamo parlando della EEPROM interna, giusto?

Dunque, la funzione EEPROM di scrittura accetta il tipo byte

Però, se i valori possono spaziare solo tra 0 e 24, non vedo un grosso problema. Fai come il tipo char, che usa l'8° bit come bit di segno, per cui da 0 a 24 memorizzi il numero così com'è, da -1 a -24 prendi il valore assoluto e lo sommi a 128.
abs(-10)+128=138

In fase di lettura, sottrai a 128 il numero letto ed ottieni il tuo valore: 128-138=-10

La seconda parte credo sia riferita alla gestione di numeri interi molto grandi. Ti consiglio di scaricarti la libreria AVR-Crypto lib
http://www.das-labor.org/wiki/Crypto-avr-lib

In essa c'è una libreria per la gestione di questi numeri, che lì viene usata per gli algoritmi crittografici a chiave pubblica.

alla faccia delle domande stupide, ti stai imbattendo in come lavora il C

  1. i numeri negativi sono memorizzati in un modo particolare, il complemento a due Complemento a due - Wikipedia .il byte non usa numeri negativi, e questo fa sballare il tutto. se i dati li prendi dal bite a poi li metti (usando il bitshift) all'interno del tipo di variabile originale, questa "riconoscerà" la notazione e tutto funzionerà.

  2. qui ti stai scontrando con i limiti del C. dato che ti servono solo i numeri positivi, puoi tentare di usare l'unsigned, in modo da avere il doppio della capacità. Se anche questo non basta, o ti scrivi un tuo tipo di variabile con la matematica annessa, una specie di super long, oppure usi i float (in arduino tra double e float non c'è differenza), e dato che essi memorizzano il dato in maniera esponenziale, perdi precisione ma puoi rappresentare numeri enormi. la spiegazione del perchè è quì: Numero in virgola mobile - Wikipedia

Sto soffrendo anch'io della sindrome di Calimero.

leo72:
Sto soffrendo anch'io della sindrome di Calimero.

no, ho solo precisato le motivazioni infarcendo un poco di teoria :slight_smile:

Se scrivi mezz'ora e poi Ti accorgi che qualcuno Ti ha appena fregato quasi tutte le risposte, cosa fai?
Ciao Uwe

quante volte mi è capitato! di solito modifico un poco per includere correzioni anche a chi ha risposto prima di me :grin:

Grazie a tutti delle dritte.
Allora, per la cronaca ho risolto in questo modo:

1 [PROBLEMA EEPROM]Se il numero è <= 24 lo lascio così, se è maggiore gli sottraggo 256 e funziona :wink:

2 [PROBLEMA NUMERI GRRRRRANDI] Chissà perchè cavolo non ci ho pensato prima, io non devo per forza rappresentare 4Gb come 4.192.288.727, ma bensì mi basta rappresentarlo in Mb o Gb, quindi mi basta dividere per 1000 i valori prima di fare i calcoli..... funziona :slight_smile:

Certo che a volte, anch'io ho na testa :disappointed_relieved:

Grazie ancora.

Con lUnsigned long a 4giga ci arrivi, per la divisione non sarebbe più corretto dividere per 1024 ?

Testato:
Con lUnsigned long a 4giga ci arrivi, per la divisione non sarebbe più corretto dividere per 1024 ?

Si, però se in futuro la SD dovesse essere da 8/16/32Gb ci sarebbero comunque problemi, oltre al fatto che per l'utente
è più facile leggere 4000Mb piuttosto che 4000000000 byte.
Credo sia più corretto dividere per 1000 perchè comunque io lavoro già con i dati che mi restituisce la libreria SDFat che
sono tutti multipli di 8, quindi 64/512/1024.
Lo scopo è solo quello di togliere 6 cifre dal numerone grosso.

Stefanoxjx:
1 [PROBLEMA EEPROM]Se il numero è <= 24 lo lascio così, se è maggiore gli sottraggo 256 e funziona :wink:

Non devi sottrarre nulla, definisci la variabile come char e automaticamente hai un valore a 8 bit con segno, byte è l'abbreviazione del nome standard in C di "unsigned char".

bella questa,
grazie

Questo non lo sapevo.
Grazie astro.