BME280 an ESP32 mit MicroPython

OP #6582623
Lesenswert?

Hallo Experten,
möchte die Daten eines BME280 auf einem oled ssd1306 über einen ESP32-s
ausgeben, mit folgendem Script (Gemäss i2c scan Adressen BME280: 0x40 
und ssd1306: 0x3C):

from machine import Pin, I2C
from time import sleep
import BME280

i2c = I2C(scl=Pin(22), sda=Pin(21), freq=10000)

while True:
  bme = BME280.BME280(i2c=i2c)
  temp = bme.temperature
  hum = bme.humidity
  pres = bme.pressure

  print('Temperature: ', temp)
  print('Humidity: ', hum)
  print('Pressure: ', pres)

  sleep(2000)

Das Script des BME280 Modules da umfangreich im Anhang.
Bekomme aber laufend folgende Fehlermeldung, die meiner Meinung nach vom
BME280 Mudule herrührt und evtl. etwas mit falschen Adressen zu tun hat.
(Habe die Adresse im BME280 Modul in Zeile 4 auf 0x40 geändert):

Traceback (most recent call last):

 File "<stdin>" line 1, in module

 File "<string>" line 11, in module

 File "BME280.py", line 155, in _init_

 File "BME280.py", line 161, in _load_calibration

 File "BME280.py", line 104, in readU16

OSError: [Errno 19] ENODV

Leider lässt sich die Fehlermeldung syntaktisch nicht korrekt 
wiedergeben.

???
Angehängte Dateien:
Gast #6582745
Lesenswert?

Marcus L. schrieb:
> Hallo Experten,
> möchte die Daten eines BME280 auf einem oled ssd1306 über einen ESP32-s
> ausgeben, mit folgendem Script (Gemäss i2c scan Adressen BME280: 0x40
> und ssd1306: 0x3C):

Jaja, ich weiss, Datenblattlesen ist heutzutage out, stattdessen macht 
man lieber irgendwelchen sinnlosen Blödsinn...

"The 7-bit device address is 111011x. The 6 MSB bits are fixed. The last 
bit is changeable by SDO value and can be changed during operation. 
Connecting SDO to GND results in slave address 1110110 (0x76); 
connection it to VDDIO results in slave address 1110111 (0x77), which is 
the same as BMP280’s I²C address. The SDO pin cannot be left floating; 
if left floating, the I²C address will be undefined. "
#6582779
Lesenswert?

Marcus Lütolf schrieb:
> der BME280 ist mit I2C angeschlossen, da braucht es m.W. keine
> Widerstande, die Pins bzw. die Leitungen werden von SCL und SDA
> jeweils auf HIGH und LOW gezogen ??

Siehe hier: 
https://de.i2c-bus.org/intro/die-funktionsweise-der-i2c-hardware/

I2C ist Open-Drain, kann also aus eigener Kraft nur etwas 
herunterziehen, aber nicht hochziehen --> es braucht Pull-Up Widerstände 
für I2C
Gast #6582811
Lesenswert?

vielen Dank für Eure Hinweise.
bin schon lange am googeln - viele Beiträge/docs gelesen - und habe
im BME280 Modul beide Adressen:

0x76 und 0x77 eingegeben: Fehlermeldung identisch.

Frage mich warum in den vielen Tutorials zu BME280 nichts von einem
pull_up Widerstand steht.
Habe aben eben die docs (MicroPython) gelesen und finde dort weder unter
Software I2C bus noch unter Hardware I2C bus einen entsprecehnden 
Hinweis, bzw. Parameter.
Gast #6582828
Lesenswert?

Marcus Lütolf schrieb:
> Frage mich warum in den vielen Tutorials zu BME280 nichts von einem
> pull_up Widerstand steht.

Weil das mit dem BME auch nix zu tun hat. Das ist Teil der I2C-SPec.


> Habe aben eben die docs (MicroPython) gelesen und finde dort weder unter
> Software I2C bus noch unter Hardware I2C bus einen entsprecehnden
> Hinweis, bzw. Parameter.

Lies einfach die richtige Doku. Und nein, googlen ersetzt nicht das 
Mitdenken...

https://www.nxp.com/docs/en/application-note/AN10216.pdf
https://www.ti.com/lit/an/slva704/slva704.pdf
Gast #6582944
Lesenswert?

Mario M. schrieb:
> Marcus L. schrieb:
>> Gemäss i2c scan Adressen BME280: 0x40
>
> Komisch. Das wäre die Adresse für einen Si7021.

Und viele weitere (kein Wunder bei 7bit-Adressen...)


    Si7021 Humidity/Temp sensor (0x40 only)
    HTU21D-F Humidity/Temp Sensor (0x40 only)
    HDC1008 Humidity/Temp sensor (0x40, 0x41, 0x42 or 0x43)
    TMP007 IR Temperature sensor (0x40 - 0x47)
    TMP006 IR Temperature sensor (0x40 - 0x47)
    PCA9685 16-channel PWM driver default address (0x40 - 0x7F)
    INA219 High-Side DC Current/Voltage sensor (0x40 - 0x4F)
    INA260 Precision DC Current/Power Sensor (0x40 - 0x4F)
Gast #6582980
Lesenswert?

4.7kOhm nun zwischen SCL/SDA und VCC: Fehlermeldung unverändert.

Nochmals am ESP32 Adressen der angeschlossenen I2C gescannt:
unverändert ssd1306 = 0x3C, BME280 = 0x40 ausgegeben.

Im BME280 Modul nochmals 0x76, 0x77 und 0x40 eigetragen, Fehlermeldung 
unverändert.

Meine nach wie vor, dass irgendwo im BME280 Modul ein falscher Eintrag 
steht.
Gast #6583037
Lesenswert?

habe eben noch 2 eigenartige Dinge entdeckt:

habe 2 leicht unterschiedliche BME280.py Module bzw. libraries, eine von 
RandomNerdTutorials und eines von github. Beide produzieren diesselbe
Fehlermeldung.
Wenn ich bei der einen library die oberste Leerzeile entferne bekomme 
ich
aber in der Fehlermeldung dieselben Zeilennummern wie bei der anderen
library. Die sollten sich ja um 1 Zeile unterscheiden.

Und wenn ich im Script zum Auslesen der Werte beim Import und in
der 2. while-Schleifen Zeile BME klein scheibe - bme280 - gibt es eine 
Fehlerzeile weniger und einen anderen OSError: [Errno 110] ETIMEDOUT.
Gast #6583098
Lesenswert?

habe Si7021 versucht, ähnliche Felermeldung, allerdings nur noch

.
.

File "si7021.py", line 23 in _init_

File "si7021.py", line 84 in _get_device_info #ist ja BME280

OSError;: [Errno 19] ENODEV
Gast #6585116
Lesenswert?

dann ist das wohl das Ende des Lateins....
der Fehler passiert in der Zeile <bme = BME280.BME280(i2c=i2c)>
im Script unten (try/except).
Nochmals vilen Dank für die Beiträge.

from machine import Pin, I2C
from time import sleep
import BME280

i2c = I2C(scl=Pin(22), sda=Pin(21), freq=10000)

while True:
  bme = BME280.BME280(i2c=i2c)
  temp = bme.temperature
  hum = bme.humidity
  pres = bme.pressure

  print('Temperature: ', temp)
  print('Humidity: ', hum)
  print('Pressure: ', pres)

  sleep(2000)
Gast #6585178
Lesenswert?

Noch ein kleiner Tip, man sollte beachten ob eine I2C-Adresse als 7Bit 
oder
8Bit gemeint ist. Besonders Leute die keine Datenblaetter lesen und 
glauben das Programmieren heisst das man aus dem Internet Source kopiert 
werden da gerne auf die Fresse fallen. .-)

Olaf
Gast #6585289
Lesenswert?

Marcus Lütolf schrieb:
> dann ist das wohl das Ende des Lateins....


