BME680 – Teil 2 – nun aber richtig

Ich hatte bereits vor knapp zwei Jahren eine Anleitung erstellt um den BME680 an einen NodeMCU (ESP8266) anzuschalten und die Daten mittels LoRaWAN an TTN zu übermitteln. Da ich momentan dabei bin meine alten Nodes und Sketches zu überarbeiten, ist mir auch dieser unter die Finger gekommen. Nun war also die Zeit gekommen das Thema wieder aufzugreifen und auf den neuesten Stand zu bringen.

Rückblick

Mit dem damaligen Sketch habe ich kein EV_TXCOMPLETE Event erhalten und somit musst ich nach jedem Senden wieder den RFM95 neu initialisieren. Damals konnte ich mir das Problem nicht erklären, aber heute bin ich etwas schlauer. In meinem Loop fehlte der Befehl os_runloop_once(); , aber was macht der?

Im Normalfall arbeitet LMIC nicht mit Interrupts und wir müssen regelmäßig nach Events fragen. Dieses erfolgt über den Befehl os_runloop_once(); . Wenn dieser also nun fehlt, dann erfahren wir nicht ob wir Daten gesendet haben, bzw. ob etwas empfangen wurde. Ihr sendet Daten, welche auch erfolgreich gesendet werden, aber der LMIC Stack denkt immer noch das der Job aktiv ist. Eigentlich also nichts kompliziertes, darf halt nur nicht fehlen.

void loop() {
  os_runloop_once();
}

Damit war dann mein eigentlicher Bug behoben und auch OTAA funktionierte nun. Zusätzlich hat sich aber auch was an der BSEC Library getan, weshalb auch die damalige Anleitung nicht mehr aktuell ist und überarbeitet werden muss. Damit geht es nun weiter. Insgesamt ist es einfacher geworden.

Vorbereitungen Arduino IDE

NodeMCU in die IDE einbinden

Wenn ihr bereits den NodeMCU in die Arduino IDE eingebunden habt, könnt ihr diesen Abschnitt überspringen.

Ihr Öffnet die Arduino IDE und geht auf Datei >> Voreinstelungen >> Zusätzich Boardverwalter-URLs und tragt dort folgenden Link ein.

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Anschließend wechselt ihr zu Werkzeuge >> Board  >> Boardverwalter und sucht nach ESP8266 und installiert dort ESP8266 Community.

Benötigte Libraries einbinden

Für den LoRaWAN-Part benötigen wir die MCCI Catena LMIC-Library. Ladet euch das Repository als ZIP herunter (clone or download) und bindet dieses über Sketch >> Bibliothek einbinden >> .ZIP-Bibliothek hinzufügen … ein.

Die BSEC-Library kann nun direkt über Sketch >> Bibliothek einbinden >> Bibliotheken verwalten gefunden werden. Sucht nach BSEC und installiert die Version 1.2.1474. Auch wenn es erst mal nicht so aussieht, sie ist aktueller als die 1.4.703 . Infos findet ich dazu auch auf GitHub.

LMIC konfigurieren

Per Default ist die LMIC für den US-Sektor konfiguriert, dieses müssen wir also anpassen. Auf einem Windows-System findet ihr unter Documents\Arduino\libraries\MCCI_LoRaWAN_LMIC_library\project_config die lmic_project_config.h welche ihr anpassen müsst. So sollte es bei euch aussehen. Wichtig ist der Punkt #define CFG_eu868 1

// project-specific definitions
#define CFG_eu868 1
//#define CFG_us915 1
//#define CFG_au921 1
//#define CFG_as923 1
// #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP	/* for as923-JP */
//#define CFG_kr920 1
//#define CFG_in866 1
#define CFG_sx1276_radio 1
//#define LMIC_USE_INTERRUPTS

BSEC/ESP8266 spezifische Anpassungen

Das war bisher alles einfach, jetzt wird es etwas komplizierter. Die BSEC beinhaltet vorgefertigte Librarys, welche beim Kompilieren mit eingebunden werden müssen, dazu müssen ein Paar Anpssungen vorgenommen werden. Normalerweise solltet ihr die Software eures Boards unter <USER-HOME>\AppData\Local\Arduino15\packages\esp8266\ finden.

platform.txt anpassen

Die Datei findet wir unter hardware\esp8266\2.5.2\platform.txt und diese muss um den Eintrag {compiler.libraries.ldflags} ergänzt werden:

Alt Zeile 105:

## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {build.exception_flags} -Wl,-Map "-Wl,{build.path}/{build.project_name}.map" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{archive_file_path}" {compiler.c.elf.libs} -Wl,--end-group  "-L{build.path}"

Neu Zeile 105:

## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {build.exception_flags} -Wl,-Map "-Wl,{build.path}/{build.project_name}.map" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{archive_file_path}" {compiler.c.elf.libs} {compiler.libraries.ldflags} -Wl,--end-group  "-L{build.path}"

Ebenfalls müsst ihr den folgenden Block noch um eine Zeile erweitern (danke Reinhard):

# These can be overridden in platform.local.txt
compiler.c.extra_flags=
compiler.c.elf.extra_flags=
compiler.cpp.extra_flags=
compiler.S.extra_flags=
compiler.ar.extra_flags=
compiler.elf2hex.extra_flags=

Hinzu kommt:

compiler.libraries.ldflags=

