home | area personale         schemi | tutorial | robotica | pic micro | recensioni         forum | chat irc         faq | contatti         store | Ordina PCB
username
password
cerca

 
FORUM: Pic Micro
Tutto quanto riguarda questi microprocessori... progetti, suggerimenti, aiuti, discussioni...ecc


Precisione float con Arduino
     
Autore Messaggio opzioni
MB54




una ogni 100 livelli


postato il:
25.02.2019, alle ore 16:38
Precisione float con Arduino 

segue...
MB54




una ogni 100 livelli


postato il:
25.02.2019, alle ore 16:38
MB54:
segue...


Per semplicità di comunicazione con un display Nextion vorrei usare Arduino (Nano) per comandare un DAC a 18 bit, f.s. 4.096 V

I valori da impostare sul DAC li invio come interi (long) e non c'è problema.

Il mio problema è come convertire un numero float (impostato manualmente da tastiera o altro ed é la tensione voluta all' uscita del DAC), in un LONG da mandare all' Arducoso.

La risoluzione nominale in tensione del DAC è di 15,25878906... µV per ogni LSB di variazione.
Il problema è che per Arduino sia le variabili float che double sono a 32 bit e quindi per entrambe la precisione é di 6-7 digit complessivi ( non chiaro se sono 6 o 7), Questi 6 o 7 digit comprendono sia i digit prima che dopo la virgola.
https://www.arduino.cc/reference/en/language/variables/data-…

Quindi, ad esempio, se volessi 3.254253 V nominali all' uscita, Arduino dovrebbe fare il seguente calcolo:

3.254253 / 0.00001525879 = 213270.7 -> arrotondato a 213271

Avrei quindi bisogno di 7 cifre significative effettive, meglio 8 meglio ancora 9: già il DAC avrà le sue imprecisioni e non linearità: vorrei non aggiungerne altre dovute ai calcoli.

Ho visto questa libreria, nata per i numeri molto grandi:
https://www.gammon.com.au/forum/?id=11519
ma che mi pare funzioni anche con numeri float.

Qualche esperienza in merito o altre soluzioni? La velocità di calcolo non è un problema....
Grazie
Mauro
picmicro675




una ogni 10 livelli


postato il:
26.02.2019, alle ore 08:05
Se sei sotto i 4 miliardi (ovvero 2^32) puoi moltiplicare e dividere entro quei limiti. Forse si scomoda meno programmazione che con i float.
3.254253 / 0.00001525879 = 213270.7 -> arrotondato a 213271

3.254253 * 1e9 / 0.00001525879 * 1e9 = 3254253000 / 15288 = 212863,22606 arrotondato a 212863

Solo la precisione si perde comunque, un computer lavora solo in notazione binaria. Ancor peggio se è a solo 8bit.
Forse ti conviene un Espressif a 32 bit, sempre nella misura dello stesso costo.



Anno nuovo, forum nuovo.
Mi sa che lascio.
MB54




una ogni 100 livelli


postato il:
26.02.2019, alle ore 11:18
picmicro675:

Solo la precisione si perde comunque,


Purtroppo la precisione è fondamentale, mentre la velocità é ininfluente


picmicro675:

Forse ti conviene un Espressif a 32 bit


Ho visto che l' argomento double float è molto piu' complesso di quello che immaginavo; oltre all' HW anche il compilatore deve essere idoneo.

Il budget non cambia molto fra 8 e 32 bit e l' uso di un 32b potrebbe essere una soluzione; alla fine mi interessa solo il risultato. Ho un Arduino M0 e vari espressif inutilizzati nei cassetti, devo però verificare le compatibilità dei livelli elettrici per i bus, i pin disponiibli e soprattutto se funzionano le librerie per il Nextion: è un periodo che ho poco tempo e non potrò metterci troppo per scrivere il codice (quindi niente STM32 con double HW ) .

In linea generale preferirei prima provare il Nano con le librerie che ho trovato, o altre equivalenti
https://www.arduino.cc/reference/en/language/variables/data-…
https://github.com/mmoller2k/Float64

Scontato il funzionamento, dovrò vedere quanta RAM lasciano libera; come detto la velocità non importa, per una divisione ci può mettere anche centinaia di mS: l' importante è la precisione

MB54




una ogni 100 livelli


postato il:
26.02.2019, alle ore 14:07
Ho provato la libreria di Nick Gammon, che consente di gestire numeri enormi, dl tipo 2^100.
https://www.gammon.com.au/forum/?id=11519

Non funziona con divisioni fra float ma solo con interi. Comunque esprimendo le tensioni del divisore e del dividendo in nV (nanoVolt !!! ) fa i calcoli correttamente

a= 3254253000 nanovolt voluti
b= 15625 nanovolt per ogni LSB

c= a/b= 208272 LSB da comunicare al DAC

Poichè prevedo un max di 15V (15000000000 nV) ci sto abbondantemente.
L' unico inconveniente è che arrotonda sempre per difetto, cosa non grave e facilmente superabile esprimendo 'a' in decimi di nV.

L' impiego di risorse è minore del previsto. La sola divisione richiede circa 5000 byte di RAM, circa il 15-18% di quella disponibile. Operazioni piu' complesse consumano circa il 30% della RAM. Calcolo rapidissimo per le esigenze.
Direi quindi che la libreria di Gammon fa quello che mi serve, proverò poi l' altra libreria e/o altre che riuscirò a trovare.

Grazie
shsjk59456




una ogni 10 livelli


postato il:
01.03.2019, alle ore 17:57
Che tipo di DAC usi? certo con una risoluzione di 15uV devi avere un circuito professionale moolto fitrato e schermato.
Per i calcoli in virgola mobile io la vedo + semplicemente modificando la virgola come facevo una volta quando non esistevano i float:
Es. 3.254253 / 0.00001525879 = 213270.7 -> arrotondato a 213271
Cosi: 3254253 / 15.25879 = 213270 sposti la vigola di sei posti perdi solo i dec.
altrimenti sposti di sette: 32542530 / 152.5879 = 213270,7
Vedi se ti va bene.
BYE



Free
MB54




una ogni 100 livelli


postato il:
01.03.2019, alle ore 18:49
shsjk59456:
Che tipo di DAC usi? certo con una risoluzione di 15uV devi avere un circuito professionale moolto fitrato e schermato.

Due AD5680, a 18 bit.
Il circuito sarà estremamente filtrato e ben schermato.Mi aspetto qualche decina di nV di rumore a 100 Hz all' uscita dell' alimentatore per gli stadi analogici. Prevedo dopo la stabilizzazione di usare 2 di questi filtri shunt: il primo per alimentare il Vref (Maxim MAX6341) dal quale derivare anche i 5V con un LDO a basso rumore per i dac, ed un secondo per uno dei due canali di uscita (che dovrà amplificare 4-5x ):
http://www.wenzel.com/documents/finesse.html

Per le uscita dei due dac userei circuiti tipo il primo di questa pagina:
http://mihalcz.ingyenweb.hu/keret.cgi?/other/ulnreg.html
Un canale x1 senza mos in uscita, per 0-4V ed un canale 4 o 5x con MOS finale(0-12 o 15 V).
Per entrambe i canali Userei un filtro RC fra DAC e opamp attorno ai 10 Hz, che penso possa essere un buon compromesso fra rumore ed un minimo di velocità.

Il tutto termostatato sui 40°C, per levarmi dubbi e problemi.


[quote](shsjk59456):
Per i calcoli in virgola mobile io la vedo ....

Cosi: 3254253 / 15.25879 = 213270 sposti la vigola di sei posti perdi solo i dec.
altrimenti sposti di sette: 32542530 / 152.5879 = 213270,7
BYE


non ho capito, mi pare che tu usi sempre un float a 32b e quindi 6 forse 7 digit. Inoltre devo prevedere un dividendo fino a 12000000 µV (12-15 V), sia pure con un divisore sui 60 µV circa. Devo anche lasciarmi un poco di margine poter compensare qualche non linearità del DAC o per l' ampli del canale amplificato..
MB54




una ogni 100 livelli


postato il:
01.03.2019, alle ore 18:52
quotato male

shsjk59456:
Che tipo di DAC usi? certo con una risoluzione di 15uV devi avere un circuito professionale moolto fitrato e schermato.



Due AD5680, a 18 bit.
Il circuito sarà estremamente filtrato e ben schermato.Mi aspetto qualche decina di nV di rumore a 100 Hz all' uscita dell' alimentatore per gli stadi analogici. Prevedo dopo la stabilizzazione di usare 2 di questi filtri shunt: il primo per alimentare il Vref (Maxim MAX6341) dal quale derivare anche i 5V con un LDO a basso rumore per i dac, ed un secondo per uno dei due canali di uscita (che dovrà amplificare 4-5x ):
http://www.wenzel.com/documents/finesse.html

Per le uscita dei due dac userei circuiti tipo il primo di questa pagina:
http://mihalcz.ingyenweb.hu/keret.cgi?/other/ulnreg.html
Un canale x1 senza mos in uscita, per 0-4V ed un canale 4 o 5x con MOS finale(0-12 o 15 V).
Per entrambe i canali Userei un filtro RC fra DAC e opamp attorno ai 10 Hz, che penso possa essere un buon compromesso fra rumore ed un minimo di velocità.

Il tutto termostatato sui 40°C, per levarmi dubbi e problemi.


shsjk59456:

Per i calcoli in virgola mobile io la vedo ....

Cosi: 3254253 / 15.25879 = 213270 sposti la vigola di sei posti perdi solo i dec. ..altrimenti sposti di sette: 32542530 / 152.5879 = 213270,7



non ho capito, mi pare che tu usi sempre un float a 32b e quindi 6 forse 7 digit. Inoltre devo prevedere un dividendo fino a 12000000 µV (12-15 V), sia pure con un divisore sui 60 µV circa. Devo anche lasciarmi un poco di margine poter compensare qualche non linearità del DAC o per l' ampli del canale amplificato..


shsjk59456




una ogni 10 livelli


postato il:
01.03.2019, alle ore 22:08
Il primo e' un intero 3254253 mentre l'altro in virgola mobile 15,25879 ha sette cifre quindi e' gestibile dalla variabile float, almeno da quanto dicono, io personalmente non le ho mai usate.


Free
MB54




una ogni 100 livelli


postato il:
02.03.2019, alle ore 05:17
shsjk59456:
.... ha sette cifre quindi e' gestibile dalla variabile float, almeno da quanto dicono, io personalmente non le ho mai usate.


Purtroppo per float32 dicono 6-7 digit: indicazione riportata in centinaia di pagine senza però specificare quando sono 6 e quando sono 7; presumo dipenda dalla posizione della virgola. A me ne servono almeno 7, 6 non va bene.

Mi sembra inutile comunque approfondire quando sono 6 e quando 7: la libreria di Gammon linkata consente di usare numeri molto grandi (es 2^200, 60 digit, ma anche molti più digit), ho visto che la divisione non occupa molto spazio ed é rapida per l' utilizzo, l' Arducoso ha ben poche altre cose da fare per cui può gestire tranquillamente il tutto.

Quando sarà il momento di scrivere il codice, farò il calcolo a 8 digit e poi arrotondo.
Grazie
segui questo thread con grixFC, per questa funzione devi aver installato il software grixFC

torna su
     

Come utente anonimo puoi leggere il contenuto di questo forum ma per aprire una discussione
o per partecipare ad una discussione esistente devi essere registrato ed accedere al sito




 







 
 
indietro | homepage | torna su copyright © 2004/2024 GRIX.IT - La community dell'elettronica Amatoriale