Funksensor mit Bosch sensortec BME680 / Luftgüte

Begonnen von juergs, 28 Oktober 2017, 18:05:43

Vorheriges Thema - Nächstes Thema

juergs


hdgucken

#406
@Nighthawk

Zitat von: Nighthawk am 22 Dezember 2018, 20:23:48
Leider hat es mit dem "ignore_battery" nicht funktioniert, es wird kein Device angelegt.

Die v1.4.5.1 habe ich leider auch nicht gefunden.

Du musst die Dateien aus meinem Git Repository: https://github.com/amigatommy/BME680-UniversalSensor verwenden, das ist der Stand mit V1.5.4.1.
Ich habe einige Änderungen in den originalen Dateien gemacht !
Zum Beispiel die "bsec_integration.c" -> um die Erkennung der I2C Adresse des BME680 zu automatisieren.
Auch die BH1750 und die Adafruit Libs sind leicht modifiziert, was ebenfalls die automatische Erkennung der I2C-Adresse
und bei der Adafruit Lib zusätzlich die Unterstützung für SH1106 Displays betrifft.

Habe die neue BSEC Soft V1.4.7.1 schon eingebunden, inkl. einiger Änderungen von Jürgen ;).
Compilieren geht schon, muß nur noch auf der Hardware getestet werden, will ich heute noch machen und dann auf Git Hub hochladen, sage hier bescheid, wenn es soweit ist ;o) 
Es gibt neue Readings in dieser Version, sieht man dann auf der seriellen  :D
Das sind: static_iaq , co2_equivalent und breath_voc_equivalent.

Hänge hier noch eine Doku zur Integration der BSEC Soft und der geänderten Dateien an, Stand V1.5.4.1:

P.S.: In der Doku hat sich ein kleiner Fehler eingeschlichen: Der BH1750 Lib Ordner muss "AS_BH1750" und nicht "AS_BH1750-master" !!!

Nighthawk

Hallo Zusammen,

dank Peter habe ich es mit der bsec 1.4.5 zum Laufen bekommen, vielen Dank für die Unterstützung!

juergs

#408
Hallo Thomas,
bei der Luftfeuchte scheinen die Werte noch nicht ganz zu stimmen (im Vergleich zu einem echten LaCrosseSensor).
Sowohl bei der nanoLGW-Platine, also auch in der LGW Firmware?
Die Werte sind viel zu niedrig.

LaCrosse_25 ist ein richtiger LaCrosse-Sensor: LaCrosse_25 T: 20.7 H: 41
bme680_cc  CustomSensor mit geändertem fhem-Code an LGW V1.30: bme680_cc  21.5 °C, 40 %, 1017 hPa

LaCrosse_76 ist der BME 680 der LaCrosseGateway V1.32 LaCrosse_76 T: 29 H: 23

LaCrosse_10 UniversalSensor_1 (nanoLGW)   LaCrosse_10 T: 25.1 H: 27
LaCrosse_0C UniversalSensor_2 (nanoLGW)   LaCrosse_0C T: 28.7 H: 24

Grüße,
Jürgen

hdgucken

#409
Hallo Jürgen,

bei mir sind die Feuchtewerte auch nicht 100% stimmig, habe mir aber darüber noch keine weiteren Gedanken gemacht  :o
So in etwa passt es aber:
Universalsensor mit STM32 - 46% (mit BSEC V1.4.7.1  8))
LaCrosseGateway Nr.1 - 40%
LaCrosseGateway Nr.2 - 41%

Gruß Thomas

P.S. Die neue V3.1 des Universalsensors ist online: https://github.com/amigatommy/BME680-UniversalSensor  ;)

juergs

#410
Hallo Thomas,
ich habe hier  x Temperatur + Luftfeuchte-Sensoren im Einsatz.
In einem beheizten Raum scheinen mir die 40% sehr plausibel,
aber 25% scheint mir eher sehr daneben zu liegen ...

Ich vergleiche mal den CC-Sensor mit dem Universalsensor-Code um evtl. Unterschiede zu finden.

ZitatDie neue V3.1 des Universalsensors ist online
Schön, dann kann ich die schon mal in Augenschein nehmen.

Der neuere ULP-Modus scheint ja auch für Batterie-betriebene Geräte gedacht zu sein.
Durch den ESP8266 kann man das aber nicht unbedingt nachverfolgen.
Der CO2 Wert verlangt ja eigentlich auch nach einer Anzeige (Nextion/ePaper).

Ich habe mir neuere Sensor-Breakouts bestellt, die einen STM32 auf dem Board beinhalten.
Da bin ich mal gespannt.  :D

Grüße,
Jürgen

juergs

#411
Zum Luftfeuchte-Problem:
https://github.com/BoschSensortec/BME680_driver/issues/51

/*!
* @brief This internal API is used to calculate the humidity value.
*/
static uint32_t calc_humidity(uint16_t hum_adc, const struct bme680_dev *dev)
{
int32_t var1;
int32_t var2;
int32_t var3;
int32_t var4;
int32_t var5;
int32_t var6;
int32_t temp_scaled;
int32_t calc_hum;

temp_scaled = (((int32_t) dev->calib.t_fine * 5) + 128) >> 8;
var1 = (int32_t) (hum_adc - ((int32_t) ((int32_t) dev->calib.par_h1 * 16)))
- (((temp_scaled * (int32_t) dev->calib.par_h3) / ((int32_t) 100)) >> 1);
var2 = ((int32_t) dev->calib.par_h2
* (((temp_scaled * (int32_t) dev->calib.par_h4) / ((int32_t) 100))
+ (((temp_scaled * ((temp_scaled * (int32_t) dev->calib.par_h5) / ((int32_t) 100))) >> 6)
/ ((int32_t) 100)) + (int32_t) (1 << 14))) >> 10;
var3 = var1 * var2;
var4 = (int32_t) dev->calib.par_h6 << 7;
var4 = ((var4) + ((temp_scaled * (int32_t) dev->calib.par_h7) / ((int32_t) 100))) >> 4;
var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
var6 = (var4 * var5) >> 1;
calc_hum = (((var3 + var6) >> 10) * ((int32_t) 1000)) >> 12;

if (calc_hum > 100000) /* Cap at 100%rH */
calc_hum = 100000;
else if (calc_hum < 0)
calc_hum = 0;

return (uint32_t) calc_hum;
}


OK, eine Herausforderung zum Reengineering ... :( :o


Vermute, dass die Erfassung mit dem BME280 vergleichbar ist.
Also erst noch etwas forschen...

PS: Die BME680 mit STM32F051k8-Sensoren sind heute gekommen ... :D
ZitatThis module has two ways to read data, namely serial port (TTL level) or chip itself IIC communication mode.
The product has high precision and high stability. It is possible to directly output utility data and omit the algorithm.
The baud rate of the serial port is 9600bps and 115200bps. There are two modes of continuous output and interrogation output, which can adapt to different working environments.
Connect to all microcontrollers and computers
When soldering the PS solder joint, the module is in the chip's own IIC mode, at which point the MCU does not participate in the operation and does not consume current. Can be used as a simple BME680 module.

hdgucken

Zitat von: juergs
... In einem beheizten Raum scheinen mir die 40% sehr plausibel,
aber 25% scheint mir eher sehr daneben zu liegen ...
Da gebe ich dir recht ...

Zitat
... Ich vergleiche mal den CC-Sensor mit dem Universalsensor-Code um evtl. Unterschiede zu finden.
Humidity wird nicht weiter umgerechnet, kommt direkt aus der Bosch lib als "float humidity".

Die Berechnung des humidity Wertes in der Bosch Lib ist schon spannend ...  ;D

Ein kleines Display wäre auch schön, mal schauen  8)

Gruß
Thomas

hdgucken

Hallo Jürgen,

coole Teile, ist aber eine andere ARM Architektur als der Maple-mini oder Bluepill (STM32F051),
muss man schauen, ob es mit der Arduino IDE machbar ist.

Was mir gerade noch einfällt, Du hattest mal geschrieben, das Dein OLED Display mit der Zeit sehr schlecht geworden ist.
Hab mal ein Bild von meinem angehängt, läuft jetzt seit November 2017 (mit Dimmung, wenn dunkel). Kein einbrennen zu erkennen  :)
Hab heute noch eine feinere Abstufung beim Display dimmen in der V3.1 eingefügt.

Gruß Thomas

juergs

#414
Zitatmuss man schauen, ob es mit der Arduino IDE machbar ist
Ja sehe ich auch so, falls es nicht direkt gehen sollte kann man den ByPass per Lötbrücke aktivieren.

Für das Modul konnte ich bisher keine Beschreibung ausmachen.
Es kann laut Angaben 9600 und 115K Baud.

Im Moment bekomme ich nur über 9600 Baud zyklisch Ausgaben des Moduls zu sehen.
Das Datenformat ist aber unklar und nicht Ascii. Habe dazu der Vertreiber kontaktiert, vieleicht
ist er in der Lage die Doku dazu nachzuliefern ...  :o :( >:(

Na ja, dann doch ByPass und ESP  ;D ... oder umprogrammieren.
Vielleicht trenne ich auch nach der ersten Stiftleiste die Platine ab, dann ist
der BME ggf. auch noch 1 Euro billiger als bei Re***lt ...  ;D

Zum OLED-Display, macht es Sinn es Nachts herunterzudimmen (lichtempf. Widerstand),
hatte es  auf 100% Helligkeit eingstellt und es so gelassen. Habe noch einige Exemplare über,
so das der Nachschub gesichert ist.  ;-)

Vieleicht reicht es mir noch, mein ePaper-Display zu aktivieren bzw. erst mal einzuarbeiten ...
Dann wäre das Einbrenn-Problem auch vom Tisch  ;)

By the way: in der LGW gibt es ja die Display-Optionen um Messwerte in einem Loop Seitenweise anzuzeigen.
Dort funktioniert der Display-Refresh ohne Flackern. Evt. wäre das auch noch eine Idee hier mit umzusetzen.   ;)


Jürgen

/edit: Angehängt der ES8266-Sketch QY_MCUBME680_Interface_V2.ino für die Plotterausgabe der Arduino-IDE.

juergs

#415
Ein erster Erfolg, es sei denn man kann chinesisch  ???
https://github.com/op0xA5/GYMCU680/blob/master/main.go
.. bietet wenigstens einige Hinweise auf das Protokoll-Format des GY-MCU680V1.

Oder in Thailand:
https://www.mcucity.com/product/2315/4-in-1-bme680-i2c-stm32-uart-temperature-humidity-pressure-and-gas-sensor

//GY_MCU680 air quality sensor ARDUINO

#include SoftwareSerial mySerial(4, 5);
uint16_t temp1=0;
int16_t temp2=0;

unsigned char Re_buf[30],counter=0;
unsigned char sign=0;
int led = 13;


void setup()
{
  Serial.begin(9600); 
   mySerial.begin(9600);
   mySerial.listen(); 
  delay(4000);   

  mySerial.write(0XA5);
  mySerial.write(0X55);   
  mySerial.write(0X3F);   
  mySerial.write(0X39);
  delay(100);

  mySerial.write(0XA5);
  mySerial.write(0X56);   
  mySerial.write(0X02);   
  mySerial.write(0XFD);
  delay(100); 
}

void loop(){
  float Temperature ,Humidity;
  unsigned char i=0,sum=0;
  uint32_t Gas;
  uint32_t Pressure;
  uint16_t IAQ;
  int16_t  Altitude;
  uint8_t IAQ_accuracy;
  while (mySerial.available()) {   
    Re_buf[counter]=(unsigned char)mySerial.read();
   
    if(counter==0&&Re_buf[0]!=0x5A) return;         
    if(counter==1&&Re_buf[1]!=0x5A)
  {
    counter=0;
     return;
   };           
    counter++;       
    if(counter==20)               
    {   
       counter=0;                 
       sign=1;
    }     
  }
  if(sign)
  { 
     sign=0;
     
     if(Re_buf[0]==0x5A&&Re_buf[1]==0x5A )       
     {   
       
            for(i=0;i<19;i++)
               sum+=Re_buf[i];
             if(sum==Re_buf[i] )
             {
                     temp2=(Re_buf[4]<<8|Re_buf[5]);   
                     Temperature=(float)temp2/100;
                     temp1=(Re_buf[6]<<8|Re_buf[7]);
                     Humidity=(float)temp1/100;
                     Pressure=((uint32_t)Re_buf[8]<<16)|((uint16_t)Re_buf[9]<<8)|Re_buf[10];
                     IAQ_accuracy= (Re_buf[11]&0xf0)>>4;
                     IAQ=((Re_buf[11]&0x0F)<<8)|Re_buf[12];
                     Gas=((uint32_t)Re_buf[13]<<24)|((uint32_t)Re_buf[14]<<16)|((uint16_t)Re_buf[15]<<8)|Re_buf[16];
                     Altitude=(Re_buf[17]<<8)|Re_buf[18];
                     Serial.print("Temperature:");
                     Serial.print(Temperature);
                     Serial.print(" ,Humidity:");
                     Serial.print(Humidity);
                     Serial.print(" ,Pressure:");
                     Serial.print(Pressure);     
                     Serial.print("  ,IAQ:");
                     Serial.print(IAQ);
                     Serial.print(" ,Gas:");
                     Serial.print(Gas );
                     Serial.print("  ,Altitude:");
                     Serial.print(Altitude);                       
                     Serial.print("  ,IAQ_accuracy:");
                     Serial.println(IAQ_accuracy); 
            }           
           delay(1000);           
   }
  }
}*


Der Output passt auch noch nicht so ganz (lässt sich mit dem GO-Programm evtl. korrigieren):

Temperature:22.50 ,Humidity:39.96 ,Pressure:101894  ,IAQ:25 ,Gas:38277  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.50 ,Humidity:39.95 ,Pressure:101894  ,IAQ:25 ,Gas:38992  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.51 ,Humidity:39.93 ,Pressure:101894  ,IAQ:25 ,Gas:39734  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.47 ,Humidity:39.99 ,Pressure:101896  ,IAQ:25 ,Gas:40426  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.46 ,Humidity:39.99 ,Pressure:101896  ,IAQ:25 ,Gas:41062  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.44 ,Humidity:39.99 ,Pressure:101896  ,IAQ:25 ,Gas:41761  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.45 ,Humidity:39.97 ,Pressure:101898  ,IAQ:25 ,Gas:42140  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.43 ,Humidity:39.98 ,Pressure:101898  ,IAQ:25 ,Gas:42875  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.42 ,Humidity:39.95 ,Pressure:101898  ,IAQ:25 ,Gas:43546  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.43 ,Humidity:39.92 ,Pressure:101898  ,IAQ:25 ,Gas:44005  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.43 ,Humidity:39.93 ,Pressure:101898  ,IAQ:25 ,Gas:44473  ,Altitude:-47  ,IAQ_accuracy:0
Temperature:22.44 ,Humidity:39.92 ,Pressure:101896  ,IAQ:25 ,Gas:45244  ,Altitude:-47  ,IAQ_accuracy:0


Es gibt wohl auch eine Windows-Anwendung dazu. Aber nur für den chinesisch Sprachbegabten.  ;):-\

Was wohl der Parametrier-Teil mit "A5 56 01 FC" bewirkt?

juergs

#416
Temperature:21.50 ,Humidity:42.33 ,Pressure:1017  ,IAQ:244 ,Gas:84681  ,Altitude:-36  ,IAQ_accuracy:3

Sieht doch schon ganz verwertbar aus.   :D
Nachts ist der IAQ-Wert in der Tat so hoch!


Alternative für die IAQ-Berechnung aus dem Resistance-Wert:
https://github.com/pimoroni/bme680-python/blob/master/examples/indoor-air-quality.py
https://learn.pimoroni.com/tutorial/sandyj/getting-started-with-bme680-breakout

juergs

#417
Der Lieferant hat schnell reagiert, leider in chinesisch ... Translator sei Dank!
Die Einstell-Möglichkeiten des GY-MCUBME680-Moduls mit serieller Ausgabe, übersetzt:
Byte3 des Telegramms ist noch etwas unklar "formuliert". 0x0F  sendet das volle Datenpaket mit 20 Bytes.

float Temperature ,Humidity;
  uint32_t Gas;
  uint32_t Pressure;
  uint16_t IAQ;
  int16_t Altitude=0;
  uint8_t IAQ_accuracy;
  uint16_t temp1=0;
  int16_t temp2=0;

locutus

Zitat von: hdgucken am 29 Dezember 2018, 00:37:11
P.S. Die neue V3.1 des Universalsensors ist online: https://github.com/amigatommy/BME680-UniversalSensor  ;)
Würdest du bitte die binäre Firmware-Datei für STM32F103Cx zur Verfügung stellen?
Vielen Dank im Voraus!

juergs

#419
Hallo Locutus,

ist noch ein bisschen Nacharbeit erforderlich:


D:\Work_FHEM\Projects\_BME680\BME680-UniversalSensor-3.1-BSEC V1.4.7.1\BME680_UniversalSensor\BME680_UniversalSensor.ino: In function 'void setup()':

BME680_UniversalSensor:702: error: 'class TwoWire' has no member named 'setClock'

     Wire.setClock(400000);



Spezielle Konfiguration(en)?