Newsgroup: it.hobby.elettronica.digitale
Titolo: Vi faccio un regalino...

Ciao a tutti,
visto che ne abbiamo parlato ultimamente, oggi mi sento magnanimo e vi 
faccio un regalino: 2 funzioni scritte in C per calcolare sia la media sia 
la mediana, che incorporano anche una funzione di acquisizione, che ho 
chiamato "ADC_READ()"
Il bubble sort č scopiazzato non so dove ma funziona: ho messo il bubble 
perchč spesso e volentieri la ricorsione č vietata (es. PIC)
Il codice č testato e funzionante, se qualcuno vuol consigliare come 
migliorarlo faccia pure! La funzione che fa la media č leggermente 
ottimizzata, perň ha dei limiti: 2^16 > (2^risoluzioneADC * numero dati 
della media)
unsigned char = BYTE
unsigned int = WORD (2 byte)
Enjoy!
---
unsigned int AverageAcquire (unsigned char ucANChannel) {
    unsigned int uiTemp = 0;
    unsigned char i;
    //ACQUISIZIONE (OTTIMIZZATA)
    for (i = 0; i < c_AveragesNumber; i++) {
        uiTemp += adc_read(ucANChannel);
    }
    //MEDIA
    uiTemp /= c_AveragesNumber;
    return uiTemp;
}
unsigned int MedianAcquire (unsigned char ucANChannel) {
    unsigned int uiTempData[c_AveragesNumber];
    unsigned int uiTemp;
    unsigned char i, j, flag = 1;
    //ACQUISIZIONE
    for (i = 0; i < c_AveragesNumber; i++) {
        uiTempData[i] = adc_read(ucANChannel);
    }
    //BUBBLE SORT
    for(i = 1; (i < c_AveragesNumber) && flag; i++) {
        flag = 0;
        for (j = 0; j < (c_AveragesNumber - 1); j++) {
            if (uiTempData[j+1] > uiTempData[j]) {             // ascending 
order simply changes to <
                uiTemp = uiTempData[j];                        // swap 
elements
                uiTempData[j] = uiTempData[j+1];
                uiTempData[j+1] = uiTemp;
                flag = 1;                                      // indicates 
that a swap occurred.
            }
        }
    }
    //RITORNA IL VALORE AL CENTRO DEL VETTORE (MEDIANA)
    return uiTempData[(c_AveragesNumber / 2)];
}
------
Ciao
CG 

 }
Anche qui lo stesso discorso delle N (c_AveragesNumber) acquisizioni 
fatte tutte insieme che possono rallentare di molto la funzione.
In entrambi i casi, poi, hai una velocità dell'ADC N volte inferiore. Se 
riesci a campionare hw a 1kHz e N=10, non avrai più di 100 campioni al 
secondo. Mi sembra uno spreco hw.
Io avrei provato a fare una funzione che, ad ogni chiamata, esegue 
l'acquisizione del prossimo campione (uno solo) e tira fuori il valore 
mediano o media considerando gli altri N-1 bufferizzati.

 }
Tra l'altro non ï¿œ necessario fare il sort di tutto l'array, visto che ti 
serve il solo elemento centrale. Basta fare il lavoro a metï¿œ :-)
Sinceramente non so se il bubble sort oppure qualche altro algoritmo di 
ordinamento. Per esempio, si potrebbe usare qualche algoritmo che 
funziona bene per array quasi ordinati (ora non mi vengono in mente i nomi).
Il successivo campione andrï¿œ a sostituire l'ultimo elemento dell'array 
ordinato al passo precedente. Praticamente l'array sarï¿œ ordinato eccetto 
l'ultimo elemento e l'ordinamento sarebbe molto piï¿œ veloce.
L'unica cosa negativa ï¿œ che andiamo a sovrascrivere un valore che 
potrebbe non essere il piï¿œ remoto, ma non penso sia un grosso problema.

 non essere il più remoto, ma non penso sia un grosso problema.
L'idea era di tirar fuori un paio di funzioni per fare questi tipi di 
filtraggio.
Parlo di ciclo "ottimizzato" perchè la funzione si occupa di interrogare 
l'adc, so benissimo che tra un ciclo e l'altro ci sarà l'attesa del 
completamento delle conversioni: riempire il vettore da un'altra parte e poi 
chiamarci un ciclo sopra sarebbe stato più dispendioso, mentre in quel modo 
risparmio 1 array da N word.
Le funzioni sono ottimizzabilissime, le ho scritte in 10 minuti!
Ciao
CG


ricorsione & iterazione sono reversibili.
Se posso implementare un algoritmo ricorsivamente
lo posso fare anche in modo iterativo :-)
A.

 migliorarlo faccia pure!
c_AveragesNumber si dovrebbe chiamare c_AveragesCount

 lo posso fare anche in modo iterativo :-)
Certo, infatti ho scritto che viene "decente".
Prova a scrivere un quicksort in forma iterativa... anzi... va bene anche un 
mergesort!
Ti ricordo che, in questo caso, l'ordinamento è da fare su una decina di 
elementi, al massimo 20, quindi è preferibile un'implementazione semplice 
piuttosto che un algoritmo bello dall'implementazione incasinata
Ciao
CG 

 c_AveragesNumber si dovrebbe chiamare c_AveragesCount
vero... e non ho detto che è una costante esterna :P
Ciao
CG 

CG Audio Laboratories:

Spero fosse evidente a tutti.
La sola cosa che tradisco di K&R sono le parentesi a capo e le costanti
tutte maiuscole. E quindi, essendo la sola, è 'na sola.
Ps. ma come fanno i komunisti a non ritirare "chiss' o' fà, il sofà, s'o
fà"?
Ora ce ne hanno cento, sulla mia schiena, in effetti sono "entitled" a
spararcelo in bocca. Eccianno raggione loro.

 usarla).
In realtà ci sono tanti algoritmi di ordinamento che è possibile 
implementare in modo "decente" in forma iterativa.
Per esempio, l'insertion sort che dovrebbe funzionare molto bene per 
array piccoli, come nel nostro caso.