Forum: Mikrocontroller und Digitale Elektronik Komplizierte Berechnung mit PIC durchführen


von Michael (Gast)


Lesenswert?

Hallo,

ich möchte gerne an meinen PIC einen Luftfeuchte- und Temperatursensor 
(Sensirion SHT11) anschließen, das wäre soweit kein Problem. Nur man 
muss die Daten vom Sensor noch umrechnen und weiß überhaupt nicht, wie 
ich das machen sollte.

Zuerst die Temperatur:
Temperatur=(-40)+0,01*SO(T)
wobei SO(T) der Temperaturwert von Sensor ist.

Luftfeuchtigkeit:
RH(lin)=(-4)+0,0405*SO+(-2,8*10e-6)*SO^2  (Realitive Luftfeuchte)

RH(true)=(T-25)*(0,01+0,00008*SO)+RH(lin) (Temperaturcompensation)

wobei SO ein Wert zwischen 0 und 3500 sein kann

Compilieren tu ich das ganze mit GoEmbedded, einen Pascal-Compiler:
Damit kann ich addieren, subtrahieren, multiplizieren und dividieren 
(und den Rest der Division mit Mod zurückgeben) rechnen mit 16Bit 
Zahlen.

Irgendwo hab ich was mit Zweierkomplement und Exponentialfunktion mit 
der Basis zwei gelesen, blick da jedoch nicht durch

Vielleicht kann mir jemand helfen

von Hans-Peter (Gast)


Lesenswert?

Wenn du genügend Programmspeicher zur Verfügung hast, dann leg doch 
alles in einem LookUp-Table an.
Dann muss der uC nicht so viel rechnen...

von jÜrgen (Gast)


Lesenswert?

Du könntest Hardware technisch die Werte um die jeweiligen Zehner 
Potenzen erhöhen od. verringern bis du keine Gleitkommawerte mehr hast. 
Der PIC rechnet sich einfacher.

Der LookUp-Table ist die andere Idee. Weiß leider nicht welchen PIC du 
hast, aber man wird sicher ein ROM anbinden können.

von Michael (Gast)


Lesenswert?

du meinst also eine Tabele wo z. b. steht 3000 ist 90%, 1500 ist 45% 
oder so:
Programmspeicher hab ich 8kWord, aber daran soll noch windrichtungs,- 
druck und regenmengenmesser angeschlossen werd und per Rs232 übertragen 
werden und da weiß ich noch nicht genau, wie viel speicher ich benötige, 
aber ich denke so ca.2kWord werden schon noch übrig sein Auflösung von 
1% würde ja reichen.
Aber wenigstens die Temperatur möcht ich schon du rechnen lösen

von Michael (Gast)


Lesenswert?

ein eeprom könnte ich schon anbinden

von A.K. (Gast)


Lesenswert?

Ich kann in den Formeln keine Exponentialfunktion finden.

Der Haken liegt eher darin, die Formeln so umzuwandeln, dass mit 
Festkommarechung gearbeitet werden kann, ohne dass ein Zwischenergebnis 
überläuft oder zu ungenau wird. Was mit 16bit-Rechnung interessant zu 
werden verspricht. Tabellen empfohlen, oder eine Programmiersprache die 
besser rechnen kann (ggf. entsprechende Library suchen).

von Michael (Gast)


Lesenswert?

A.K. schreib: Ich kann in den Formeln keine Exponentialfunktion finden.

(-2,8*10e-6) hier ist doch ne Exponenzialfunktion

von Michael (Gast)


Lesenswert?

wenn ich ne Tabele anfertige, wie soll ich dan die Temperaturkompenstion 
mit einbauen?

von A.K. (Gast)


Lesenswert?

Nö, das ist eine Konstante, nämlich -0,0000028. Hast du noch nie eine 
Zahl in technisch-wissenschaftlicher Notation gesehen? Bzw. in dessen 
üblicher programmiersprachlicher Darstellung?

