2019
HOME

Wetterstation in ESP8266BASIC und dem Bosch
BME280-Sensor
Ergänzung zum Buch: Messen, Steuern und Regeln mit Wifi und ESP-BASIC

Sensor BME280Der Bosch-Environment-Sensor BME280 ist in der Lage drei verschiedene Umgebungsgrößen zu erfassen. Der auf einem kleinen Breakout untergebrachte, winzige Sensor mit dem Loch im Metallgehäuse liefert hier über eine I2C-Verbindung die aktuellen Werte von

  • Temperatur
  • Luftdruck
  • Luftfeuchte,

ist also Thermometer, Barometer und Hygrometer auf kleinstem Raum.


Der heutige Maker greift gerne auf Bibliotheken zurück, die eine Art fertige Treiber für die kleinen Breakouts und Sensoren darstellen. Mit drei Klicks und etwas Kopieren und Einfügen wird so ein schnelles Erfolgserlebnis erreicht, was sehr motivierend wirken kann. Sie schirmen den Maker jedoch ab, indem sie einfache Aufrufe bereithalten für das gewünschte Resultat, die eigentliche technische Interaktion bleibt aber im Verborgenen. ESP8266BASIC hat viele solcher Treiber oder Bibliotheken bereits integriert, wodurch z. B. eine Temperatur mit einem speziellen Sensor mit nur einer Programmzeile angezeigt werden kann. Ist die Bibliothek nicht eingebaut und ist die Einbindung komplizierter, kann das trotzdem in ESP8266BASIC erfolgen. Dies soll Anhand des Sensors BME280 hier gezeigt werden.

In einer kargen aber zweckmäßige Anzeige im Browser, die von ESPBASIC aus gesteuert wird, erscheint die Temperatur in °C, der aktuelle lokale Luftdruck in hPa (Hektopascal bzw. mbar), die relative Luftfeuchte in Prozent. Die zusätzlich angezeigte Uhrzeit dient nur der Kontrolle. Mit Hilfe von JavaScript und der Ausführungen aus Messen Steuern Regeln mit Smartphone und Tablet kann mittels fertiger Elemente eine realitätsnähere Anzeige erfolgen, wie hier oben auf einem Smartphone in Firefox dargestellt.



Anschluss und erster Kontakt Testkommunikation


Der Sensor wird über das eingebaute I2C-Protokoll angesprochen (Kapitel 3.8), seine Adresse lautet hier 76HEX, kann aber mit dem I2C-Scanner aus demselben Kapitel individuell in Erfahrung gebracht werden. Die Kommunikation läuft also über die Anschlüsse SCL (Serial Clock) und SDA (Serial Data). Die Versorgungsspannung (Vcc) 3,3 Volt und die Masse (Gnd) kommen vom ESP8266. Bei Benutzung eines D1 Mini ESP8266 erfolgt Verbindung über die Anschlüsse D1 und D2.

  • ESP8266
  • BME280
  • VCC (3,3 Volt)
  • VCC
  • GND
  • GND
  • D1 (GPIO05)
  • SCL
  • D2 (GPIO04)
  • SDA

Der Sensor kann anhand seiner ID identifiziert werden. Im Register bzw. in der Speicherstelle D0HEX liegt die Zahl, die den BME280 vom BMP280 (ohne Hygrometer) unterscheidet. Um diesen Wert zu erhalten sind erste Schritte in I2C erforderlich. An den zwei Leitungen soll Teilnehmer 0x76 angesprochen -, und dazu bewegt werden das Byte von Adresse 0xD0 zu senden. In ESPBASIC sieht das so aus:

adr = hextoint("76")
reg = hextoint("D0")
i2c.setup(D2,D1)
i2c.begin(adr)
i2c.write(reg)
i2c.end()
delay 10
i2c.requestfrom(adr,1)
id = i2c.read()
Print "0x"&Str(int(id/16))&Str(int(id%16))
End

Mit i2c.setup erfolgt die Festlegung der benutzten Leitungen und i2c.write überträgt die gewünschte Speicherstelle an den BME280. Anschließend erfolgt mit i2c.requestfrom ein einziges Byte angefordert und mit i2c.read gelesen. Die Printausgabe zeigt das Ergebnis hexadezimal, weil es im Datenblatt auch so angegeben ist. Basic antwortet im Browser mit

0x60


Done...

Das Ergebnis zeigt, dass bis hier hin alles richtig angeschlossen ist und funktioniert. Es ist ein BME280 vorhanden


Rohdaten auslesen Messwerte holen


Die Messwerte der Sensoren liegen laut Datenblatt im Speicherbereich (Memory map) ab Adresse F7HEX des BME280. Die insgesamt 8 Bytes beinhalten Angaben zu Druck, Temperatur und Feuchtigkeit im Rohformat. Die Umrechnung dieser Rohdaten in Messwerte erfordert einigen Aufwand und ist weiter unten beschrieben.

Im Urzustand liefern diese Speicherplätze die Werte 128, 0, 0, 128, 0, 0, 128 ,0. Die 128 zeigt an, dass der betreffende Sensor nicht aktiv ist. Die Aktivierung von Druck- und Temperatursensor erfolgt über den Inhalt von Register bzw. Adresse F4HEX. Das Hygrometer bleibt zunächst aus, da es an anderer Stelle aktiviert werden muss.

Mit dem Bitmuster 00100111 bzw 32+7 in Register 0xF4 ändern sich nun die Rohdaten der Analog/Digitalwandler für Temperatur und Druck im Speicherbereich ab 0xF7. ESPBASIC liest mit folgenden Zeilen die 8 Bytes Rohdaten in ein Array mit dem Namen t(8).

Dim t(8)
i2c.setup(D2,D1)
adr = hextoint("76")
print "BME280 Einzelmessung für Temp und Druck <br>mit Auslesen aller 8 Bytes"
reg = hextoint("F4")'mode+temp+press
i2c.begin(adr)
i2c.write(reg)
i2c.write(32+7)'00100111
i2c.end()

reg = hextoint("F7")
i2c.begin(adr)
i2c.write(reg)
i2c.end()
delay 10
i2c.requestfrom(adr,8)
for i = 0 to 7
 t(i) = i2c.read()
 Print t(i)
next i

End

BME280 Einzelmessung für Temp und Druck 
mit Auslesen aller 8 Bytes


74
56
0
130
127
0
128
0
Done...

Die Ausgabe zeigt jeweils leicht unterschiedliche Werte mit Ausnahme der letzten beiden Bytes, die dem Hygrometer zugeordnet sind, welches noch deaktiviert ist. Eine Messung von Temperatur und Druck findet jedoch offensichtlich statt.


Kalibrierdaten auslesen Exemplarstreuungen


Der Bosch-Sensor wird mit Kalibrierdaten ausgeliefert, die bei der Herstellung und der Qualitätskontrolle erfasst werden. Diese Daten sind für jedes Exemplar unterschiedlich. Die Berechnung der tatsächlichen Messwerte muss diese Kalibrierdaten berücksichtigen damit die Messdaten auch stimmen. Im Datenblatt des BME280 gibt Bosch an, dass die Kalibrierdaten für die Temperatur und den Druck ab Adresse 0x88 in 24 Bytes abgelegt worden sind. Die ersten 6 Bytes sind Kalibrierdaten zum Temperatursensor, die restlichen 18 Bytes werden zur Berechnung des Luftdrucks herangezogen. Entsprechende Hygrometerdaten stehen an 0xA1 und ab 0xE1. Diese Kalibrierdaten und die Einrechnung erfolgt teilweise über vorzeichenbehaftete 64Bit-Integerwerte, die in BASIC normalerweise als Variablentyp nicht vorkommen. Ein vorzeichenloser ganzzahliger 16Bit-Wert, der in zwei Bytes abgelegt wird, erhält man üblicherweise mit der Rechnung

U16 = 256 * Highbyte + Lowbyte

Da ESPBASIC auch über den Shift-Operator verfügt, kann diese Rechnung auch mit Bitschiebung erreicht werden.

U16 = Highbyte<<8 + Lowbyte

Dies kann nützlich sein, wenn Datenblätter Beispiele in anderen Sprachen angeben.

Vorzeichenbehaftete ganzzahlige 16Bit-Werte liegen vor wenn der 16Bit-Zahlenbereich 0 bis 65535 so geteilt wird, dass auch negative Zahlen möglich sind. Der Bereich wäre dann -32767 bis +32768. Eine 65535 wäre dann eine -1. Da ESPBASIC und die meisten anderen BASIC-Varianten nur Fließpunkzahlen als Typ kennen, muss entsprechend umgerechnet werden. Mit

if x > 32767 then x = x – 65536

erhält x den entsprechend negativen Wert. In C wäre dieser Typ ein int, im Gegensatz zum unsigned int. Oft wird der Typ um deklariert, damit auf jedem System klar wird, wie viele Bits beteiligt sind (z. B. uint32). Die Reihenfolge der Bytes kann unterschiedlich sein. Im BME280 ist die Reihenfolge Lowbyte (LSB), Highbyte (MSB)..


Gesamtlisting mit Berechnungen


Mit diesem Ausführungen und dem Datenblatt des BME280 sollte der folgende Abschnitt in ESPBASIC deutlich werden. Es ist das komplette Listing zur Anzeige der drei Werte im Browser. Ein lauffähiges Programm in ESP8266BASIC entsteht dadurch, dass die Erläuterungen zwischen den Kode-Zeilen entfernt werden. Das Gesamtlisting begint hier mit memclear und endet mit dem return nach der Zeitzuweisung, die nur bei Internetzugang des ESP richtig funktioniert.

memclear
Dim b(8) ' ADC DATA
Dim c(24)' CAL DATA P/T
Dim h(7) ' CAL DATA HUM
i2c.setup(D2,D1)
adr = hextoint("76")
reg = hextoint("88")' TEMP/PRESS calibration data
i2c.begin(adr)
i2c.write(reg)
i2c.end()
delay 10
i2c.requestfrom(adr,24)
for i = 0 to 23
c(i) = i2c.read()
'Print i&" "&c(i)
next i
dig_T1=c(0)+c(1)<<8
dig_T2=c(2)+c(3)<<8
dig_T3=c(4)+c(5)<<8
dig_P1 = c(6) + 256 * c(7)
dig_P2 = c(8) + 256 * c(9)
dig_P3 = c(10) + 256 * c(11)
dig_P4 = c(12) + 256 * c(13)
dig_P5 = c(14) + 256 * c(15)
dig_P6 = c(16) + 256 * c(17)
dig_P7 = c(18) + 256 * c(19)
dig_P8 = c(20) + 256 * c(21)
dig_P9 = c(22) + 256 * c(23)
'Signed!
if dig_T2 > 32767 then dig_T2 = dig_T2 - 65536
if dig_T3 > 32767 then dig_T3 = dig_T3 - 65536
if dig_P2 > 32767 then dig_P2 = dig_P2 - 65536
if dig_P3 > 32767 then dig_P3 = dig_P3 - 65536
if dig_P4 > 32767 then dig_P4 = dig_P4 - 65536
if dig_P5 > 32767 then dig_P5 = dig_P5 - 65536
if dig_P6 > 32767 then dig_P6 = dig_P6 - 65536
if dig_P7 > 32767 then dig_P7 = dig_P7 - 65536
if dig_P8 > 32767 then dig_P8 = dig_P8 - 65536
if dig_P9 > 32767 then dig_P9 = dig_P9 - 65536

Man könnte meinen, dass die Entwickler für den Luftfeuchtesensor und seine Kalibrierdaten verzweifelt auf der Suche nach freien Plätzen waren, die beim BMP noch nicht benutzt wurden. Die Anordnung erfordert dadurch mehr Programmieraufwand beim Hygrometer.

'HUMIDITY
reg = hextoint("A1") 'HUM calibration data
i2c.begin(adr)
i2c.write(reg)
i2c.end()
delay 10
i2c.requestfrom(adr,1)
dig_H1 = i2c.read()
reg = hextoint("E1") 'HUM calibration data
i2c.begin(adr)
i2c.write(reg)
i2c.end()
delay 10
i2c.requestfrom(adr,7)
for i = 0 to 6
h(i) = i2c.read()
'Print i&" "&h(i)
next i
dig_H2 = h(0) + (h(1) * 256) 'int16
dig_H3 = h(2) 'uint8
dig_H4 = h(3) * 16 + (h(4) and 15) 'uint16
dig_H5 = h(5) * 16 + (h(4) and 240) / 16 'uint16
dig_H6 = h(6) ' int8
if dig_H2 > 32767 then dig_H2 = dig_H2 - 65536
if dig_H6 > 127 then dig_H6 = dig_H6 - 256

In den zwei Arrays c(24) und h(7) stehen nun die speziellen Kalibrierdaten des benutzten Sensors. Diese Daten ändern sich nicht und müssen nur einmal abgefragt werden. Im nächsten Schritt erfolgt die Aktivierung aller drei Sensoren, wobei hier das Hyghrometer wieder eine Sonderrolle einnimmt.

reg = hextoint("F2") 'HUM MODE 
i2c.begin(adr)
i2c.write(reg)
i2c.write(5) 'Reg F2 = 00000101 
i2c.end()
reg = hextoint("F4")' PRESS/TEMP Mode
i2c.begin(adr)
i2c.write(reg)
i2c.write(32+7)'Reg F4 = 00100111
i2c.end()

An dieser Stelle ist der BME280 initialisiert und Messbereit. Es folgt nun noch die karge Browseroberfläche, die timergesteuert alle 10 Sekunden die Messwerte abruft. Zur Kontrolle erfolgt auch noch eine Zeitanzeige im Sekundentakt.

Timer 10000,[tm]
Textbox T
html " C<br>"
Textbox press
html " hPa<br>"
textbox hum
html " %<br>"
Textbox date
Timercb 1000,[cb]
Wait

Die eigentliche Messung übernimmt also die Routine an der Stelle [tm]. Dort erfolgt auch die Berechnung von der Temperatur, dem Luftdruck und der relativen Luftfeuchte. Die Gleichungen sind dem Datenblatt entnommen und geringfügig an ESPBASIC angepasst.

[tm] 'MEASUREMENT
reg = hextoint("F7") 'ALL 8 BYTES
i2c.begin(adr)
i2c.write(reg)
i2c.end()
delay 10
i2c.requestfrom(adr,8)
for i = 0 to 7 'PRESS+TEMP+HUM
b(i) = i2c.read()
next i

'T BERECHNEN
adc_T = b(3)<<16 + b(4)<<8 + b(5)
adc_T = adc_T>>4
var1 = (adc_T / 16384 - dig_T1 / 1024) * dig_T2 'OK!
x = adc_T / 131072 - dig_T1>>13
var2 = (x * x) * dig_T3
t_fine = var1 + var2
T = (var1 + var2) / 5120

'P BERECHNEN
adc_p = b(0)*65536+b(1)*256+b(2)
adc_p = adc_p / 16
var1 = (t_fine/2) - 64000
var2 = var1 * var1 * dig_P6 / 32768
var2 = var2 + var1 * dig_P5 * 2
var2 = (var2/4)+(dig_P4 * 65536)
var1 = (dig_P3 * var1 * var1 / 524288 + dig_P2 * var1) / 524288
var1 = (1 + var1 / 32768)*dig_P1
p = 1048576 - adc_p
p = ((p - var2 / 4096) * 6250) / var1
var1 = dig_P9 * p * p / 2147483648
var2 = p * dig_P8 / 32768
p = p + (var1 + var2 + dig_P7) / 16
press = p/100

'H BERECHNEN
adc_h= b(6) * 256 + b(7)
var_H = t_fine - 76800
var_H = ......................................... (siehe unten)
var_H = var_H * (1 - dig_H1 * var_H / 524288)
if var_H > 100 then var_H = 100
if var_H < 0 then var_H = 0
hum = var_H
Wait

[cb]
date = Time("hour:min:sec")
return

var_H = (adc_h - (dig_H4 * 64 + dig_H5 / 16384 * var_H)) * (dig_H2 / 65536 * (1 + dig_H6 / 67108864 * var_H * (1 + dig_H3 / 67108864 * var_H)))

Mit den Ausführungen im Buch „Messen Steuern Regeln mit Smartphone und Tablet“ zu JavaScript und fremden Bibliotheken kann das Aussehen der kargen Browserausgabe entsprechend aufgemöbelt werden. Eine sogenannte Gauge wird dort als fertiges Element benutzt.

Der reine ESPBASIC Quellcode als Text des obigen Listings liegt hier bereit, der für die runden Instrumente ganz oben (ohne die erforderliche Datei gauges.min.js) ist hier zu finden.


Schon in dem im Herbst 2017 erschienenen Messen Steuern Regeln mit Smartphone und Tablet war ESPBASIC ein Thema. Durch die vertiefende Beschäftigung mit der Referenz zu dieser Sprache entstand ein eigenes Buch zu ESP8266-BASIC, da sich ganz neue Perspektiven bei der Umsetzung von Ideen ergaben und diese in dieser Form weiter gereicht werden sollte.

Weitere Bücher
Weitere Software
.
Startseite Bücher Software Digital RTV Musik Kontakt

Für Inhalt und weitere Verzweigung externer Links sind die Betreiber der dortigen Seiten verantwortlich - H.-J. Berndt