So, ich habe jetzt mal kurz bei mir die Micropython-Version 1.14 
(https://micropython.org/resources/firmware/esp32-idf3-20210202-v1.14.bin) 
auf ein WROOM-32-Modul gespielt und einen BME280 Sensor an die Pins 
13(SCL) sowie 16(SDA) gehängt (die Pins 21 und 22 sind auf meinem 
Devboard nicht herausgeführt).
Ich habe das Skript von unten sowie die Lib aus dem ersten Post genommen 
und siehe da, sowohl Temperatur als auch Feuchtigkeit und Druck werden 
korrekt ausgegeben.

Daher:
- Prüfe Deine Verkabelung
- Probiere andere Pins
- Nimm obige Micropython-Version (oder die analoge für PSRAM, falls Du 
ein Wrover-Modul hast)


> der Fehler passiert in der Zeile <bme = BME280.BME280(i2c=i2c)>
> im Script unten (try/except).
> Nochmals vilen Dank für die Beiträge.
>
> from machine import Pin, I2C
> from time import sleep
> import BME280
>
> i2c = I2C(scl=Pin(22), sda=Pin(21), freq=10000)
>
> while True:
>   bme = BME280.BME280(i2c=i2c)
>   temp = bme.temperature
>   hum = bme.humidity
>   pres = bme.pressure
>
>   print('Temperature: ', temp)
>   print('Humidity: ', hum)
>   print('Pressure: ', pres)
>
>   sleep(2000)
Gast #6585290
Lesenswert?

Hier noch die Ausgaben des Moduls:


ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5148
load:0x40078000,len:12880
load:0x40080400,len:3484
entry 0x40080630
Warning: I2C(-1, ...) is deprecated, use SoftI2C(...) instead
Temperature:  24.27C
Humidity:  65.60%
Pressure:  1003.40hPa
Gast #6586017
Lesenswert?

also bin ein Hobby Bastler und muss mir die Anleitungen Scripts
(Sketches für Arduino/C, mittlerweile aufgegeben)d.h. den ganzen
Lernprozess im Internet besorgen.
Ich darf noch anfügen, dass ich schon mehrere Projekte mit Raspberry's
gebaut habe und mit Python gut vertraut bin.

Selbstverständlich lese ich docs, verstehe aber nicht immer
alles.

Soweit ich verstanden habe bezeichnet das 7. Bit in der Adresse entweder
0x76 wenn der Wert 0 ist und 0x77 wenn der Wert 1 ist.

Aber mein Scan Script gibt mir - wie schon erwähnt - 0x40 als Adresse 
des
BME280 aus.

Ich habe Micropython-Version 1.13, werde sogleich 1.14 laden.

Ich habe mir noch überlegt mit try/except: ValueError das importierte
BME280 Modul systematisch auf die fehlerhaften Zeilen abzusuchen, weiss 
aber
nicht ab das geht.
Gast #6586031
Lesenswert?

Marcus Lütolf schrieb:
> Aber mein Scan Script gibt mir - wie schon erwähnt - 0x40 als Adresse
> des
> BME280 aus.
>
> Ich habe Micropython-Version 1.13, werde sogleich 1.14 laden.
>
> Ich habe mir noch überlegt mit try/except: ValueError das importierte
> BME280 Modul systematisch auf die fehlerhaften Zeilen abzusuchen, weiss
> aber
> nicht ab das geht.

Das Skript scheint ja zu funktionieren, da es bei Planloser 
funktioniert.
Stell doch mal bitte ein Foto (ein scharfes...) Deines Moduls von der 
Vorder- und Rückseite hier ein.
Gast #6586148
Lesenswert?

Auf Deinem Foto ist ein SHT21 an den ESP32 angeschlossen.
Ist das der Sensor, mit dem Du die ganze Zeit testest?

Die BME280-Boards haben 6 Anschlüsse, nicht nur 4.

Falls ja, dann solltest Du einfach eine SHT21-Bibliothek nehmen, die 
Addresse 0x40 passt jedenfalls zum SHT21.
#6586581
Lesenswert?

hi bingo, kann es sein dass du keinen BME280 sondern wie im Bild einen 
BMP280 verbastelt hast. Ich habe von Ali alle drei Bosch-Sensoren hier 
liegen, BMP/BME280 und BME680, die kleinen silbernen chips haben alle 
eine etwas andere Form. Die Größe ist in den specs jeweils vermerkt. 
Versuch mal eine BMP280 Libary 
(https://github.com/dafvid/micropython-bmp280.git) z.Bsp. Am uPython 
image liegt es m.E. normalerweise nicht und auch nicht an den pullups. 
I2C funktionierte eigentlich meist zuverlässig. Lass dich nicht verrückt 
machen und versuch zur not einfach mal die Register von Hand auszulesen, 
Bsp. dazu gibt es in der uPython docu zu Hauf. Und wenn ich mich richtig 
erinner geht die BME280 lib nicht mit dem BMP280.
Gruß Gerd
Gast #6586790
Lesenswert?

tja geehrte Experten, muss mich ...löffeln !!!
habe 2 RPi's mit BME280 auswärts im Betrieb und meinte dieselben für
den ESP32 bestellt zu haben, tatsächlich sind es aber si7021 !!!
Mit der si7021 library gibt es nur noch einen Fehler im folgenden 
Script:

1 import si7021

2 import machine

3 i2c = machine.I2C(sda=machine.Pin(21),scl=machine.Pin(22))
4
5 temp_sensor = si7021.Si7021(i2c)
6
7 print('Serial:{value}'.format(value=temp_sensor.serial))

8 print('Identifier:{value}'.format(value=temp_sensor.identifier))

9 print('Temperature:{value}'.format(value=temp_sensor.temperature))

10print
('Relative 
Humidity:{value}'.format(value=temp_sensor.relative_humidity))


an der 9. Zeile stürzt das Script ab weil in der si7021 library offenbar
ein Fehler ist in

<def _get_data(self, command):>

und zwar in der Zeile

<self.i2c.readfrom_into(self.address, data)>

wobei das eigentlich nur am Parameter 'data' liegen kann, welchem 4 
Zeilen weiteroben der Wert

<bytearray(3)>

zugeordnet ist. Habe aber im datasheet von si7021 keinen hilfreichen
Hinweis gefunden.

Wenn ich obigem Script die betreffende 9. Zeile kommentiere bekomme ich 
die
'Relative Humidity' richtig abngezeigt.
Gast #6589312
Lesenswert?

Hallo,

Ich würde es zusätzlich noch mit Pullups probieren. Dasgeht auch per SW.
Dazu kann man im Micropython den I2C bus wie folgt initialisieren.

i2c = 
machine.I2C(scl=machine.Pin(0,machine.Pin.PULL_UP),sda=machine.Pin(2,mac 
hine.Pin.PULL_UP))

So laufen zwei ESP8266-01 bei mir seit Jahren stabil durch.
Ohne die Pullups gabs immer mal hänger.

Grüße
    Christian
Gast #6590156
Lesenswert?

mit den wie oben definierten pull_up Widerständen und mit einem neuen 
Si7021 leider identische Fehlermeldung.
Wäre schwer verständlich warum pull_up's bei Temperatur erforderlich 
sind
und bei den anderen 3 Werten nicht.
OP #6590688
Lesenswert?

ich kann Deiner Argumentation bez. Widerständen nicht folgen:
Die pull_up bzw. pull_down Widerstände sollen doch einen konstanten
Pin Wert, 0 oder 1 garantieren um ein "Flottieren" zu verhindern.

Es gibt in meinem Aufbau nur 2 entsprechende Pin's, SCL und SDA. Wenn 
Die Datenübertragung bei 3 von 4 Werten ohne Fehler stattfindet kann es 
nicht
an den pull_up Werten  liegen ???
Zudem messe ich am SCL und SDA Pin auch ohne pull_up konstante 3.3V.
Gast #6590800
Lesenswert?

Marcus L. schrieb:
> ich kann Deiner Argumentation bez. Widerständen nicht folgen:
> Die pull_up bzw. pull_down Widerstände sollen doch einen konstanten
> Pin Wert, 0 oder 1 garantieren um ein "Flottieren" zu verhindern.

Du musst Dir mal die Funktionsweise von I2C ansehen. Dann kannst Du den 
nötigen Pull-Up Widerstand ausrechnen. Die 2.2 sind ganz OK, es könnte 
aber noch weniger sein.

Espressif schreibt übrigens explizit in der Doku:
"ESP32’s internal pull-ups are in the range of tens of kOhm, which is, 
in most cases, insufficient for use as I2C pull-ups. Users are advised 
to use external pull-ups with values described in the I2C 
specification."

Daher mein Lieblingsspruch: RTFM!

> Es gibt in meinem Aufbau nur 2 entsprechende Pin's, SCL und SDA. Wenn
> Die Datenübertragung bei 3 von 4 Werten ohne Fehler stattfindet kann es
> nicht
> an den pull_up Werten  liegen ???
> Zudem messe ich am SCL und SDA Pin auch ohne pull_up konstante 3.3V.

Ich denke auch nicht, dass es an den Pull-Ups liegt.
Kann es sein, dass Du das erste Modul auf folgender Seite nutzt? Das 
sieht aus wie auf Deinem Foto:
https://www.mysensors.org/build/humidity_si7021

Das hat einen Spannungsregler von 5V auf 3,3V drauf. Der ESP32 läuft 
aber schon mit 3,3 Volt auf Deinem Board.
Das könnte unter Umständen eine Ursache für Dein Problem sein.

Hast Du mal den Soft-I2C versucht, wie von John Doe in Deinem anderen 
Thread Beitrag "Si7021 Fehler in der library" vorgeschlagen?

Der Fehler "OSError: [Errno 19] ENODEV" von Micropython kommt daher, 
dass Micropyton nach dem Senden der Start-Condition kein ACK innerhalb 
der Timeout-Zeit mehr zurückerhält.
Gast #6590926
Lesenswert?

Die Pull-Up Widerstände liefern den High Pegel. Sie bilden zusammen mit 
den kapazitäten der Leitung und der Chips einen Tiefpass. Wenn die 
Flanken nicht schnell genug ansteigen (siehe Anforderungen der 
beteiligten IC's in deren Datenblättern), funktioniert der Bus nicht.

Das kann man mit einem Oszilloskop sichtbar machen.
Gast #6590979
Lesenswert?

Vielen Leuten ist nicht klar, dass 1. die Treiber beim I2C-Bus open 
collector oder open drain sind und 2. die Treiber einen Strom von 
mindestens 3 mA produzieren sollen, bei höheren Busgeschwindigkeiten 
noch mehr (- 20 mA).

Im bereits oben erwähnten Dokument 
https://www.nxp.com/docs/en/application-note/AN10216.pdf ist auf S.17 
links oben ein Kasten "Pull-up Resistor calculation", da steht eine gute 
Formel drin, auch in der I2C-Bus Spezifikation von NXP 
https://www.nxp.com/docs/en/user-guide/UM10204.pdf ist auf S.47 in der 
Table 9 die Zeile "LOW-level output current" lesenswert: mindestens 3 
mA, bei höheren Busgeschwindigkeiten sogar 6 oder 20 mA.

Nach Simon Ohm resultiert also bei 5 Volt und 100 kHz für den Pullup 1,5 
kOhm und bei 3.3 Volt 1 kOhm, bei höheren Geschwindigkeiten sollten die 
Widerstände noch niedriger sein. Wer sich jetzt über zu hohen 
Stromverbrauch aufregt: der I2C-Bus wurde nicht für batteriebetriebene 
Geräte entwickelt, sondern für die Kommunikation von Baugruppen/-teilen 
innerhalb von Consumer-Geräten wie Fernseher, Waschmaschinen etc. Der 
Strom fliesst auch nur, wenn die Leitung low ist, in der Ruhephase ist 
sie aber high.

In der Praxis funktioniert der I2C-Bus manchmal auch mit höheren 
Widerständen, dann aber ausserhalb der Spezifikation und damit unsicher.
Gast #6591507
Lesenswert?

habe die einschlägigen websites bez. I2C Kommunikation insbesondere
hinsichtlich Pull_up Widerstände nochmals eingegender durchgelesen und
dabei viel gelernt!
Die Berechnunsformel ergibt 1kOhm Widerstände für meinem Fall.

Als Sensor habe ich den Si7021 GY-21, d.h. die 5V Version, mit voltage
regulator und level converter bestückt, sollte kein Problem machen.

Habe nun diese 1kOhm's eingebaut. Leider identische Fehlermeldung!
Frustrierend!
Beim ersten Test hatte ich vergessen die soft_pull_up's zu löschen
und bekam einen neuen Fehler in der Funktion
<get_device_info(self):>  aber immer mit OSError: [19] ENODEV.
Gast #6591655
Lesenswert?

Nochmal: Ich bin mir fast zu 100% sicher das auf dem Si-Breakout Pullups 
verbaut sind! Auf meinem ist ein 5V Regler und 10k Pullups verbaut.
Keine Ahnung was der TO da aufführt, meiner Meinung nach brauchts keinen
Soft-IIC und auch keine externen Pullups.
Wie schon einmal gesagt, ich hab den Code aus dem vom TO angeführten 
Link
ausprobiert und der funktioniert einwandfrei.
@TO
Stell nochmal deinen Code ein!
OP #6591714
Lesenswert?

habe alles probiert, ohne externe pull_up Widerstände, mit externen(1 
kOhm),
mit software pull_up's, mit externen und software pull_up's.
<machine.SoftI2C> produziert einen AttributeError.

Habe eben auch 5V auf den Si7021 gegeben, bis anhin immer 3.3V,

immer die selben Fehlermeldungen....Hier nochmals mein Script:

1 import si7021

2 import machine

3 i2c = machine.I2C(sda=machine.Pin(21),scl=machine.Pin(22))

4 temp_sensor = si7021.Si7021(i2c)

5 print('Serial:{value}'.format(value=temp_sensor.serial))

6 print('Identifier:{value}'.format(value=temp_sensor.identifier))

7 print('Temperature:{value}'.format(value=temp_sensor.temperature))

8 print('Relative Humidity: 
{value}'.format(value=temp_sensor.relative_humidity))
OP #6591857
Lesenswert?

ich habe den ESP32 per USB an meinem PC angeschlossen, und der liefert
5V - evtl. zu wenig Leistung ?. Habe den Si7021 mit 3.3V und 5V 
versorgt, kein Unterschied.

Hatte auch schon einen OLED Display ssd1306 (letztendliches Ausgabeziel) 
mit 3.3V angeschlossen, der funktionierte normal.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren