Umweltsensor Bosch BME680       

 
                      Elektronik-Labor  Bastelecke  Projekte  Mikrocontoller                        



https://learn.watterott.com/de/sensors/bme680/


Dieser Sensor von Bosch misst Temperatur, Luftdruck, Luftfeuchte und die Belastung mit brennbaren Gasen wie Methan oder Alkohol. Die Platine hat Watterott hergestellt. Dank an Andreas Riedenauer, der mir die Musterplatine besorgt hat. Jetzt wollte ich endlich mal damit experimentieren, war aber erst einmal schockiert, wie kompliziert das alles ist. Das Datenblatt ist eher abschreckend, weil die Auswertung der Messdaten so aufwendig ist. Den ersten Erfolg hatte ich mit dem Arduino und der Bibliothek von Adafruit und ihrem Beispielprogramm. Da konnte ich sehen, dass der Sensor kleinste Höhenunterschiede erkennt, und dass die Luft messbar besser wird, wenn ich die Balkontür öffne.



Das ES-M32: http://www.elexs.de/ESM32.htm


Arduino hin, Arduino her, damit funktioniert es zwar, aber ich verstehe nichts, und das Beispielprogramm belegt schon den halben Speicher. Ich brauche aber gar nicht die volle Genauigkeit und alle Messkanäle. Interessanter ist eine grundlegende Lösung, bei der ich noch alles selbst im Griff habe. Zu diesen Zweck habe ich die Platine an das ES-M32 angeschlossen. Mehr als +5V und I2C braucht man ja nicht. Erstmal reicht es mir, wenn ich die Temperatur und den Druck mit Bascom messen kann. Bei beiden will ich nur die Rohdaten auslesen und auf die komplette Kalibrierung verzichten.

 

Nach einem ausgiebigen Studium des Datenblatts war klar, dass ich nur ein Byte  &H55 in das Register &H74 schreiben muss, um eine Messung mit Druck und Temperatur zu starten. Nach einigen Millisekunden lese ich dann zweimal zwei Bytes für Druck und Temperatur aus.  Jeder Rohwert hat also eine Breite von 16 Bit. Der Druck kommt offenbar invertiert heraus, also als Drifferenz von 65356. Dann konnte ich sehen, dass der Rohwert um 5 abnimmt, wenn ich den Sensor um 1 m anhebe. Tatsächlich nimmt der Druck auf Meereshohe um 100 Pa ab, wenn man 8 m höher geht. Daraus ergab sich, dass ich den Rohwert durch 40 teilen muss, um einen Messewert in HPa zu bekommen. Jetzt zeigt der Sensor 1072 hPa, was ganz grob stimmen dürfte. Wenn ich p nicht als word sondern als single deklariere, bekomme ich auch die Nachkommastellen. Damit kann ich auch wieder Höhenmessungen durchführen. Bei der "richtigen" Auswertung werden allerlei Kalibrierdaten eingerechnet und auch der Temperatureinfluss. In erster Näherung ist das Ergebnis allerdings erstaunlich unabhängig von der Temperatur.



'******************************************
' Temperatur und Druck mit dem Bosch BME680
'******************************************

'MCU config
$regfile = "m32def.dat"
$crystal = 11059200
$hwstack = 256
$swstack = 256
$framesize = 256
$baud = 9600


dim d as byte
dim t as word
dim p as word     'oder single

Config Sda = Portc.4
Config Scl = Portc.5



do
  I2cstart
  I2cwbyte &HEE  'I2C_adresse Schreiben
  I2cwbyte &H74  'Reg_adress
  I2cwbyte &H55  'Wert, Messung starten
  I2cstop
  Waitms 10

  I2cstart
  I2cwbyte &HEE  'I2C_adresse
  I2cwbyte &H1F  'Reg_adress   Auslesebereich
  I2cstart
  I2cwbyte &HEF  'I2C_adresse  Lesen
  I2crbyte d , Ack    'Reg 1F
  p = 256 * d
  I2crbyte d , Ack    'Reg 20
  p= p + d
  p=  65536  -p
  p=p/40          '1 m höher, 5 weniger
  I2crbyte d , Ack    'Reg 21
  I2crbyte d , Ack    'Reg 22
  t = 256*d
  I2crbyte d , Nack   'Reg 23
  t= t+ d
  t=t/100
  t=t-290
  I2cstop
  print  "p = ";
  print p
  print  "t = ";
  print t
  waitms 1000
loop


 

Bei der Auswertung werden insgesamt fünf Bytes ausgelesen. Die ersten beiden gehören zum Druck, die letzten beiden zur Temperatur, das dritte Byte wird verworfen. Die Temperatur lag im Bereich 30000 und sah auf den ersten Blick so aus, als würde die absolute Temperatur in Kelvin in der Auflösung Hundertstel-Grad gezeigt. Also Teilen durch 100 und Subtrahieren von 273, dann stimmte es schon fast. Der Vergleich mit einem anderen Thermometer legte dann nahe, dass 290 subtrahiert werden sollte. Die Abweichung von 17 Grad könnte individuell sein und würde natürlich berücksichtigt, wenn man die offiziellen Kalibrierdaten verwendet.





Ein Vergleich mit dem Datenblatt des BM280 legt nahe, dass diese vereinfachte Auswertung da auch funktionieren könnte. Man müsste nur zwei Registeradressen ändern, die im Quelltext mit angegeben sind. Der Vorteil dieses einfachen Programms ist jedenfalls, dass nur 3% des Speichers, also ca. 1 KB belegt wird. Man könnte also für überschaubare Aufgaben auch sehr viel kleinere Controller wie den Tiny13 einsetzten.




Anpassung für den BMP280



'******************************************
' Temperatur und Druck mit dem Bosch BMP280
'******************************************

'MCU config
$regfile = "m32def.dat"
$crystal = 11059200
$hwstack = 256
$swstack = 256
$framesize = 256
$baud = 9600


dim d as byte
dim t as word
dim p as single 'word 'oder single

Config Sda = Portc.4
Config Scl = Portc.5



do
I2cstart
I2cwbyte &HEE 'I2C_adresse Schreiben
I2cwbyte &HF4 'Reg_adress
I2cwbyte &H55 'Wert, Messung starten
I2cstop
Waitms 100

I2cstart
I2cwbyte &HEE 'I2C_adresse Schreiben,
I2cwbyte &HF7 'Reg_adress Auslesebereich

I2cstart
I2cwbyte &HEF 'I2C_adresse Lesen,
I2crbyte d , Ack 'Reg F7
p = 256 * d
I2crbyte d , Ack 'Reg F8
p = p + d
p = 65536 -p
p = p / 40 '1 m höher, 5 weniger
I2crbyte d , Ack 'Reg F9
I2crbyte d , Ack 'Reg FA
t = 256 * d
I2crbyte d , Nack 'Reg FB
t = t + d
t = t / 100
t = t - 308
I2cstop
print "p = ";
print p
print "t = ";
print t
waitms 1000
loop







Elektronik-Labor  Bastelecke  Projekte  Mikrocontoller