Messwert eines Sensors anpassen

Gast #5279175
Lesenswert?

Hallo zusammen,

ich will einen Messwert am ATMEga 644 über den AD Eingang messen.
funktioniert alles soweit ganz gut.

nun würde ich gerne die Kurve des Messfühlers anpassen.

bis zum AD Wert von 50 soll er den Wert mit 33.333333 muliplizieren
was auch noch funktioniert

ab dem Wert 51 soll er den ADWert mit 30 Muliplizieren.

Allerdings kommen dann ganz komische werte raus
es hat den anschein, als ob er den Wert von der ersten If-Anweisung und 
den Wert der zweiten If Anweisung einfach hintereinander setzt

ist an meiner If anweisung was falsch?
1
    if (ADCWert1 <=50)
2
    {
3
      ADCFloat = ((float)(ADCWert1)*33.333333);
4
      ADCWert1 = (short)ADCFloat;
5
    }
6
    
7
    if (ADCWert1 >=51)
8
    {
9
      ADCFloat = ((float)(ADCWert1)*30);
10
      ADCWert1 = (short)ADCFloat;
11
    }
#5279183
Lesenswert?

Susanne schrieb:
> Hallo zusammen,
>
> ist an meiner If anweisung was falsch?
>
>
1
>     if (ADCWert1 <=50)
2
>     {
3
>       ADCFloat = ((float)(ADCWert1)*33.333333);
4
>       ADCWert1 = (short)ADCFloat;
5
>     }
6
> 
7
>     if (ADCWert1 >=51)
8
>     {
9
>       ADCFloat = ((float)(ADCWert1)*30);
10
>       ADCWert1 = (short)ADCFloat;
11
>     }
12
> 
13
>


Wie wäre es mit einem else?

In der ersten Abfrage änderst Du ja den Wert von ADCWert1!
Gast #5279203
Lesenswert?

Bei dem Senor handelt es sich um eine Wägezelle. Diese ist an einem 
10bit AD Wandler angeschlossen. Das heißt ich habe 1024 Messwerte. Da 
ich das Ergebnis so genau wie möglich haben will denke ich, dass ich 
alle 50 Schritte eine If Anweisung benötige, damit das Gewicht so genau 
wie nur möglich angezeigt wird Oder wie würdet ihr das machen?
#5279210
Lesenswert?

@ Susanne (Gast)

>bis zum AD Wert von 50 soll er den Wert mit 33.333333 muliplizieren
>was auch noch funktioniert

>ab dem Wert 51 soll er den ADWert mit 30 Muliplizieren.

Warum auch immer.

>Allerdings kommen dann ganz komische werte raus
>es hat den anschein, als ob er den Wert von der ersten If-Anweisung und
>den Wert der zweiten If Anweisung einfach hintereinander setzt

Das macht man auch nicht so.

1. Läßt man die Eingangsvariable ADCWert1 wie sie ist und ändert da nix 
dran rum. Das ist und bleibt der ADC-Wert. Punkt. Man berechnet nur die 
Ausgangsvariable. Das ist deutlich sinnvoller und systematischer. Und 
dann würden die beiden getrennten IF-Blöcke sich auch nicht gegenseitig 
beeinflußen.

2. Es gibt auch else, wie schon bemerkt, was die Sache kompakter und 
weniger fehleranfällig macht.

3. Es gibt Festkommaarithmetik. Die meisten ausreichend und 
schneller.

1
    if (ADCWert1 <= 50)
2
    {
3
      ADCFloat = ((long)ADCWert1*136533)>>12;  // *33.33333
4
    }
5
    else 
6
    {
7
      ADCFloat = ((long)ADCWert1*122880)>>12;  // *30
8
    }
#5279215
Lesenswert?

@ Susanne (Gast)

>Bei dem Senor handelt es sich um eine Wägezelle. Diese ist an einem
>10bit AD Wandler angeschlossen. Das heißt ich habe 1024 Messwerte.

Nein. Du hast Meßwerte mit max. 1024 Schritten Auflösung.

> Da
>ich das Ergebnis so genau wie möglich haben will

Dann sollte man Auflösung und Genauigkeit unterscheiden . . .

>denke ich, dass ich
>alle 50 Schritte eine If Anweisung benötige, damit das Gewicht so genau
>wie nur möglich angezeigt

Aua. Versuchst du gerade maximal umständlich, einen ADC-Wert in ein 
Gewicht umzurechnen? Lies mal was über Festkommmaarithmetik.

> wird Oder wie würdet ihr das machen?

Mit einer normalen Rechnung. Dreisatz und so.
#5279217
Lesenswert?

Susanne schrieb:
> Bei dem Senor handelt es sich um eine Wägezelle. Diese ist an einem
> 10bit AD Wandler angeschlossen. Das heißt ich habe 1024 Messwerte. Da
> ich das Ergebnis so genau wie möglich haben will denke ich, dass ich
> alle 50 Schritte eine If Anweisung benötige, damit das Gewicht so genau
> wie nur möglich angezeigt wird Oder wie würdet ihr das machen?

Wenn die Wägezelle DMS Messstreifen hat, würde ich gar nichts machen. 
Die sind ziemlich linear.

Ansonsten:
- Kennlinie aufnehmen
- durch Taylor Polynom approximieren
- dann ausrechnen

Also keine endlose if then else Konstruktionen. Die approximieren immer 
nur stückweise linear.
Gast #5279220
Lesenswert?

Das hat einen ganz simplen Grund. Du braucht nur eine Zwischenvariable.

Er macht den Inhalt von der ersten If Anweisung, und ADCWert wird schon 
auf einen deinen gewünschten Wert gesetzt. Jedoch ist der Wert dann 
schon >51, dann springt er sofort in die nächste if Anweisung, da dieser 
Fall auch zutrifft.

Mach es mal so:
      short Zwischenwert
>     while(true){
>           Zwischenwert = ADCWert1;
>           if (Zwischenwert <=50){
>              ADCFloat = ((float)(ADCWert1)*33.333333);
>              ADCWert1 = (short)ADCFloat;
>           }
>
>           if (Zwischenwert >=51){
>               ADCFloat = ((float)(ADCWert1)*30);
>               ADCWert1 = (short)ADCFloat;
>           }
>    }
>
wobei die while schleife nicht notwendig ist
Gast #5279242
Lesenswert?

Susanne schrieb:
> nun würde ich gerne die Kurve des Messfühlers anpassen.
>
> bis zum AD Wert von 50 soll er den Wert mit 33.333333 muliplizieren
> was auch noch funktioniert
>
> ab dem Wert 51 soll er den ADWert mit 30 Muliplizieren.

Da hat Dich schon jemand gründlich verarscht.

Wer immer diese Kurve ausgedacht hat, bescheert Dir schon einen 
gewaltigen Sprung in die falsche Richtung beim Wechsel von 50 auf 51 (du 
springst immerhin ein paar Prozent vom Messwert zurück).

Für Dich wäre es besser, wenn Du die 1024 Werte einfach als eine Tabelle 
ablegst, bis Du Dir selber die einfachsten Grundlagen der 
Stützstellen-Mathematik beibringst.

Und natürlich als gerundete integer-Zahl von 16 Bit.

Wenn Du die Tabelle hast, dann kannst Du z.B. nur jeden 10ten Wert 
ablegen und dazwischen interpolieren. Ob per if/else if oder Schleife 
über eine Tabelle ist dann erstmal egal.
Gast #5279255
Lesenswert?

Wenn die Wägezelle Linear ist, reicht eine einfache Geradengleichung, 
mit der Offset und Steigung angepasst werden.
(y = k * x + d), wobei:
y... der Korrigierte Messwert
k... Korrekturwert für die Steigung
x... der Unbearbeitete Sensowert
d... der Offset (Fehler bei 0g)

Es reicht dann, wenn der OFfset bei 0 (unbelegte Wägezelle) und die 
Steigung an 2 Punkten ermittelt wird.

https://de.wikipedia.org/wiki/Lineare_Funktion
Gast #5279273
Lesenswert?

ich schrieb:
> Wenn die Wägezelle Linear ist, reicht eine einfache Geradengleichung,
> mit der Offset und Steigung angepasst werden.

Wenn die Wägezelle linear ist, braucht man keine abschnittsweise 
unterschiedliche Steigung.

Nach dem bisherigen Ansatz scheint diese Voraussetzung nicht erfüllt zu 
sein.

Martin B. schrieb:
> Ansonsten:
> - Kennlinie aufnehmen
> - durch Taylor Polynom approximieren
> - dann ausrechnen

Bevor man sich für ein Taylor Polynom mit manchmal üblem Verhalten 
zwischen Stützstellen als Aproximation entscheidet, sollte man sich 
erstmal die Kennlinie ansehen. Falls es nach einem Polynom höherer 
Ordnung (>3) aussieht, sollte man noch mal über die Funktionsklasse 
nachdenken.
Gast #5279330
Lesenswert?

Saemtliche Werte kleiner 50 werden mit 33 multipliziert, und da dann 
groesser 51 nochmals mit 30.

Erst mal die Linearitaet der Waegezelle messen. Also eine Tabelle 
aufstellen mit Gewichten von 1,2,5,10,20,50, .. was auch immer.
In eine Grafik einzeichen und schauen, ob eine Gerade reinpasst. Das 
waere dann Gewicht=Offset+Steigung*Messwert

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren