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
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...
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).
A.K. schreib: Ich kann in den Formeln keine Exponentialfunktion finden. (-2,8*10e-6) hier ist doch ne Exponenzialfunktion
wenn ich ne Tabele anfertige, wie soll ich dan die Temperaturkompenstion mit einbauen?
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
...yep, und genau deshalb kriegt man es heutzutage in recht vielen Ausbildungszweigen mit Mathematik zu tun.
aber ich bin halt erst mit 17Jahren im zweiten Lehrjahr und da hatten wir halt noch nicht mit Rechnen in Binärtechnik zu tun
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.
ja schon aber ich hab mir halt vor kurzem dieses Programm gekauft, und damit müsste es ja auch gehn
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
Vielen dank für eure Antworten. Werde das alles jetzt mal auspobieren
Noch ne kleine Frage: Wie mach ich das bei negativen Zahlen, mit dem Zweierkompliment?
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
Dein Pascal Compiler wird doch wohl mit negativen Zahlen umgehen können?
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.
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%
Hier noch eine genauere Lösung. Kein Schnellschuss wie das letzte mal. Mfg Michael
Thanks: Wie bist du bloss da drauf gekommen? Aitz muss ich noch Rausfinden, wie die Formel mit der Temperaturkompensation geht.
> 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)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.