Luftdruckmessung mit MS5534/MS5540

Knickohr

BASCOM-Experte
29. Feb. 2008
465
0
16
Sprachen
Hallo zusammen,

da immer mehr Anfragen kommen, ob meine Astro-Wetterstation auch den Luftdruck messen könnte, habe ich mich entschlossen eine entsprechende Druckdose mit dran zu hängen. Leider ist das Platinenlayout schon fertig und auch die Anzahl und Funktion der Pins am Atmega1281 begrenzt. Ich habe zwar noch den kompletten Port E frei, dieser ist auch auf eine Stiftleiste gelegt und somit muß ich mit diesen Ressourcen auskommen.

Das schränkt die Auswahl der Drucksensoren drastisch ein. Einen analogen Typ kann ich nicht nehmen, da ich keinen A/D-Pin mehr frei habe, bzw. nicht mehr zugänglich ist. Dosen mit entsprechendem digitalen Protokoll, wie I²C, TWI, ... kommen auch nicht in Frage. Ich muß mir über die freien Pins das Bitgezappel irgendwie selbst zusammen stricken. Eine relativ einfache Lösung bietet (hoffentlich) der MS5534 oder MS5540 von Intersema. Die Sensoren sind auch bei ELV zu bekommen, woanders habe ich ihn nicht gefunden.

Hat jemand so ein Bitgezappel (ja, ich weiß, Markus hat das für den SHT71 schon gemacht) schon mal programmiert ? Vielleicht sogar schon für diese Drucksensoren ? Habe den ganzen Nachmittag gegooglet, aber bis auf eine Ausnahme nichts vernünftiges gefunden. Hat jemand Erfahrung mit den Sensoren gemacht ? Vielleicht sogar schon eine passende Lösung in BASCOM parat ?

Der Sensor hätte den Vorteil, das er sehr wenig Strom verbraucht und sogar voll kompensiert und abgeglichen ist. Außerdem ist auch noch ein Thermometer mit drin, mit denen ich dann die Raumtemperatur messen könnte ;)

Thomas
 
Datenblätter?

Hi Thomas,

poste doch bitte mal in diesem Thread die relevanten Datenblätter. Schau mal bitte nach ob es beim Hersteller irgendwelche Referenzimplementierungen oder Beispiele gibt.

Ich kann mir das gerne die nächsten Tage mal ansehen. Wenn Du Lust hast dann komm doch einfach mal mit einem Sensor bei mir vorbei und dann machen wir das gemeinsam. Ich programmiere gerne Bitgezappel :rolleyes: und das STK500 steht auch noch bei mir auf dem Schreibtisch.

Für Michael hatte ich ja auch schon die PLL zum zappeln bekommen. Was hältst Du von der Idee?

Grüße,
Markus
 
Hallo Nico,

den MS5401 haben die, ja. Aber den 5534 oder 5540 nicht :(

OK, ist ja nicht ganz so schlimm, bekommen den 5534 ja bei ELV. Wäre halt schön gewesen, wenn es noch Alternativen gäbe.

Nun gut, es gibt eine. Direkt beim Hersteller. Aber da ist mir das Porto von 75 Fränkli zu teuer !


Markus,

alles weitere findest Du bei http://www.intersema.ch/site/technical/ms5534.php

Da ist auch ein Applikationsnote dabei, wie man die Werte ausliest und wie das Gezappel aussehen muß. Leider alles in C und ich kann im Alphabet nur bis B(ASCOM) ;) Ich habe auch ein Beispiel in den Weiten des www gefunden, aber das ist, denke ich, nicht so dolle programmiert.

Thomas
 
Hei Thomas,

bist Du mit Deinem Bitgezappel schon weiter gekommen und hast mit einer Implementierung begonnen oder hast Du noch Bedarf an Support?

Grüße,
Ma
 
Hallo Markus,

die Druckdinger sind heute angekommen ;)

Sind zwar nicht ganz so fuzzelig wie der SHT71, aber doch noch klein genug. Da werde ich wohl mit Lackdraht die Kabel dran "bonden" und erst mal auf ein vernünftiges 2,54mm Raster auflegen.

Thomas
 
Hei Thom,

das sind ja gute Nachrichten! Jetzt musst Du nur noch heute Nacht :rolleyes: die PCB fertig machen und bestücken und dann können wir morgen am offenen Herzen operieren. :eek:

Ich denke dann sollte das Bitgezappel kein Problem weiter sein und vielleicht gibt es ja spätestens morgen Abend einen fertigen Treiber in BASCOM für die Geschichte!

Grüße,
Ma
 
Hallo

:party:

Es ist getan, die Bits zappeln und die Werte werden fein säuberlich aus dem MS5534 ausgelesen.

Das Problem mit dem externen 32.768Hz-Takt für den MS5534 habe ich auch in den Griff bekommen. Beim PWM kann man diesen auch in einen Fast-Modus versetzen, dann kann er richtig schöne hohe Frequenzen erzeugen. Allerdings geht das nicht mit BASCOM-internen Mitteln, da muß man direkt in Register schreiben.

