Forum: Mikrocontroller und Digitale Elektronik Messwert eines Sensors anpassen


von Susanne (Gast)


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
    }

von ich (Gast)


Lesenswert?


von Martin B. (ratazong)


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!

von Susanne (Gast)


Lesenswert?

Ja, an das hab ich auch schon gedacht. Aber was mach ich wenn ich den 
Faktor bei dem Wert 100 wieder anpassen muss?

von Stefan S. (chiefeinherjar)


Lesenswert?

Du kannst ja au hier wie folgt abfragen:
1
If(ADC Wert >= 51 && ADCWert < 100){
2
3
} else {
4
5
}

von Martin B. (ratazong)


Lesenswert?

Susanne schrieb:
> Ja, an das hab ich auch schon gedacht. Aber was mach ich wenn ich den
> Faktor bei dem Wert 100 wieder anpassen muss?

Dann braucht Du auch das "else if" aus dem tutorial.

von Susanne (Gast)


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?

von Falk B. (falk)


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
    }

von Falk B. (falk)


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.

von Martin B. (ratazong)


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.

von fhdfh (Gast)


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

von A. S. (Gast)


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.

von ich (Gast)


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

von Wolfgang (Gast)


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.

von dünnwandiger Flachbandtroll (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.