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
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.
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
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).
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?
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
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.
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.
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.
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
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
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.
> 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.
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.
> 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.
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
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.
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)