Nachdem Markus und ich gestern mal konstruktiv etwas zusammen gemacht haben, darf ich ein Beispielprogramm in BASCOM für den Drucksensor von Intersema vorstellen :

Code:
$regfile = "m644def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 40
$prog &HFF , &HE2 , &HD9 , &HFE                                                 ' BODEN=1,8V, JTAG disabled, sonst Standard

Config Clock = Soft , Gosub = Sectic
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
Config Lcd = 16 * 2 , Chipset = Dogm162v3

' Timer1, Fast-PWM (Mode 15), Prescale = 1, variable Frequenz, Tast 1:1, OC1A -> ca. 32.768Hz
Tccr1a.7 = 0                                                                    ' COM1A1
Tccr1a.6 = 1                                                                    ' COM1A0
Tccr1a.1 = 1                                                                    ' WGM11
Tccr1a.0 = 1                                                                    ' WGM10
Tccr1b.4 = 1                                                                    ' WGM13
Tccr1b.3 = 1                                                                    ' WGM12
Tccr1b.2 = 0                                                                    ' CS12
Tccr1b.1 = 0                                                                    ' CS11
Tccr1b.0 = 1                                                                    ' CS10
Ocr1ah = 0
Ocr1al = 120

Cursor Off Noblink
Cls

Config Portd.0 = Output
Portd.0 = 0                                                                     ' GND MS5534
Sclk Alias Portd.1
Config Portd.1 = Output                                                         ' SCLK MS5534
Dout Alias Pind.2
Config Pind.2 = Input                                                           ' Dout MS5534
Din Alias Portd.3
Config Portd.3 = Output                                                         ' Din MS5534
Mclk Alias Portd.5
Config Portd.5 = Output                                                         ' MCLK MS5534
Config Portd.6 = Output
Portd.6 = 1                                                                     ' VDD MS5534

Const Hoehe = 600

Const Conv_start_press = &B1111010000000000
Const Conv_start_temp = &B1111001000000000
Const Read_cali_data_1 = &B1110101010000000
Const Read_cali_data_2 = &B1110101100000000
Const Read_cali_data_3 = &B1110110010000000
Const Read_cali_data_4 = &B1110110100000000
Const Reset_sequence = &B1010101010101010

Dim V As Word                                                                   ' allgemeine Variable
Dim W As Word                                                                   ' allgemeine Variable
Dim Temp_integer As Integer
Dim Temp_word As Word
Dim Temp_single As Single
Dim S As String * 6

' Globale Variable für originale Calibration Data aus Sensor
Dim W1 As Word
Dim W2 As Word
Dim W3 As Word
Dim W4 As Word

' Globale Variablen für umgerechneten Calibration Data
Dim C1 As Word
Dim C2 As Word
Dim C3 As Word
Dim C4 As Word
Dim C5 As Word
Dim C6 As Word

' Globale Variablen für Luftdruck und Temperatur aus Sensor
Dim D1 As Word
Dim D2 As Word
Dim Ut1 As Single
Dim Dt As Single
Dim T As Single
Dim T2 As Single
Dim Offset As Single
Dim Sens As Single
Dim P As Single
Dim P2 As Single
Dim Pm(8) As Single

' Prototypen definieren
Declare Sub Read_calibration_data(byval Adress As Word , Value As Word )

Gosub Contrastset

Locate 1 , 3 : Lcd "Test MS5534"
Locate 2 , 3 : Lcd "by Knickohr"

Enable Timer1
Enable Interrupts

'Wait 1
'Cls

' Reset-Sequence
Temp_word = Reset_sequence
Shiftout Din , Sclk , Temp_word , 1 , 16 , 50
For V = 1 To 5
   Pulseout Portd , 1 , 100
   Waitus 100
Next V

' Calibration Data auslesen und auf Display ausgeben
Call Read_calibration_data(read_cali_data_1 , W1)
Call Read_calibration_data(read_cali_data_2 , W2)
Call Read_calibration_data(read_cali_data_3 , W3)
Call Read_calibration_data(read_cali_data_4 , W4)
Gosub Calc_calibration_data

'Cls

'Locate 1 , 1 : Lcd W1
'Locate 1 , 9 : Lcd W2
'Locate 2 , 1 : Lcd W3
'Locate 2 , 9 : Lcd W4

'Wait 1
'Cls

'Locate 1 , 1 : Lcd C1
'Locate 1 , 7 : Lcd C2
'Locate 1 , 12 : Lcd C3
'Locate 2 , 1 : Lcd C4
'Locate 2 , 6 : Lcd C5
'Locate 2 , 11 : Lcd C6

Wait 1
Cls

Do

   Locate 1 , 16 : Lcd "*"

   ' Pressure Measurement

   ' Reset-Sequence
   Temp_word = Reset_sequence
   Shiftout Din , Sclk , Temp_word , 1 , 16 , 50
   For V = 1 To 5
      Pulseout Portd , 1 , 100
      Waitus 100
   Next V

   ' Saubere Startbedingungen schaffen
   Reset Sclk
   Reset Din

   ' START + Adresse + STOP + 2x warten
   Temp_word = Conv_start_press
   Shiftout Din , Sclk , Temp_word , 1 , 12 , 50
   V = 0
   Do                                                                           ' Warten auf "end of conversation"
      Incr V
      If V > 50 Then Exit Do
      Waitms 1
   Loop Until Dout = 0
   If V < 50 Then                                                               ' nur wenn kein Timeout
      Shiftin Dout , Sclk , D1 , 0 , 16 , 50
      Pulseout Portd , 1 , 100
