c'e qualcuno che mi puo' dare un indicazione per come fare una funzione che mi dica se dei valori sono commensurabili tra loro (magari indicando un tot di scostamento +/- ammissibile ) ?
Ovviamente i valori "buoni" sono la maggioranza, diciamo almeno un 60 % (o >)
Per chiarezza mi spiego meglio..
ho un tot di letture analogiche, diciamo 10, e vorrei fare una funzione che mi restituisca la media dei soli valori commensurabili tra loro, scartando quelli "fuori".
per esempio se leggo:
678 675 680 677 681 677 679 675 679 680
e' chiaro che sono simili e la media e' semplice da fare
ma se leggessi :
121 675 680 234 681 677 679 675 679 680
io vorrei avere la media dei soli valori -> 675 680 681 677 679 675 679 680, scartando i 2 "fuori" : 121 e 234
Mi sono arenato perche io non so a priori quale sia la lettura "centrale", che puo' essere qualunque tra 0 e 1023...
come prima cosa il / i valori sballati potrebbero anche essere piu' alti,o un misto tra piu' alti e piu' bassi ma a parte questo facendo una prova come dici tu verrebbe fuori:
Innanzitutto conviene scartare la prima che potrebbe esser influenzata da un errato tempo di conversione del ADC.
Poi memorizzi in un vettore i rimanenti 9 campioni ed esegui la media aritmetica.
Con un loop confronti ciascun campione con la media ottenuta e scarti quelli si scostano dal valore oltre una percentuale da te predefinita (intervallo di confidenza).
Supponendo che siano scartati un paio di campioni, riesegui la media dei rimanenti 7.
confronto il 675 con 587 .. 88 di differenza..
confronto il 680 con 587 .. 93 di differenza..
confronto il 681 con 587 .. 94 di differenza..
confronto il 677 con 587 .. 90 di differenza..
.....
confronto il 121 con 587 .. 466 di differenza..
confronto il 234 con 587 .. 353 di differenza..
a occhio e' chiaro che vanno scartati gli ultimi 2, ma come faccio a metterlo in una funzione ??
non posso impostare a priori un numero o una percentuale di scostamento, perche la media matematica potrebbe essere molto piu' bassa (o alta) influenzata da 3 o 4 campioni completamente sballati (per esempio uno zero..)
In questo caso gia' se impostassi di scartare quelli sopra al 10 % della media (che e' tanto..)(circa 60) matematicamente li scarterei tutti..
In questo caso specifico perche' funzioni dovrei tenere buono uno scarto fino al 15 % minimo.. ma la prossima serie potrebbe essere anche piu' lontana (o vicina) dalla media.
non mi sembra la strada giusta.. sempre se ho capito cio' che intendevi..
se io dopo aver confrontato tutti i campioni con la media mi estraggo il valore piu' basso dello scarto (in questo caso 88) e prendo questo valore come unita' di riferimento,
poi potrei nuovamente confrontare la differenza dei campioni con questo 88 e tenere tutti i campioni che sono tra 88 ed un 88+X che posso decidere come scarto massimo.
Se impostassi questo X a "8" per esempio, automaticamente prenderei come buoni tutti i valori che come differenza dalla media vanno da 88 a 96
vedendo le cifre di prima in effetti riuscirei a scartare con una buona approssimazione solo i valori piu' "lontani"..
Adesso faccio un paio di prove e vedo come si comporta con i valori "negativi" cioe' distanti in piu' invece che in meno...
In quel caso credo basti prendere il numero senza segno, cioe' il valore assoluto per fare il confronto...
che dici ??
Puo' funzionare ??
controindicazioni o errori prevedibili ?
int Misura[10] = {675, 680, 681, 677, 679, 675, 679, 680, 121, 234};
int M; // media
int MF; // media finale
const byte P = 20; // percentuale 20%
int Delta; // delta percentuale
for (byte I = 0; I < 10; I ++) {
M += Misura[I];
}
M /= 10;
Delta = M * P / 100;
byte J = 0;
for (byte I = 0; I < 10; I ++) {
if (abs(Misura[I] - M) < Delta) {
MF += Misura[I];
J ++;
}
}
MF /= J; // Media finale
Hai ragione, ragionando cosi funzionerebbe se tutti i valori buoni fossero superiori alla media, ma la casualita' potrebbe benissimo farmi avere dei valori errati anche superiori..
es:
121 675 680 754 681 677 679 810 679 680
avrei bisogno di un "algoritmo" per scartare comunque il 121, il 754 ed il 810
@ cyberhs :
quello che avevo messo giu' temporaneamente dopo il ragionamento di ieri era molto piu' "complicato"..
Stasera quando rientro a casa e sono tranquillo ragiono sulla tua soluzione.. intanto grazie
@ uwefed :
In questo momento sto misurando della corrente elettrica (mA), ma la linea e' soggetta ad alcuni spike "lenti" positivi e negativi rispetto alla corrente nominale, dovuti a disturbi elettrici causati da qualsiasi cosa posa essere.
Questo mi provoca dei picchi appunto, casuali e non frequentissimi, che pero' possono durare anche qualche centesimo di secondo, quindi la sfortuna vuole che campionando a caso anche ogni x secondi prima o poi un disturbo (o un paio/tre) lo posso beccare
In ogni caso questa funzione potrebbe essere comoda anche in caso di letture di luminosita' tramite fotoresistenza, per eliminare falsi positivi dovuti a fari delle macchine di passaggio, fulmini etc...
axl936:
@ simone :
Hai ragione, ragionando cosi funzionerebbe se tutti i valori buoni fossero superiori alla media, ma la casualita' potrebbe benissimo farmi avere dei valori errati anche superiori..
@axl un pò di "elasticità" mentale non guasta.
Logicamente elimini sia quelli sotto la media che quelli sopra la media.
Come detto anche da @cyberhs comunque DEVI stabilire una percentuale oltre la quale i valori li vuoi scartare.
Comunque matematicamente anche la soluzione di @cyberhspotrebbe avere problemi. Tutto okay se i valori sporchi sono pochi rispetto a quelli buoni. Ma facendo la prima volta la media e contando anche quelli "sporchi" la media potrebbe essere "deviata" di molto e quindi prenderemmo per buoni anche valori "sporchi".
Qui una "soluzione" statistica che però complica un pochetto rispetto alla soluzione proposta da @cyberhs: http://ishtar.df.unibo.it/stat/avan/misure/criteri/chauvenet.html
P.S. non sarebbe meglio porre una soluzione hardware ?
Hai ragione per l' elasticita' mentale.. ma ti posso assicurare che la mia risposta e' dovuta al fatto che non saprei come fare.. non volevo assolutamente minimizzare la proposta di simone.. o avere la soluzione pronta senza sbattermi .. proprio non risco ad arrivarci..
...La media e' inferiore alla maggior parte dei valori, quindi scartando i valori inferiori alla media scarto i valori errati piu' bassi..
Ma nel caso ci siano anche dei valori errati piu' alti, non saprei come fare per scartarli sen non come suggeriva cyberhs , perche sia quelli, sia quelli buoni sono superiori alla media..
Torno nella situazione di dover capire quale sia il "valore guida" dei valori buoni, che a occhio salta subito fuori, ma come funzione e' proprio il motivo per cui chiedo aiuto..
Per sa soluzione hardware ... ok, mi piaceva farlo software .. creando una funzione che fa' come quello che farei ad "occhio"..
Adesso sto pensando come fare a stabilizzare la lettura di una fotoresistenza, per esempio... non so .. con dei condensatori abbastanza grossi da livellare la tensione in uscita.. in modo che non cambi con variazioni brusche..
Altrimenti soluzioni piu' efficaci non ne saprei pensare ...
E per la corrente non avrei assolutamente idea di come fare..
Tieni conto che rispetto al codice di @cyberhs, lo complicherebbe e rallenterebbe un pochetto (si calcola anche la deviazione standard, portando a valori float piuttosto lenti).
Se hai problemi di velocità e i valori "sporchi" sono comunque pochi il codice suggerito basta e avanza.
Ho fatto alcune prove con il codice di cyberhs e con una brutta implementazione della tecnica del link indicato da nid69ita...
Alla fine , prove sul campo non mi vale la pena introdurre la complicazione del calcolo della deviazione standard..
In effetti i campioni da scartare sono pochi rispetto al totale di campioni e sono abbastanza lontani, quindi gia il codice di cyberhs va piu' che bene..
In questo momento sto misurando della corrente elettrica (mA), ma la linea e' soggetta ad alcuni spike "lenti" positivi e negativi rispetto alla corrente nominale, dovuti a disturbi elettrici causati da qualsiasi cosa posa essere.
Questo mi provoca dei picchi appunto, casuali e non frequentissimi, che pero' possono durare anche qualche centesimo di secondo, quindi la sfortuna vuole che campionando a caso anche ogni x secondi prima o poi un disturbo (o un paio/tre) lo posso beccare
In ogni caso questa funzione potrebbe essere comoda anche in caso di letture di luminosita' tramite fotoresistenza, per eliminare falsi positivi dovuti a fari delle macchine di passaggio, fulmini etc...
grazie a tutti
Questo mi procupa.
Se misuri una corrente e poi hai un abbassamento a un quarto del valore medio secondo me non puó essere un disturbo nella corrente ma nella misura.
Ciao Uwe