Hallo!
Ich benutze das Board STM32F407 und A/D-wandle mit 12-Bit eine
Potispannung. Aus dem A/D-Wert möchte ich einen Wertebereich von 0…20
realisieren. Dieser Wert soll dann binär auf 5 in Reihe gelöteten LEDs
ausgegeben werden und gleichzeitig zum Einstellen eines anderen
(Kraft-)Wertes dienen. Mein erster Ansatz war einfach den A/D-Wert durch
200 zu teilen: 0…4095 / 200 = 0…20. Diese Lösung hat sich aber schnell
als ungenügend bewiesen, da beispielsweise Werte zwischen 399…401 / 200
aufgrund des Rauschens vom A/D-Wandler ständig toggeln. Dann habe ich
den Ansatz über eine Mittelwertbildung probiert:
1
uint16_tCalculate_Force(uint16_tadc_value)
2
{
3
staticuint16_tcalc_tmp=0,i=0;
4
staticuint16_tval_array[100];
5
staticuint32_tmean_value=0;
6
7
if(i<=100)
8
{
9
val_array[i]=adc_value;
10
i++;
11
12
if(i>=100)
13
{
14
i=0;
15
while(i<=100)
16
{
17
mean_value+=val_array[i];
18
i++;
19
}
20
calc_tmp=mean_value/100;
21
calc_tmp/=200;
22
i=0;
23
mean_value=0;
24
}
25
}
26
LED_ext_binary(calc_tmp);
27
ClearFlag(&TimingFlags,SYSTICK_1000_HZ_PERIOD);
28
returncalc_tmp;
}
Das funktioniert zwar einigermaßen, hat das Problem aber noch nicht
final gelöst. Es gibt immer noch Potistellungen, wo die berechneten
Dezimalwerte toggeln. Hat evtl. jemand eine Idee bzw. kennt eine
Möglichkeit, wie man trotz des A/D-Rauschens klar definierte Zustände
erzeugen kann? Z.B. das Rauschen in derart „kompensieren“, dass ein
gewisser Wertebereich über- bzw. unterschritten werden muss, bevor eine
Dezimalstelle auf- bzw. abgezählt wird?
MfG
thelightener
Torch M. schrieb:> if(i<=100)> {> val_array[i] = adc_value;
Das geht übrigens in die Hose. i kann hier den Wert 100 annehmen, das
Array hat aber nur Platz für 100 Elemente.
Torch M. schrieb:> Dann habe ich> den Ansatz über eine Mittelwertbildung probiert:
...
> Das funktioniert zwar einigermaßen, hat das Problem aber noch nicht> final gelöst.
Eine Mittelwertbildung bringt dir nichts da der Wert ja auch gemittelt
toggeln kann. Dein "Rauschen" ist ja kein weißes sondern kommt von
Störstrahlern wie der Netzfrequenz.
Besser geeignet ist m.E. eine Hysterese.
Hallo,
danke für eure Rückmeldungen.
@Karl M.
Sprichst du von einer Hardware-Lösung?
@X4U
Kannst du mir evtl. ansatzweise erläutern, wie in meinem Fall eine
Software-Hysterese aussehen soll?
MfG
thelightener
Wenn es am Netzbrumm liegt, solltest du z.B. 10 AD-Wandlungen
gleichverteilt in 20 ms (also alle 2 ms) durchführen und die
Ergebnisse summieren.
Diese Summe ist recht gut vom Netzbrumm befreit.
Ansonsten: Willst du wirklich 0..20, (21 Zustände),
oder 0..19 (20 Zustände, die üblichere Wahl) haben?
Entsprechend müstest du die 10-fache Summe
durch 1951 teilen - für 0..20, oder
durch 2048 teilen - für 0..19
Wenn die letzte Stelle toggelt, lässt man die einfach weg. 12 bit für
ein Poti? Ich stelle ja sogar an den AVRs den 8-bit Modus ein obwohl die
10bit ADCs haben.
Ein einzelnes Poti kannst du unmöglich so präzise drehen dass du das
12te Bit alleine geändert bekommst.
Grob+Feinpoti ist was anderes.
THOR schrieb:> Wenn die letzte Stelle toggelt, lässt man die einfach weg.
Ändert nichts prinzipielles, es wird nur seltener.
Hysterese ist ne gute Lösung.
Du könntest auch einen einfachen Filter machen:
z.B. wert_alt*90%+wert_neu*90%
es macht das ganze zwar träger, aber wenn man es schnell macht(z.B.
200Hz+ abtastrate) merkt man sozusagen nichts, und durch das runden
sollte es nicht immmer hin und herspringen, wenn es noch zu viel
springt, kann man den den alt anteil hochschrauben. Bei 90% alt Anteil
braucht es rund 50 Rechnenzyklen um von bei einer Änderung von 0 auf 100
beim Resultat auf 99 zu kommen. Ist nicht die schönste Lösung aber macht
ihren Job gut, wenn man nichts kompliziertes will
@hp-freund
Eine Hysterese in dieser Form habe ich schon versucht. Das Problem dabei
war, dass ich meine Funktion jede ms aufrufe und der Differenzbetrag
somit ca. jede ms neu berechnet wird. Da muss man schon verdammt schnell
am Poti drehen, damit eine wirkliche Differenz zustande kommt ;-) Evtl.
gibt es dafür ja einen Workaround, mir ist jedenfalls noch nichts
eingefallen.
@Domenic
Werde ich mal probieren, danke.
MfG
thelightener
Torch M. schrieb:> dass ich meine Funktion jede ms aufrufe
Warum ist das so?
Wenn Du diese Geschwindigkeit nicht brauchst, rufe die Funktion alle 20
oder 50 ms auf.
Vielleicht wäre in diesem Fall sogar ein Drehgeber die bessere Wahl.
Torch M. schrieb:> Eine Hysterese in dieser Form habe ich schon versucht. Das Problem dabei> war, dass ich meine Funktion jede ms aufrufe und der Differenzbetrag> somit ca. jede ms neu berechnet wird. Da muss man schon verdammt schnell> am Poti drehen, damit eine wirkliche Differenz zustande kommt ;-) Evtl.> gibt es dafür ja einen Workaround, mir ist jedenfalls noch nichts> eingefallen.
Man muß für die Hysterese nicht die Differenz zum vorigen echten
Messwert betrachten, sondern die Differenz zum aktuellen geglätteten
Wert. Der bleibt ja die ganze Zeit konstant, bis ein Messwert weit genug
abweicht, dann erst gibt es eine Änderung, egal wie oft man das
zwischendurch berechnet.
Ungefähr so: