Newsgroup: it.comp.lang.c
Titolo: array e tabelle in c

Ricevo su un microcontrollore un valore di tensione su un adc 
corrispondente ad una temperatura.
io conosco i passi di adc corrispondenti ad ogni temperatura.
anziche' salvare il valore per comparazione come segue usando un casino 
di if,è possibile creare un'array o una tabella per fare la stessa cosa
ma in modo piu' elegante e compatto ?
if (valoreadc) == 250 ) temperatura = 22; //22°C
if (valoreadc) == 235 ) temperatura = 21; //21°C
etc.......(devo convertire circa 100 valori adc)
Grazie anticipatamente
PippoPippo


a parte che metterei, al posto di:
if (valoreadc == 250 ) temperatura = 22;
if (valoreadc == 235 ) temperatura = 21;
if etc.etc.
qualcosa tipo:
if (valoreadc == 250 ) temperatura = 22;
else if (valoreadc == 235 ) temperatura = 21;
else etc.etc.
in modo da non controllare tutti i valori di (valoreadc) ma solo
dall'inizio fino al valore ottenuto (riservandoti la possibilità di di
mettere prima i valori più probabili di temperatura, in modo da
ridurre statisticamente il numero di controlli).
Se non ti interessano i cicli macchina o la memoria utilizzata certo,
puoi usare un'array statico. La cosa più logica sarebbe, visto che hai
uno step di un grado sul risultato, utilizzare la temperatura come
indice dell'array. Se le temperature vanno da 0 a 22, per esempio,
definisci l'array come int valoreADC[23] = { 100, 130, ... , 235,
250 }; e poi fai un for() da 0 a 22 per trovare l'indice giusto.
Ovviamente se non parti da 0 dovrai sommare o sottrarre ogni volta che
utilizzi l'indice la cifra esatta: se vanno da -10 a 22, la
temperatura di 0 gradi sarà all'indice 10.
Se lo stepping non è di un grado ma di mezzo puoi moltiplicare e
dividere per due gli indici, e così via - insomma se vuoi usare
un'array preparati ad usare qualche "trucchetto" per far quadrare il
tutto.
Ciao!

Grazie mille!
ciao
PippoPippo
fma...@gmail.com
 ha scritto:


 poi fai un for() da 0 a 22 per trovare l'indice giusto.
Abbastanza inefficiente e brutto...
E' un semplice problema matematico.
Basta riscalare il valore dell'adc sul range delle temperature.
Un'addizione e una divisione...

La conversione temperatura/tensione non è lineare,non si puo' fare come 
dici tu camillo.
ciao
PippoPippo
camillo ha scritto:


 dici tu camillo.
In effetti mi era venuto il sospetto dopo aver postato... reminescenze di 
elettronica scolastica... E probabilmente stai anche lavorando su 
hardware senza una FPU immagino, altrimenti portesti riscalare anche se 
la curva fosse quadratica. Ma comunque, tornando alle lookup table...
I valori dell'ADC avranno un Bias immagino. Lo sottrai e usi il risultato 
come indice in un array con le rispettive temperature. I valori intermedi 
li puoi sempre interpolare.

 > 
fmas...@gmail.com
:


 for)
In ogni caso anche utilizzando il for puoi mettere un break :) quindi
solo il caso peggiore è lo stesso. Il caso migliore idem. L'unica
differenza è che con gli if puoi decidere in maniera più semplice
qual'è il caso (o i casi) più ricorrenti. Anche io quindi sono per gli
if.
So che è bruttissimo da vedere, ma queste cose nella programmazione
per micro sono comuni (come fare un file separato chiamato
conversione.c contenente solo la funzione di conversione e cercare di
dimenticarsi della sua esistenza :D ).

 table... 
dipende quant'e' la non linearita'.
io ho progetti in cui uso un NTC per misurare la temperatura, e nel range 
di utilizzo la curva dell'NTC e' lineare quanto serve da avere la 
precisione che mi serve con una regressione lineare.
L'FPU non serve se fai calcoli su interi (o a precisione finita). L'unico 
handicap e' che ci mette tempo a calcolare la radice quadrata per risolvere 
l'equazione di secondo grado.
 
Ciao Jack
-- 
http://motoko.dyndns.org

Come pippano spazio i compilatori c per i microcontrollori,mamma mia 
,siamo al 30% circa rispetto all'assembly.
ciao
fma...@gmail.com
 ha scritto:


>     
Un sistema č quello di avere un atabella  a due posizioni,
la prima contiene il valore ADC e la seconda il valore
associato.
Una funzione fa un loop da 0 a MAX_PUNTI e trova
la posizione del valore adc in tabella, quindi ritorna
il valore associato...
Esempio (non testato):
typedef struct tabella{
   unsigned short adc;
   unsigned shoer val;
}TAB_T;
/*
* Tabella adc<->valore, ordinata per valori crescenti
* Usare un numero pari di coppie...
*/
static
const TAB_T  TAB[100]={
    {10, 10},
    {10,  20},
      ,....,
};
#define MAX_ADC  (sizeof(TAB))/(sizeof(TAB[0])
unsigned short get_val(unsigned short adc)
{
    unsigned short val;
    unsigned short val2;
    val= 0; /* Default value */
    for(j=0; j < (MAX_ADC-1); j+=2)
    {
          if((adc >= TAB[j].adc) && (adc <= TAB[j+1].adc))
          {
              /* Punto adc nel range   */
               val = TAB[j].val;           /* Primo punto */ 
 
               val2= TAB[j+1].val;   /* Secondo punto */
               /* interpolazione lineare tra val e val2 o altra 
compensazione ... */
               val= ................;
                break;
           }
    }
   return(val); /* value */
}
B.

Gentile fmassei,
grazie prima di tutto per l'esaustiva risposta :)
sto' optando per fare un'array con il for perchè devo fare delle 
operazioni particolari.
Non ho chiara una cosa che hai detto:
Quando dici: "Se non ti interessano i cicli macchina o la memoria 
utilizzata certo, puoi usare un'array statico."
Sono d'accordo per i cicli macchina, ma per la memoria tu intendi
ram o rom?
perche' se dichiaro l'array come costante
(unsigned const 16 array[100] = {300,300,etc...}) dovrebbe
scriverlo nella rom(devo solo leggerlo) e la ram dovrebbe lasciarla
libera.
Sei d'accordo ?
grazie per la delucidazione
PippoPippo
fma...@gmail.com
 ha scritto:



Ciao!

Grazie :)
PippoPippo
brix99luftballons ha scritto:


Se la memoria non è un problema, e non hai necessità di interpolare, e
i valori provenienti dall'ADC sono di 8bit, puoi realizzare una
tabella utilizzando il valore di tensione come indice; dovresti quindi
preparare un vettore di 256 posizioni, ed inizializzarlo in modo che
    tabella_temperature[valoreadc] = temperatura
nei casi che hai esposto, in posizione 250 inseriresti un 22, in
posizione 235 un 21, e così via...
nel codice, una volta istanziata la variabile valoreadc, la
temperatura la ottieni con un semplice:
    temperatura = tabella_temperature[valoreadc];
Spero di essere stato chiaro.