eagle.app.v6.common.ld.h anpassen

Diese Datei finden wir unter hardware\esp8266\2.5.2\tools\sdk\ld und muss um den Eintrag *libalgobsec.a:(.literal.* .text.*) erweitert werden:

Neu nach Zeile 177 *libwps.a:(.literal.* .text.*):

*libwpa.a:(.literal.* .text.*)
*libwpa2.a:(.literal.* .text.*)
*libwps.a:(.literal.* .text.*)
*libalgobsec.a:(.literal.* .text.*)
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom0.text.* .irom.text .irom.text.*)

Aufbau der Schaltung für BME680 und RFM95

Ich verwende ein BME680 Breakout von Watterott. Das Bard von Watterott verwendet die I²C Adresse 0x77. Daher spreche ich in dem späteren Sketch diese auch an über iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire); Sollte euer Board die 0x76 nutzen müsst ihr dieses auf iaqSensor.begin(BME680_I2C_ADDR_PRIMARY, Wire); ändern. Die Anschaltung erfolgte nach folgendem Schema:

bme680 schema

Für Besitzer des Adafruit Moduls:

Entgegen des Schaubildes, muss D1 mit G0 verbunden werden und D2 mit G1.

NodeMCU an RFM95
  D1 (GPIO5)  - DIO0 (SX1275/RFM95)
  D2 (GPIO4)  - DIO1
  D5 (GPIO14) - SCK 
  D6 (GPIO12) - MISO
  D7 (GPIO13) - MOSI
  DO (GPIO16) - NSS
  GND         - GND
  3.3v        - VCC
 
BME680 an NodeMCU
  D3 (GPIO0)  - SDA (BME680)
  D4 (GPIO2)  - SCL
  GND         - GND
  3.3v        - VCC

TTN Payload Decoder

Mit folgendem Decoder bekommt ihr die Werte für Temperatur, Luftfeuchtigkeit, Luftdruck, IAQ und CO2 dekodiert.

function Decoder(b, port) {

  var temp = (b[0] | b[1]<<8 | (b[1] & 0x80 ? 0xFF<<16 : 0)) / 100;
  var hum = (b[2] | b[3]<<8 | (b[3] & 0x80 ? 0xFF<<16 : 0)) / 100;
  var iaq = (b[4] | b[5]<<8 | (b[5] & 0x80 ? 0xFF<<16 : 0)) / 100;
  var press = (b[6] | b[7]<<8 | (b[7] & 0x80 ? 0xFF<<16 : 0))/10+7;
  var co2 = (b[8] | b[9]<<8 | (b[9] & 0x80 ? 0xFF<<16 : 0));


  if (iaq !== 0) {
    return {
    env: {
      temp: temp,
      hum: hum,
      iaq: iaq,
      press: press,
      co2: co2
    },
  };
  }
}

Die eigentliche Software

Der Sketch liegt als ABP und OTAA Variante auf GitHub und darf von euch frei verwendet werden.

Nun wünsche ich euch viel Spaß beim Tüfteln!

10 Gedanken zu „BME680 – Teil 2 – nun aber richtig“

  1. Hallo Bjoern,
    ein wichtiger Punkt fehlt, auf den ich jetzt reingefallen bin und der mich einige Stunden gekostet hat:
    (das nicht wegen deinem Blog, ich sehe nur gerade, dass das hier fehlt)
    die Datei platform.txt muss um eine weitere Zeile ergänzt werden und zwar

    nach dem Textblock
    # These can be overridden in platform.local.txt
    compiler.c.extra_flags=
    compiler.c.elf.extra_flags=
    compiler.cpp.extra_flags=
    compiler.S.extra_flags=
    compiler.ar.extra_flags=
    compiler.elf2hex.extra_flags=

    diese Zeile ergänzen:
    compiler.libraries.ldflags=

    Ohne diese Änderung funktioniert zwar die bsec Library, aber alle anderen Sketche produzieren Compiler Fehler.
    Auf der github Seite der Library kann man das leicht übersehen.

    Gruß
    Reinhard

    Antworten
  2. Hallo Bjoern,

    ein super Beitrag zum BME680!
    Geht auch eine Umsetzung auf dem WeMos D1 Mini? Ist doch auch ein ESP8266.
    Wie müsste dann die Vorgehensweise aussehen? Kannst du dazu auch eine Anleitung erstellen, da ich als „ESP8266-Frischling“ nicht so fit bin 😉

    Grüße Jörg

    Antworten
  3. Hallo Björn,

    der Nachbau hat funktioniert- danke für dein geteiltes Projekt!
    Ein Problem habe ich mit dem TTN-Uplink:

    TTN Payload Format = Custom
    im Uplink – Fields werden Daten angezeigt

    TTN Payload Format = Cayenne LPP
    im Uplink – Fields werden KEINE Daten angezeigt

    Hast du dazu einen Hinweis.

    Gruß
    Kurt

    Antworten
  4. Hallo Björn,

    funktioniert der Payload-Dekoder auch für negative Temperaturen? Es sind gerade Minusgrade auf meinem Balkon und der im TTN angezeigte Wert „temp“: 167770.04 passt nicht so richtig.

    var temp = (b[0] | b[1]<<8 | (b[1] & 0x80 ? 0xFF<<16 : 0)) / 100;

    Viele Grüße
    Roland

    Antworten

Schreibe einen Kommentar