von Michael (Gast)


Lesenswert?

ups stimmt, aber trotzen weiß ich nicht, wie ich eine so lange 
Kommazahl, die auch noch negativ ist, so zu verarbeiten, dass ich nicht 
über 16Bit hinauskommt

von A.K. (Gast)


Lesenswert?

...yep, und genau deshalb kriegt man es heutzutage in recht vielen 
Ausbildungszweigen mit Mathematik zu tun.

von Michael (Gast)


Lesenswert?

aber ich bin halt erst mit 17Jahren im zweiten Lehrjahr und da hatten 
wir halt noch nicht mit Rechnen in Binärtechnik zu tun

von A.K. (Gast)


Lesenswert?

Das hat fast nichts mit Binärtechnik zu tun. Einzig der Wertebereich 
0..65535 oder -32768..+32767 ist davon betroffen. Der Rest dieses 
mathematischen Problems ist von der gewählten Basis erst einmal 
unabhängig.

von Tom (Gast)


Lesenswert?

Nimm halt nen C-Compiler, der Pascal Kram taugt eh nix und beruflich 
brauchste eh immer C und/oder Assembler wenn du ernst genommen werden 
willst. Beim Wetter- Messen hat der PIC ja reichlich Zeit um mit 
Fliesskommazahlen zu rechnen.

von Michael (Gast)


Lesenswert?

ja schon aber ich hab mir halt vor kurzem dieses Programm gekauft, und 
damit müsste es ja auch gehn

von A.K. (Gast)


Lesenswert?

Bleiben also 2 Möglichkeiten:

(1) Es gelingt dir, die Formeln so umzuwandeln, dass es mit 16bit 
Festkommaarithmetik geht.

(2) Du stellst fest, dass die Investition in GoEmbedded zumindest bei 
dieser Problemstellung ein Schuss in den Ofen war, und suchst etwas dazu 
passenderes. Der SDCC beispielsweise kostet nix und beherrscht 
Fliesskommarechnung.

von Karl H. (kbuchegg)


Lesenswert?

Das Prinzip das du anwenden möchtest ist Folgendes:

Deine Aufgabe ist es zb 3.48 + 8.65 zu berechnen und du
hast keine Kommazahlen zur Verfügung.
Dann schiebst du einfach mal das Komma um 2 Stellen nach rechts.
Deine Aufgabe wird dann zu  348 + 865
Das Ergebnis lautet dann: 1213. Da du das Komma aber um 2 Stellen
nach rechts verschoden hast, ist das Ergebnis also 12.13
Du realisierst das, indem du bei der Ausgabe der Zahl das Komma einfach
an der richtigen Stelle wieder einschmuggelst.

Im Grunde macht man sowas auch im täglichen Leben. Anstatt
auszurechnen wieviel 2 Euro 32 plus 3 Euro 99 ergibt, kannst du
auch rechnen 232 Cent plus 399 Cent.
Oder: 3.4 km + 12.8 km   Die Kommazahlen lassen sich vermeiden
indem man auf Meter übergeht: 3400 + 12800

Du musst dir nur überlegen um wieviele Stellen du das Komma
verschieben musst. Auf der einen Seite gewinnst du mit jeder
Stelle eine Kommastelle dazu, auf der anderen Seite werden
deine Zahlen dadurch immer größer und du musst darauf achten
nicht über den durch den Datentyp vorgegebenen zulässigen
Wertebereich zu kommen.

Viel Spass beim ausknobeln.
Noch ein Tipp: Niemand sagt, dass alle Teilberechnungen mit
der gleichen Kommaverschiebung gerechnet werden müssen:

   3 km + 7 km + 7.25 km

Die 3 km + 7 km  kann man auch addieren ohne das Komma zu verschieben

von Michael (Gast)


Lesenswert?

Vielen dank für eure Antworten. Werde das alles jetzt mal auspobieren

von Michael (Gast)


Lesenswert?

Noch ne kleine Frage: Wie mach ich das bei negativen Zahlen, mit dem 
Zweierkompliment?

von rene (Gast)


Lesenswert?

Das Pascal sollt's schon koennen. 17 ist noch etwas zu jung um sich von 
C Blähungen zu holen. Falls die gerechneten Daten auf einen PC 
uebermittelt werden, koennen sie auch dort berechnet werden. Die 
Berechnung auf dem PIC macht nur Sinn wenn der PIC die Werte auch so 
anzeigen soll.
Der Ansatz ist nun, die Berechnung zu optimieren. Zuerst, was ist der 
dynamische Bereich der Rechnung, welches ist der dynamische Bereich der 
Eingangs-, Zwischen- und Ausgangswerte. Moeglicherweise genuegen 16 bit, 
entsprechend 4.5 Stellen nicht. Dann muesste man auf 24 oder 23 bit 
gehen.

rene

von Karl H. (kbuchegg)


Lesenswert?

Dein Pascal Compiler wird doch wohl mit negativen Zahlen umgehen können?

von A.K. (Gast)


Lesenswert?

Wenn's denn mal Pascal wäre. Diese Schrumpfversion hat freilich genau 2 
numerische Datentypen: 0.255 und 0..65535. Schon ein Vorzeichen ist 
unbekannt. Nicht wirklich die einfachste Basis für Numerik.

von Karl H. (kbuchegg)


Lesenswert?

> Diese Schrumpfversion hat freilich genau 2
> numerische Datentypen: 0.255 und 0..65535.

Schmeiss ihn weg.
Da kannst du auch gleich in Assembler programmieren. In so
einem Fall bringt dir Hochsprache nichts oder nur sehr wenig.
Wenn du in der Hochsprache dich auch noch ums 2-er Komplement
bei Ein und Ausgabe kümmern musst, na dann: gute Nacht.


von Michael (Gast)


Lesenswert?

das ist das Problem, dass der Wert an nen zweiten PIC per Funk 
übermitelt werden soll, und dort auf nem Grafik-LCD ausgegeben werden 
soll und deshalb kann ich es nicht mit nem PC umrechnen. Das sollte dann 
ne Wetterstation werden.

von Michael (Gast)


Lesenswert?

RH(lin) = (SO - 99) / 25

Mfg Michael

von Michael (Gast)


Lesenswert?

diese Formel funktioniert im unter Drittel ganz gut, aber wird dann sehr 
ungenau 2500 müsste 80% laut Diagramm sein ist aber dann schon bei 96%

von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Hier noch eine genauere Lösung. Kein Schnellschuss wie das letzte mal.

Mfg Michael

von Michael 1 (Gast)


Lesenswert?

Thanks: Wie bist du bloss da drauf gekommen?
Aitz muss ich noch Rausfinden, wie die Formel mit der 
Temperaturkompensation geht.

von Karl H. (kbuchegg)


Lesenswert?

> Thanks: Wie bist du bloss da drauf gekommen?

Anwendung der Fixed Point Prinzipien

Das ist deine ursprüngliche, vereinfachte Gleichung
RH(lin)=(-4)+0,0405*SO

Etwas umstellen ergibt
RH(lin) = 0.0405 * SO - 4

Da ist jetzt eine Kommazahl drinnen. Die wollen wir
weghaben. Anstatt 0.0405 soll eine ganze Zahl stehen.
Am einfachsten ist es mal, wenn da eine 1 stehen würde
(denn dann würde auch die Multiplikation wegfallen :-)

Also: 1 / 0.0405 ergibt 24.69   Grob gerundet also 25

Wenn wir die Gleichung also mit 24.69 multiplizieren, ergibt
sich

 24.69 * RH(lin) = 1 * SO - 98.76

oder

  RH(lin) = ( SO - 98.76 ) / 24.69

Die Kommazahlen runden wir und es ergibt sich

  RH(lin) = (SO - 99 ) / 25

Nun ist 1 / 0.0405 keine wirklich schöne Zahl. Mann könnte
also nach etwas anderem als 1 suchen, dass bei Division durch
0.0405 einen Wert ergibt, der näher an einer ganzen Zahl liegt.
405 zum Beispiel.
405 / 0.0405 ergibt 10000

Man könnte die Formel also auch so umformen

RH(lin) = ( 405 * SO - 40000 ) / 10000

Das könnte jetzt aber ein Problem mit dem Zahlenbereich geben.
Was ist mit 40?
40 / 0.0405 ergibt 987.6
987.6 * 4 ergibt 3950.6

  RH(lin) = ( 40 * SO - 3950.6 ) / 987.6

Der Trick besteht also darin, die 0.0405 in einen Bruch
mit möglichst ganzzahligen Werten zu zerlegen, mit dem
dann die ganze Gleichung multipliziert wird.

Jetzt solltest du auch rausfinden können, wie Michael das
quadratische Glied behandelt hat.

von Matthias (Gast)


Lesenswert?

Hallo Michael,

will dir kurz mal das zweier komplement erklären:

Das zweier Komplement errechnet sich immer so:
zweier_komplement_der_zahl_X = (End_wert+1) - X

der End_wert ist der wert, was dein (gerade verwendetes) zahlenformat 
MAXIMAL darstellen kann.

Beispiel mit "normalen" dezimalzahlen
wir rechnen mit EINER stelle in unserem dezimalzahlensystem:
also können wir (mit dieser Stelle) zahlen von NULL...NEUN darstellen.
Also ist der End_wert hier NEUN. somit errechnet sich das 
Zweierkomplement von zB der DREI: (neun + 1)-3 = SIEBEN.
du kannst jetzt zB rechnen:
          8                   8
        - 3                +  7  (zweierkomplement von 3)
      ------                -----
          5                 1 5
Die fünf ist das richtige ergebnis. Das ergebnis bei der Rechnung mit 
Zweierkomplement ist auch fünf. Die Eins ist ja der Übertrag (an die 
nächste Stelle). Da wir ja aber nur mit EINER stelle rechnen wollten, 
fällt dieser einfach weg!!
Bei 8bit binärzahlen zB. char, uint8_t oä.
also du Wertebereiche von 0...255 nutzt,ergibt sicht durch die bildung 
des zweierkomplements der zahl X:  zw_komp_X = (255+1)-X.
Probiers mal aus.
Verwendest du Compiler zur Programmierung, kümmern die sich um alles. 
Nur in Assembler musst du das selbst tun...

Gruß Matthias





von Michael (Gast)


Lesenswert?

Danke für die Erklärungen, jetzt bin ich wieder ein bischien schlauer^^ 
:-)

Die zweite Formel konnt ich jetzt selber auflösen und für die Erste nehm 
ich
jetzt, damits genauer wird ne Tabelle. Aber dabei hab ich noch ein 
Problem:
Um mir Auszurechen, was z.b. 10% Prozent für ein Wert vom Sensor ist 
muss ich die erste Formel: RH(lin)=(-4)+0,0405*SO+(-2,8*10e-6)*SO^2 
umstellen und zwar in die Form: SO(RH)=...
nur hab ich da einmal SO und einmal SO^2 und ich brings irgenwie nicht 
fertig.

von Karl H. (kbuchegg)


Lesenswert?

Das ist dann eine quadratische Gleichung.
Die bringst du auf die Form:

   x^2 + px + q = 0

Diese Gleichung hat 2 Lösungen:

  x    =  -( p/2 )  +  sqrt( ( p/2 )^2 - q )
   1

  x    =  -( p/2 )  -  sqrt( ( p/2 )^2 - q )
   2

(x ist natürlich dein SO, sqrt ist die Quadratwurzel)

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.