'      Locate 1 , 1 : Lcd D1
'   Else
'      Locate 1 , 1 : Lcd "Fehler Druck"
   End If

   ' Temperature Measurement

   ' Reset-Sequence
   Temp_word = Reset_sequence
   Shiftout Din , Sclk , Temp_word , 1 , 16 , 50
   For V = 1 To 5
      Pulseout Portd , 1 , 100
      Waitus 100
   Next V

   ' Saubere Startbedingungen schaffen
   Reset Sclk
   Reset Din

   ' START + Adresse + STOP + 2x warten
   Temp_word = Conv_start_temp
   Shiftout Din , Sclk , Temp_word , 1 , 12 , 50
   V = 0
   Do                                                                           ' Warten auf "end of conversation"
      Incr V
      If V > 50 Then Exit Do
      Waitms 1
   Loop Until Dout = 0
   If V < 50 Then                                                               ' nur wenn kein Timeout
      Shiftin Dout , Sclk , D2 , 0 , 16 , 50
      Pulseout Portd , 1 , 100
'      Locate 2 , 1 : Lcd D2
'   Else
'      Locate 2 , 1 : Lcd "Fehler Temp"
   End If

   ' Temperatur berechnen
   Ut1 = 8 * C5
   Ut1 = Ut1 + 20224
   Dt = D2 - Ut1
   Temp_single = C6 + 50
   Temp_single = Temp_single * Dt
   Temp_single = Temp_single / 1024
   T = 200 + Temp_single

   ' Luftdruck berechnen
   Temp_single = C4 - 512
   Temp_single = Temp_single * Dt
   Temp_single = Temp_single / 4096
   Temp_word = C2 * 4
   Offset = Temp_single + Temp_word
   Temp_single = C3 * Dt
   Temp_single = Temp_single / 1024
   Temp_single = Temp_single + 24576
   Sens = C1 + Temp_single
   Temp_single = D1 - 7168
   Temp_single = Sens * Temp_single
   Temp_single = Temp_single / 16384
   Temp_single = Temp_single - Offset
   Temp_single = Temp_single * 10
   Temp_single = Temp_single / 32
   P = Temp_single + 2500

   ' Second-Order Temperature Compensation
   Select Case T
      Case Is < 200
         Temp_single = 200 - T
         Temp_single = Temp_single ^ 2
         Temp_word = C6 + 24
         Temp_single = Temp_single * Temp_word
         Temp_single = 11 * Temp_single
         T2 = Temp_single / 1048576
         Temp_single = P - 3500
         Temp_single = Temp_single * T2
         Temp_single = Temp_single * 3
         P2 = Temp_single / 16384
      Case Is > 450
         Temp_single = 450 - T
         Temp_single = Temp_single ^ 2
         Temp_word = C6 + 24
         Temp_single = Temp_single * Temp_word
         Temp_single = 3 * Temp_single
         T2 = Temp_single / 1048576
         Temp_single = P - 10000
         Temp_single = Temp_single * T2
         P2 = Temp_single / 8192
      Case Else
         T2 = 0
         P2 = 0
   End Select
   T = T - T2
   P = P - P2

   ' Mittelwertbildung über 8 Messungen
   Select Case P                                                                ' Plausibilitätsprüfung
      Case Is < 8000
         !nop
      Case Is > 11000
         !nop
      Case Else
         For V = 1 To 7
            W = V + 1
            Pm(v) = Pm(w)
         Next V
         Pm(8) = P
         If Pm(1) <> 0 Then                                                     ' allererste 7 Messung nicht mitteln
            Temp_single = 0
            For V = 1 To 8
               Temp_single = Temp_single + Pm(v)
            Next V
            P = Temp_single / 8
         End If
   End Select

   ' Druckberechnung bezogen auf Meereshöhe
   Temp_single = T / 10
   Temp_single = Temp_single + 273.15
   Temp_single = 0.0065 / Temp_single
   Temp_single = Temp_single * Hoehe
   Temp_single = 1 - Temp_single
   Temp_single = Temp_single ^ 5.255
   P = P / Temp_single

'   Wait 1
'   Cls

'   Locate 1 , 5 : Lcd Time$
   T = T * 10                                                                   ' 0.01° Resolution
   Temp_integer = Round(t)
   S = Str(temp_integer)
   Locate 1 , 5 : Lcd Format(s , "  0.00") ; "ßC"
   Temp_integer = Round(p)
   S = Str(temp_integer)
   Locate 2 , 3 : Lcd Format(s , "    0.0") ; "mbar"
   Locate 1 , 16 : Lcd " "

   Wait 1

Loop

End

Sectic:
   !nop
   Return

Contrastset:
   V = 15
   V = V And &B00001111
   V = V + &B01110000
   W = 15
   Shift W , Right , 4
   W = W + &B01010100
   _temp1 = &B00101001
   !rCall _Lcd_control
   _temp1 = V
   !rCall _Lcd_control
   _temp1 = W
   !rCall _Lcd_control
   _temp1 = &B00101000
   !rCall _Lcd_control
   Return


Calc_calibration_data:

   ' C1 aus Word1 berechnen
   C1 = W1
   Shift C1 , Right , 1

   ' C2 aus Word3 und Word4 berechnen
   C2 = W3 And &B0000000000111111
   Shift C2 , Left , 6
   Temp_word = W4 And &B0000000000111111
   C2 = C2 + Temp_word

   ' C3 aus Word4 berechnen
   C3 = W4
   Shift C3 , Right , 6

   ' C4 aus Word3 berechnen
   C4 = W3
   Shift C4 , Right , 6

   ' C5 aus Word1 und Word2 berechnen
   C5 = W1 And &B0000000000000001
   Shift C5 , Left , 10
   Temp_word = W2
   Shift Temp_word , Right , 6
   C5 = C5 + Temp_word

   ' C6 aus Word2 berechnen
   C6 = W2 And &B0000000000111111

   Return

Sub Read_calibration_data(byval Adress As Word , Value As Word )

   ' Saubere Startbedingungen schaffen
   Reset Sclk
   Reset Din

   ' START + Adresse + STOP + 1x warten
   Shiftout Din , Sclk , Adress , 1 , 13 , 50
   Shiftin Dout , Sclk , Value , 0 , 16 , 50

   ' weiteren SCLK für sauberen Abschluß
   Pulseout Portd , 1 , 100

End Sub

Markus, das Buch hat sich schon gelohnt ! :)

Thomas
 

Anhänge

  • MS5534.jpg
    MS5534.jpg
    187,2 KB · Aufrufe: 78
Nochmals herzlichen Glückwunsch!

Hei Thomas,

da bin ich ja begeistert! Dann waren wir gestern ja doch auf dem richtigen Weg und die Werte die wir gestern noch ausgelesen haben waren plausibel. Ja da freu ich mich aber.

Noch kurz zur Erläterung für alle:
Das Buch von dem Thomas spricht ist das Buch "Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie: Programmierung in Assembler und C - Schaltungen und Anwendungen" von Günter Schmitt.
Und nachdem Thomas ja eh in einem der letzten Threads angekündigt hat, dass er jetzt mehr in Assembler einsteigen möchte/muss habe ich ihm gleich das Buch zu seinem gestrigen Wiegenfeste :flowers: vermacht.
Freut mich, dass das Buch angekommen ist :p

Damit kann die Astro-Wetterstation um eine weitere Komponente erweitert werden.

Schönen Abend,
Markus
 
Hallo zusammen :)

Es hat einen Codeupdate gegeben (siehe oben). Die Temperatur wird jetzt auf 0,01°C ausgegeben und eine "Second-Order Temperature Compensation" zur Liniearisierung der Temperatur- und Druckwerte ist implementiert. Vorsicht bei der Berechnung der Werte, sie können recht hohe Zahlen annehmen ! Long Integer oder besser Single ist notwendig.

Das Ding ist jetzt so genau, das selbst ein Höhenunterschied von 1m ! stabil angezeigt wird. Es ist also notwendig, die Höhe des Standortes genau zu kennen (GPS).

:trytofly:

@Markus
Das "EMV-Problem" war kein EMV-Problem, sondern ein Fehler in der Berechnung der Second-Order Temperature Compensation. Jedesmal, wenn die Temperatur unter 20°C fiel, gab er unsinnige Werte aus. Nun ja, und wenn ich das Ding dann in die Finger nahm, war die Temperatur wieder über 20°C ... :stoned:

Thomas
 
Hallo Thomas,

das Projekt ist genau das was ich gesucht habe. Da ich elektronisch nicht so bewandert bin, meine Frage: Kannst du mir bitte den Bauplan und die Stückliste für das Projekt senden??

Wäre tolle wenn du mir diesen geben könntest.


Ich möchte gerne in Abhängigkeit des Luftdruckes einen Schrittmotor steuern (d.h. bei steigendem Luftdruck nach rechts und bei fallendem nach links usw.).


MfG
Ronny
 
Fehlerhafte Werteberechnung ?

Hallo Leute,

ich bekomme hier echt noch die Krise ! :shout:

Was anfangs mit dem ersten MS5534-Sensor gut funktioniert hat, stellt sich bei anderen Sensoren als echtes Problem heraus. Offensichtlich streuen die Dinger dermaßen, das man keine Richtwerte angeben kann. Komischerweise ließen sich die Werte beim ersten Sensor ohne Probleme berechnen und waren auch plausibel.

Doch jetzt habe ich 10 weitere MS5534-Sensoren hier liegen. Und keiner ist von den Werten her, nur im entferntesten wie der andere. Jetzt stellt sich für mich die Frage, ob ich einfach die Werte und Kalibationsdaten falsch auslese oder berechne. Oder aber die Sensoren sind Müll, was ich eigentlich nicht glaube.

Kann hier mal jemand über den Code drüber schauen ? Vielleicht sehe ich den Wald vor lauter Bäumen nicht. Irgendwo muß doch der Hund begraben sein !

Code:
$regfile = "m644def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 40
$prog &HFF , &HE2 , &HD9 , &HFE                                                 ' BODEN=1,8V, JTAG disabled, sonst Standard

Config Clock = Soft , Gosub = Sectic
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
Config Lcd = 16 * 2 , Chipset = Dogm162v3

' Timer1, Fast-PWM (Mode 15), Prescale = 1, variable Frequenz, Tast 1:1, OC1A -> ca. 32.768Hz
Tccr1a.7 = 0                                                                    ' COM1A1
Tccr1a.6 = 1                                                                    ' COM1A0
Tccr1a.1 = 1                                                                    ' WGM11
Tccr1a.0 = 1                                                                    ' WGM10
Tccr1b.4 = 1                                                                    ' WGM13
Tccr1b.3 = 1                                                                    ' WGM12
Tccr1b.2 = 0                                                                    ' CS12
Tccr1b.1 = 0                                                                    ' CS11
Tccr1b.0 = 1                                                                    ' CS10
Ocr1ah = 0
Ocr1al = 120

Cursor Off Noblink
Cls

Config Portd.0 = Output
Portd.0 = 0                                                                     ' GND MS5534
Sclk Alias Portd.1
Config Portd.1 = Output                                                         ' SCLK MS5534
Dout Alias Pind.2
Config Pind.2 = Input                                                           ' Dout MS5534
Din Alias Portd.3
Config Portd.3 = Output                                                         ' Din MS5534
Mclk Alias Portd.5
Config Portd.5 = Output                                                         ' MCLK MS5534
Config Portd.6 = Output
Portd.6 = 1                                                                     ' VDD MS5534

Const Hoehe = 610
Const Druckkorrektur = 0
Const Tempkorrektur = 0

Const Conv_start_press = &B1111010000000000
Const Conv_start_tempr = &B1111001000000000
Const Read_cali_data_1 = &B1110101010000000
Const Read_cali_data_2 = &B1110101100000000
Const Read_cali_data_3 = &B1110110010000000
Const Read_cali_data_4 = &B1110110100000000
Const Reset_sequence = &B1010101010101010

Dim V As Word                                                                   ' allgemeine Variable
Dim W As Word                                                                   ' allgemeine Variable
Dim Z As Byte                                                                   ' allgemeiner Zähler
Dim Temp_integer As Integer
Dim Temp_word As Word
Dim Temp_single1 As Single
Dim Temp_single2 As Single
Dim Temp_long As Long
Dim S As String * 6

Dim Ms5534_w(4) As Word
Dim Ms5534_c(6) As Long

Dim D1 As Long
Dim D2 As Long
Dim Dt As Single
Dim T1 As Single
Dim T2 As Single
Dim Offset As Single
Dim Sens As Single
Dim P1 As Single
Dim P2 As Single
Dim Pm(8) As Single

Declare Sub Read_calibration_data(byval Adress As Word , Value As Word )

Gosub Contrastset

Locate 1 , 3 : Lcd "Test MS5534"
Locate 2 , 3 : Lcd "by Knickohr"

Enable Timer1
Enable Interrupts

Wait 1
Cls

' MS5534 Reset-Sequence

Reset Sclk
Reset Din
Waitus 10
Temp_word = Reset_sequence
Shiftout Din , Sclk , Temp_word , 1 , 16 , 10
Reset Din
Waitus 10
For Z = 1 To 5                                                                  ' 5 weitere SCLKs für sauberen Abschluß
   Pulseout Portd , 1 , 10
   Waitus 25
Next Z

' MS5534 Calibration-Data auslesen

Reset Sclk
Waitus 25
Call Read_calibration_data(read_cali_data_1 , Ms5534_w(1))
Call Read_calibration_data(read_cali_data_2 , Ms5534_w(2))
Call Read_calibration_data(read_cali_data_3 , Ms5534_w(3))
Call Read_calibration_data(read_cali_data_4 , Ms5534_w(4))
Temp_word = Ms5534_w(1) And &B1111111111111110                                  ' C1 aus Word1 berechnen
Shift Temp_word , Right , 1
Ms5534_c(1) = Temp_word And &B0111111111111111
Temp_word = Ms5534_w(3) And &B0000000000111111                                  ' C2 aus Word3 und Word4 berechnen
Shift Temp_word , Left , 6
Temp_long = Temp_word And &B0000111111000000
Temp_word = Ms5534_w(4) And &B0000000000111111
Ms5534_c(2) = Temp_long + Temp_word
Temp_word = Ms5534_w(4) And &B1111111111000000                                  ' C3 aus Word4 berechnen
Shift Temp_word , Right , 6
Ms5534_c(3) = Temp_word And &B0000001111111111
Temp_word = Ms5534_w(3) And &B1111111111000000                                  ' C4 aus Word3 berechnen
Shift Temp_word , Right , 6
Ms5534_c(4) = Temp_word And &B0000001111111111
Temp_word = Ms5534_w(1) And &B0000000000000001                                  ' C5 aus Word1 und Word2 berechnen
Shift Temp_word , Left , 10
Temp_long = Temp_word And &B0000010000000000
Temp_word = Ms5534_w(2) And &B1111111111000000
Shift Temp_word , Right , 6
Temp_word = Temp_word And &B0000001111111111
Ms5534_c(5) = Temp_long + Temp_word
Ms5534_c(6) = Ms5534_w(2) And &B0000000000111111                                ' C6 aus Word2 berechnen

Cls

Locate 1 , 1 : Lcd Ms5534_w(1)
Locate 1 , 9 : Lcd Ms5534_w(2)
Locate 2 , 1 : Lcd Ms5534_w(3)
Locate 2 , 9 : Lcd Ms5534_w(4)

Wait 1
Cls

Locate 1 , 1 : Lcd Ms5534_c(1)
Locate 1 , 7 : Lcd Ms5534_c(2)
Locate 1 , 12 : Lcd Ms5534_c(3)
Locate 2 , 1 : Lcd Ms5534_c(4)
Locate 2 , 6 : Lcd Ms5534_c(5)
Locate 2 , 11 : Lcd Ms5534_c(6)

Wait 1
Cls

Do

   Locate 1 , 16 : Lcd "*"

   ' Pressure Measurement

   Temp_word = Conv_start_press                                                 ' MS5534-Druck-Messung
   Shiftout Din , Sclk , Temp_word , 1 , 12 , 10
   Waitus 10
   Reset Din
   Z = 0
   Do                                                                           ' Warten auf "end of conversation"
      Incr Z
      If Z > 50 Then Exit Do
      Waitms 1
   Loop Until Dout = 0
   If Z < 50 Then                                                               ' nur wenn kein Timeout
      Set Sclk
      Waitus 10
      Shiftin Dout , Sclk , D1 , 0 , 16 , 10
      Waitus 10
      Reset Sclk                                                                ' weiteren SCLK für sauberen Abschluß
      Pulseout Portd , 1 , 10
      Locate 1 , 1 : Lcd D1
   Else
      Locate 1 , 1 : Lcd "Fehler Druck"
   End If

   ' Temperature Measurement

   Temp_word = Conv_start_tempr                                                 ' MS5534-Temp-Messung
   Shiftout Din , Sclk , Temp_word , 1 , 12 , 10
   Waitus 10
   Reset Din
   Z = 0
   Do                                                                           ' Warten auf "end of conversation"
      Incr Z
      If Z > 50 Then Exit Do
      Waitms 1
   Loop Until Dout = 0
   If Z < 50 Then                                                               ' nur wenn kein Timeout
      Set Sclk
      Waitus 10
      Shiftin Dout , Sclk , D2 , 0 , 16 , 10
      Waitus 10
      Reset Sclk                                                                ' weiteren SCLK für sauberen Abschluß
      Pulseout Portd , 1 , 10
      Locate 2 , 1 : Lcd D2
   Else
      Locate 2 , 1 : Lcd "Fehler Temp"
   End If

   ' Temperatur und Druckwerte berechnen

   Temp_single1 = 8 * Ms5534_c(5)
   Temp_single1 = Temp_single1 + 20224
   Temp_single1 = D2 - Temp_single1
   Dt = Temp_single1 + Tempkorrektur
   Temp_single1 = Ms5534_c(6) + 50
   Temp_single1 = Temp_single1 * Dt
   Temp_single1 = Temp_single1 / 1024
   T1 = Temp_single1 + 200
   Temp_single1 = Ms5534_c(4) - 512
   Temp_single1 = Temp_single1 * Dt
   Temp_single1 = Temp_single1 / 4096
   Temp_single2 = Ms5534_c(2) * 4
   Offset = Temp_single1 + Temp_single2
   Temp_single1 = Ms5534_c(3) * Dt
   Temp_single1 = Temp_single1 / 1024
   Temp_single1 = Temp_single1 + 24576
   Sens = Ms5534_c(1) + Temp_single1
   Temp_single1 = D1 - 7168
   Temp_single2 = Sens / 16384
   Temp_single1 = Temp_single1 * Temp_single2
   Temp_single1 = Temp_single1 - Offset
   Temp_single1 = Temp_single1 / 3.2
   Temp_single1 = Temp_single1 + 2500
   P1 = Temp_single1 + Druckkorrektur

   ' Second-Order Temperature Compensation

   Select Case T1
      Case Is < 200
         Temp_single1 = 200 - T1
         Temp_single1 = Temp_single1 ^ 2
         Temp_single2 = Ms5534_c(6) + 24
         Temp_single2 = 11 * Temp_single2
         Temp_single1 = Temp_single1 * Temp_single2
         T2 = Temp_single1 / 1048576
         Temp_single1 = P1 - 3500
         Temp_single1 = Temp_single1 * T2
         Temp_single1 = Temp_single1 * 3
         P2 = Temp_single1 / 16384
      Case Is > 450
         Temp_single1 = 450 - T1
         Temp_single1 = Temp_single1 ^ 2
         Temp_single2 = Ms5534_c(6) + 24
         Temp_single2 = 3 * Temp_single2
         Temp_single1 = Temp_single1 * Temp_single2
         T2 = Temp_single1 / 1048576
         Temp_single1 = P1 - 10000
         Temp_single1 = Temp_single1 * T2
         P2 = Temp_single1 / 8192
      Case Else
         T2 = 0
         P2 = 0
   End Select
   T1 = T1 - T2
   T1 = T1 / 10
   P1 = P1 - P2
   P1 = P1 / 10

   ' Druckberechnung bezogen auf Meereshöhe

   Temp_single1 = T1 + 273.15
   Temp_single1 = 0.0065 / Temp_single1
   Temp_single1 = Temp_single1 * Hoehe
   Temp_single1 = 1 - Temp_single1
   Temp_single1 = Temp_single1 ^ 5.255881
   P1 = P1 / Temp_single1

   Wait 1
   Cls

   Locate 1 , 5 : Lcd Time$
   T1 = T1 * 100                                                                ' 0.01° Resolution
   Temp_integer = Round(t1)
   S = Str(temp_integer)
   Locate 1 , 5 : Lcd Format(s , "  0.00") ; "ßC"
   P1=P1*10                                                                      ' 0.1mbar Resolution
   Temp_integer = Round(p1)
   S = Str(temp_integer)
   Locate 2 , 3 : Lcd Format(s , "    0.0") ; "mbar"
   Locate 1 , 16 : Lcd " "

   Wait 1

