Skalierung von Messwerten in C

Gast #1750250
Lesenswert?

Hallo, ich erfasse diverse Größen (Temperatur,Kraft,Druck) mit einem 
10-Bit AD Wandler des PIC18.
Als Beispiel
0-1023 Digit = -50....+300 Grad Celsius.
0-1023 Digit = - 25... 100 BAR (4-20 mA Messung)

Gint es eine fertige Funktion in C, die aus dem Eingangs Integer einen 
skalierten Ausgangsinteger macht ? Ich kenn sowas von der Siemens S7.

int Skalieren ( int In-min, INT IN-max, INT Out-min, INT OUT-max)

Werte für die Temperaturmessung:

INT Skalieren (0,1023,-500,3000);  // 1 Nachkommastelle

Ergebnis sollte dann ebenfalls als INT mit 1 Nachkommastelle sein.

Danke für eure Hilfe im voraus !
Gast #1750271
Lesenswert?

Hi

>Gint es eine fertige Funktion in C,

Weiß ich nicht. Aber in der Zeit, in der du hier auf Antwort wartest, 
hätte ich eine solche Funktion in  Pascal dreimal geschrieben. In 
Assembler wahrscheinlich auch.
Außerdem fehlt deiner Funktion irgendwie der umzurechnende Wert.

MfG Spess
#1750275
Lesenswert?

1
                                                       out_max - out_min
2
 salierter_wert = out_min +  ( Messwert - in_min ) * ---------------------
3
                                                         in_max - in_min

wenn du noch 1 Kommastelle haben willst, musst du noch einen Faktor 10 
anbringen
1
                                  10 * ( Messwert - in_min )  * ( out_max - out_min )
2
 salierter_wert = 10 * out_min +  ----------------------------------------------------
3
                                                    in_max - in_min

Auf Datentypen und mögliche Überläufe achten!
Gast #1750326
Lesenswert?

Hallo, danke für die Hinweise. Habe es hin bekommen:


//**********************scale**********************************

  int scale (int in_min, int in_max, int out_min, int out_max, int wert)
  {
  int abc;
  abc = ((float)wert / ( (float)in_max - (float)in_min))*((float)out_max 
- (float)out_min) + (float)out_min;
  return (abc);
  }


//******************************Main**************************


void main(void)
{

  int ergebnis;
           int wert=600;
  ergebnis = scale (0,1024,-500,2500,wert);
#1750329
Lesenswert?

DirkF schrieb:
> Hallo, danke für die Hinweise. Habe es hin bekommen:
>
>
> //**********************scale**********************************
>
>   int scale (int in_min, int in_max, int out_min, int out_max, int wert)
>   {
>   int abc;
>   abc = ((float)wert / ( (float)in_max - (float)in_min))*((float)out_max
> - (float)out_min) + (float)out_min;
>   return (abc);
>   }

Warum hab ich blos geahnt, dass du float nehmen wirst :-)

Es ist unnötig!

Und schieb die Division nach hinten! Du willst so spät wie möglich 
dividieren!

(Da ist noch ein Fehler, den ich zu verantworten habe. Vom Messwert muss 
noch in_min abgezogen werden. Bei dir fällt es nicht auf, weil dein 
in_min gleich 0 ist.

Sieh dir nochmal die Formel weiter oben an. Da hab ich das in_min 
eingebaut.
)

Und schmeiss die float raus. Es reicht wenn du alles in long rechnest.
Gast #1750359
Lesenswert?

Hallo, danke für den Hinweis mit dem Long. Der code ist jetzt wesentlich 
kleiner geworden !

//**********************scale**********************************

  int scale (int in_min, int in_max, int out_min, int out_max, int wert)
  {
  int abc;
  abc = ((long)out_max - (long)out_min)* (long)wert / ( (long)in_max - 
(long)in_min);
  abc = abc + out_min;

  return (abc);
  }

//******************************Main**************************

void main(void)
{
  int ergebnis;
  int wert = 600;  // vom AD Wandler 10 Bit
  ergebnis = scale (0,1024,-500,2500,600); // skalieren in 
-50,0...+250,0°C
#1750364
Lesenswert?

Den in_min Offset Fehler hast du immer noch.

Sagtest du nicht auch etwas von einer Skalierung, so dass im Endergebnis 
noch 1 'Nachkommastelle' auftaucht? (Kannst du natürlich auch über die 
out_min, out_max Werte erreichen, wenn du deren möglichen Zahlenbereich 
nicht ausnutzen wirst.

Und es reicht wenn du das Ergebnis von  ( max - min )   auf long 
castest. Die Subtraktion muss nicht long gemacht werden. Nicht bei 
deinen Zahlenwerten. Wenn du es allerdings ein wenig allgmeiner halten 
willst, dann lass es so wie es ist.

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