Forum: Mikrocontroller und Digitale Elektronik AVR Formel berechnen


von Frank G. (frankg)


Lesenswert?

Hallo, ich habe lange in Euren Beträgen gesucht und komme alleine 
einfach nicht weiter. Ich habe eine Temperatur vom STM-160 zu berechnen. 
Der liefert ein PWM Signal 4-7kHz und man braucht die Länge der 
positiven "Halbwelle" = T1  und der Periodendauer = T2. Ich habe viele 
von diesen Teilen verbaut, ein Tipp "nehme einen anderen" hilft mir 
nicht. Viele verbaute Sensoren sind nur noch Anschlüsse, die gelesen 
werden wollen!!  Ich habe einen AT Mega 16 und benutze den ICP Pin, die 
Werte die bei der Messung raus kommen sind auch (z.B. mal in Excel 
eingesetzt) OK.
z: B: H-Zahl = 281 und Periode = 639

Aber aus diesen Werten in C ein Ergebnis zu machen ist mir bis jetzt 
nicht gelungen.
Hier die Formel im Original:
temperatur = ((T1/T2) -0.32) / 0.0047) in grd C   Was ich schon lernen 
durfte ist das das geteilt durch 0.0047 recht doof ist. Ich hatte mal 
eine Erweiterung mit 100 probiert
temperatur = ((T1 /(T2/100) -32 ) * 2.127   auch das ist schlecht da 
durch die Multiplikation am Ende  *2....  dann Temperaturen z.B. 20 °C, 
22°C, 24 °C sind, wenn das angezeigt wird ist das nicht falsch aber 
schön auch nicht.
Dann hatte ich was gefunden was mit >> << "schieben geht und gedacht in 
nehme mal den temperatur Wert * 100   also 22,12°C  wären 2212  usw.

char temperatur[4];
volatile long high;
volatile long period;
      high=Stopwert-Startwert;
      period=Stopwert2-Startwert;
      high = high << 13;
      //period = high / period;
      //period = period - (2621);
      //period = period * 21200;
      period = (((high / period) - 2621) * 21200) >> 13;

Das (letzte Zeile; oder dafür die 3 auskommentierten Zeilen) scheinen zu 
gehen Fragen sind aber:

A....Wie man das vielleicht wirklich gut/besser macht (die Rechnung) 
keine Ahnung und

B....Eine Ausgabe zu meinem LCD mit ltoa oder als integer, soll heißen
temperatur Wert aus der Rechnung = 3267 ->   LCD Ausgabe  32,67 °C sind 
mir ein Rätsel  Ich bekomme da nicht so richtig eine Komma dazwischen.

Gruß Frank

: Verschoben durch User
von Frank (Gast)


Lesenswert?

>temperatur = ((T1/T2) -0.32) / 0.0047)
Wenn du das mit 10000 erweiterst hast du schon Mal keine float mehr im 
Term und später für das LCD 4 Nachkommastellen (die du wahrscheinlich 
nicht brauchen wirst).
Wenn T1 16 Bit ist, hast du dann aber 32 Bit an der Backe. Trotzdem 
wahrscheinlich besser als float.

von Frank G. (frankg)


Lesenswert?

> Wenn T1 16 Bit ist, hast du dann aber 32 Bit an der Backe. Trotzdem
> wahrscheinlich besser als float.
ich hatte ja mit T1 * 100 angefangen aber dann wird der letzte Teile ein 
-> Multiplikator * 2,   dann spring die Temperatur von 20 22 24

von Frank (Gast)


Lesenswert?

uint32_t temp = ((((uint32_t)T1)*10000UL/T2) - 3200UL) / 47UL)

von Reiner_Gast (Gast)


Lesenswert?

Du könntest die Formel umstellen zu:

((T1/T2) -0,32) * 212,766

Dann umstellen nach:

(T1/T2 * 212,766) - (0,32 x 212,766)

oder auch:

(T1 * 212,766)/T2 - 68,1

Macht als Float mit deinen Werten T1 = 281 und T2 = 639 als Ergebnis:

(281 * 212,766) / 639 - 68,1 = 25,464

Nimmst du jetzt statt der festen Float Werte mit 100 multipliziert 
Integer Konstanten und rechnest mit Uint32_t Werten, dann wird:

(281 * 21277) / 639 - 6810 = 2546

=> Das jetzt wieder durch 100 teilen und du hast die Temperatur

von Reiner_Gast (Gast)


Lesenswert?

Frank G. schrieb:
> B....Eine Ausgabe zu meinem LCD mit ltoa oder als integer, soll heißen
> temperatur Wert aus der Rechnung = 3267 ->   LCD Ausgabe  32,67 °C sind
> mir ein Rätsel  Ich bekomme da nicht so richtig eine Komma dazwischen.

Mal aus dem Gedächtnis geschrieben...

Gegeben ist die Variable: uint16_t temp=3267

uint8_t buf[20]
sprint (buf, "%2d,%20d °C",temp/100,temp%100);

buf sollte dann die Temperatur in der gewünschten Zeichenfolge 
enthalten...

von Reiner_Gast (Gast)


Lesenswert?

Reiner_Gast schrieb:
> sprint (buf, "%2d,%20d °C",temp/100,temp%100);

Muss natürlich sprintf heissen :-)

von xxx (Gast)


Lesenswert?

%20d  muss  %02d   heissen.

von Reiner_Gast (Gast)


Lesenswert?

Reiner_Gast schrieb:
> Reiner_Gast schrieb:
>> sprint (buf, "%2d,%20d °C",temp/100,temp%100);
>
> Muss natürlich sprintf heissen :-)

Grrrr... gerade nochmal nachgesehen auf 
http://www.cplusplus.com/reference/cstdio/printf/

Sollte so richtig sein: sprintf (buf, "%2d,%02d °C",temp/100,temp%100);

von Reiner_Gast (Gast)


Lesenswert?

xxx schrieb:
> %20d  muss  %02d   heissen.

Jepp... Habs auch gemerkt...

von Frank G. (frankg)


Lesenswert?

ich bin noch da und brauche etwas Zeit das nach zu vollziehen.... um 
19:00 Uhr muss ich weg  aber ich werde sicher noch Fragen haben also 
erst einmal DANKe an alle

von Frank G. (frankg)


Lesenswert?

> Nimmst du jetzt statt der festen Float Werte mit 100 multipliziert
> Integer Konstanten und rechnest mit Uint32_t Werten, dann wird:
>
> (281 * 21277) / 639 - 6810 = 2546
>
> => Das jetzt wieder durch 100 teilen und du hast die Temperatur

Bis hier bin ich schon.... das ist sehr viel schöner

von xxx (Gast)


Lesenswert?

Fuer temp reichen 16 Bits, aber es muss signed sein, da auch negative 
Temperaturen vorkommen koennen.
Mit den beiden Integer-Konstanten (Offset und Steigung) kann man das 
Thermometer gut kalibrieren.

von Frank G. (frankg)


Lesenswert?

Reiner_Gast schrieb:
> sprintf (buf, "%2d,%02d °C",temp/100,temp%100);

hier muss ich noch etwas grübeln ich habe ja in meinem Programm
LCD_Print("Temp: ");    das gibt den Text aus oder
LCD_Integer_schreiben(zahl);
wie ich das verheirate ???  aber heute muss ich eh erst mal Schluss 
machen

von xxx (Gast)


Lesenswert?

LCD_Print(buf);
Danke fuer Deine schoene Herleitung, Reiner_Gast!
Man koennte noch ueber ein %3d statt %2d nachdenken, weil bei 
Temperaturen ueber 100 oder unter -10 der Text um eine Stelle weiter 
rechts steht.

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.