Loop

End

Sectic:
   !nop
   Return

Contrastset:
   V = 15
   V = V And &B00001111
   V = V + &B01110000
   W = 15
   Shift W , Right , 4
   W = W + &B01010100
   _temp1 = &B00101001
   !rCall _Lcd_control
   _temp1 = V
   !rCall _Lcd_control
   _temp1 = W
   !rCall _Lcd_control
   _temp1 = &B00101000
   !rCall _Lcd_control
   Return


Sub Read_calibration_data(byval Adress As Word , Value As Word )
   Shiftout Din , Sclk , Adress , 1 , 13 , 10                                   ' START + Setup + STOP + 1x warten
   Reset Din
   Waitus 10
   Set Sclk
   Waitus 10
   Shiftin Dout , Sclk , Value , 0 , 16 , 10
   Waitus 10
   Reset Sclk                                                                   ' weiteren SCLK für sauberen Abschluß
   Pulseout Portd , 1 , 10
   Waitus 25
End Sub

Bin echt am Verzweifeln. Die Wetterstationen sind in Serie und die doofen Druckdinger tun nicht so, wie sie sollen. Habe die letzten beiden Tage damit verbracht, nach einem Fehler zu suchen :confused:

Mein momentaner "Workaround" besteht darin, 2 Korrekturwerte einzufügen, um auf die gleichen Temperatur und Druckwerte zu kommen. Das kanns aber nicht sein, da die Sensoren laut Hersteller offensichtlich abgeglichen sind (mit den Kalibtrationswerten) und sehr genau sein sollen :mad:

Thomas
 
Hallo Thomas,

das ist ärgerlich, ich habe jetzt gerade keine Zeit, sehe mir aber heute abend mal das Datenblatt und dein Programm an, vielleicht fällt mir etwas auf.

Es wäre schön, wenn wir Thomas bei dem Problem helfen könnten, also alle, die sich ein bisschen mit Bascom auskennen, bitte mithelfen :)

Grüße,
Dirk
 
Hallo Dirk,
hallo Thomas !

Natürlich würde ich Thomas auch sehr gerne helfen...

Bis ich aber die Hälfte von dem Code verstanden habe, hat er die Version 4.1 schon lange im Umlauf. :D

Von daher beschränkt sich meine Tätigkeit auf Daumendrücken. ;)

Wünsche es aber gerade Thomas, dass ihr den "Fehler" schnell findet.

Grüße,
Cassio
 
Guten Morgen.

Hmmm, mir kam da gerade eine Idee. Es muß ja nicht BASCOM sein. Eine ASM Routine zum Auslesen der Kalibrationsdaten und der Werte müßte auch gehen. Ich denke da an eine LIB. Nur leider bin ich echt zu doof dazu, so etwas zu basteln ;)

Wenn ich doch nur irgendwo einen Vergleich hätte. Bisher habe ich in den unendlichen Weiten des WWW nichts brauchbares gefunden. Nun ja, ich habe auch nur nach BASCOM gesucht.

Thomas.
 
Hallo,

ja Dirk, was soll es denn sonst noch sein ? Ich habe mit den ausgelesenen Werten mal "von Hand" berechnet. Komme da auch auf unsinnige Werte. Interessanterweise sind die Korrekturwerte aber alle innerhalb des gültigen Bereiches, auch wenn sie dermaßen streuen von Sensor zu Sensor.

Ich habe auch schon mit dem MSCLK etwas rum gespielt. Den stört es fast gar nicht, welche Frequenz dort anliegt. Da kommen die gleichen Werte raus. Seltsam finde ich nur, das Intersema da so peinlichst auf die 32768Hz besteht. Nun gut, soll so sein.

Vielleicht habe ich auch noch irgendetwas im Datenblatt übersehen, oder als letzte Alternative, die Sensoren sind doch madig. Kann ich mir aber echt nicht denken. Deshalb hätte ich ach gerne ein "Vergleichsaufbau", in dem man die Sensoren mal probeweise rennen lassen könnte.

Bin echt am Verzweifeln ! :help:

Thomas
 
Hallo,

Guten Morgen Thomas,
du meinst, es liegt am Auslesen der Werte?

Ich bereite zur Übersichtlichkeit die Kalibirier-Worte noch mal auf ...

Arrangement (Bit-pattern) of calibration data in Word1 to Word4
Word 1 - 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 | 10 - C1 | C5
Word 2 - 09 08 07 06 05 04 03 02 01 00 | 05 04 03 02 01 00 - C5 | C6
Word 3 - 09 08 07 06 05 04 03 02 01 00 | 11 10 09 08 07 06 - C4 | C2
Word 4 - 09 08 07 06 05 04 03 02 01 00 | 05 04 03 02 01 00 - C3 | C2

Eventuell bringt das ein wenig Klarheit für die Fehlersuche ...

Oder hast Du da evtl irgendwo MSB/LSB-Verdrehungen/Vertauschungen drin wie ich bei meiner 1-Wire-Routine ?
(Byte war gespiegelt)

Ich hab mir den Datentransfer (Fig6a) angesehen.

Reingetaktet (Din) werden die Daten mit positiver Flanke von SCLK und
Bit0 zuerst (Bit 7 als letztes!).
Ausgetaktet werden die Daten mit fallender Flanke von SCLK und
Bit 7 zuerst (Bit 0 als letztes!).
Die Daten sind also zwischen schreiben und lesen gespiegelt :eek:

Senden : Bit0,1,2,3,4,5,.... => Empfangen : Bit15,Bit14,...,Bit1,Bit0

Cmd 1111010000 => D1 als 16bit auslesen (D15..D8 , D7..D0)
Cmd 1111001000 => D2 als 16bit auslesen (D15..D8 , D7..D0)
Cmd 111010101000 => W1 als 16bit auslesen (D15..D8 , D7..D0)
Cmd 111010110000 => W2 als 16bit auslesen (D15..D8 , D7..D0)
Cmd 111011001000 => W3 als 16bit auslesen (D15..D8 , D7..D0)
Cmd 111011010000 => W4 als 16bit auslesen (D15..D8 , D7..D0)
Cmd 101010101010101000000 => Reset

Die Commands sind also auch noch in verschiedenen Längen (9/11/21-Bit)

Die Ausgangsdaten fangen auch noch mit verschieden vielen 1-Bits auf Dout an.
D1/2 => keine 1-Bits vor denn Daten
W1/3 => ein 1-Bit vor den Daten
W2/4 => zwei 1-Bits vor den Daten

"over an easy-to-use 3-wire serial interface" =>=>=> :D :D :D

Gruß
Dino
 
Hallo Dino,

ich vermute auch, das ich irgendwo beim Auslesen und "zerhacken" der Calibration-Data einen Fehler mache. Sonst würden die Werte doch nicht so unterschiedlich sein bei den einzelnen Sensoren.

Arrangement (Bit-pattern) of calibration data in Word1 to Word4
Word 1 - 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 | 10 - C1 | C5
Word 2 - 09 08 07 06 05 04 03 02 01 00 | 05 04 03 02 01 00 - C5 | C6
Word 3 - 09 08 07 06 05 04 03 02 01 00 | 11 10 09 08 07 06 - C4 | C2
Word 4 - 09 08 07 06 05 04 03 02 01 00 | 05 04 03 02 01 00 - C3 | C2

Habs 10000x kontrolliert. Ich sehe einfach keinen Fehler.

Oder hast Du da evtl irgendwo MSB/LSB-Verdrehungen/Vertauschungen drin wie ich bei meiner 1-Wire-Routine ?

Peinlichst darauf geachtet. Ich habe sogar die Kommandos schon gespiegelt :

Const Conv_start_press = &B1111010000000000
Const Conv_start_tempr = &B1111001000000000
Const Read_cali_data_1 = &B1110101010000000
Const Read_cali_data_2 = &B1110101100000000
Const Read_cali_data_3 = &B1110110010000000
Const Read_cali_data_4 = &B1110110100000000
Const Reset_sequence = &B1010101010101010

Moment, warte mal. Vielleicht sollte ich das nicht in eine Konstante schreiben, sondern direkt in die Wort-Variable ?! Probier ich gleich mal.

Die Ausgangsdaten fangen auch noch mit verschieden vielen 1-Bits auf Dout an.
D1/2 => keine 1-Bits vor denn Daten
W1/3 => ein 1-Bit vor den Daten
W2/4 => zwei 1-Bits vor den Daten

Du hat Recht, die Einser davor habe ich aber einfach mal ignoriert und nur die Takte gezählt. Aber jetzt, wo wir es ansprechen. Vielleicht lese ich ja einmal zu früh oder zu spät das Wort ? Boahh, das kanns sein ! Würde auch erklären, warum die Meßwerte so "komisch genau" immer um die typischen Werte liegen, die Kalibrationsdaten aber streuen. Die Meßwerte haben ja auch keine "vorlaufende" Einser. Dino, das kann es schon sein !

Thomas
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)