• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
BME680 wzór przeliczania gas (kOhms) na AIQ
#1
Witam może ktoś poda mi jak przeliczyć odczyt "gas" czujnika BME680 na jakość powietrza. Czytam specyfikację ale nic nie kapuje. Jakieś szkice które wyliczają jakość powietrza nie mogę rozkminić Smile. Może ktoś ma już rozpracowane. Chcę przeliczyć te dane z takiego gotowego szkicu.



#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println(F("BME680 test"));

  if (!bme.begin()) {
    Serial.println("Could not find a valid BME680 sensor, check wiring!");
    while (1);
  }

  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms
}

void loop() {
  if (! bme.performReading()) {
    Serial.println("Failed to perform reading Sad");
    return;
  }
  Serial.print("Temperatura = ");
  Serial.print(bme.temperature);
  Serial.println(" *C");

  Serial.print("Cisnienie = ");
  Serial.print(bme.pressure / 100.0);
  Serial.println(" hPa");

  Serial.print("Wilgotnosc = ");
  Serial.print(bme.humidity);
  Serial.println(" %");

  Serial.print("Wysokosc = ");
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  Serial.print("Gas = ");
  Serial.print(bme.gas_resistance / 1000.0);
  Serial.println(" KOhms");

  Serial.println();
  delay(5000);
}



Układ mam na D1 ESP8266 i PME 680 I2C
Program to jeden z nielicznych który dał się wgrać i działa.

Przykładowe odczyty:

Temperature = 24.94 *C
Pressure = 992.78 hPa
Humidity = 31.18 %
Gas = 128.55 KOhms
Approx. Altitude = 171.84 m

Temperature = 24.94 *C
Pressure = 992.76 hPa
Humidity = 31.19 %
Gas = 129.44 KOhms
Approx. Altitude = 172.01 m
 
Odpowiedź
#2
Ta biblioteka zwraca raczej gotowe wartości 0-500, no jak są jakieś /100 to może dlatego że wynik jest dokładniejszy, a nikogo nie interesuje Pa tylko hPa czy przez 1000 dla IAQ. Co innego, że każdy czujnik kłamie i wymaga kalibracji/wzorcowania okresowo, a już te od jakości gazu to w szczególności, jak tam zajrzałem do środka to jest kilkadziesiąt parametrów do kalibracji. Dlatego pewnie jednostką jest kOhms, interpretację zostawiając użytkownikom.
Możesz sobie nachuchać do pudełka (pooddychać na obiegu zamkniętym, byle nie pluć na czujnik, bo go uszkodzisz), potem iść gdzieś na łąkę wiosną z dala od ludzi i porównać wyniki - taka domowa kalibracja. Do tego dorób skalę z zieloną, żółtą i czerwoną buźką i gotowe. Jak chcesz to mieć w IAQ i miałoby to coś robić to i tak musisz zrobić wzorcowanie, każdy egzemplarz może pokazywać co innego, a po miesiącu/roku znowu się rozjadą.
 
Odpowiedź
#3
(10-03-2019, 14:27)kaczakat napisał(a): Ta biblioteka zwraca raczej gotowe wartości 0-500, no jak są jakieś /100 to może dlatego że wynik jest dokładniejszy, a nikogo nie interesuje Pa tylko hPa czy przez 1000 dla IAQ. Co innego, że każdy czujnik kłamie i wymaga kalibracji/wzorcowania okresowo, a już te od jakości gazu to w szczególności, jak tam zajrzałem do środka to jest kilkadziesiąt parametrów do kalibracji. Dlatego pewnie jednostką jest kOhms, interpretację zostawiając użytkownikom.
Możesz sobie nachuchać do pudełka (pooddychać na obiegu zamkniętym, byle nie pluć na czujnik, bo go uszkodzisz), potem iść gdzieś na łąkę wiosną z dala od ludzi i porównać wyniki - taka domowa kalibracja. Do tego dorób skalę z zieloną, żółtą i czerwoną buźką i gotowe. Jak chcesz to mieć w IAQ  i miałoby to coś robić to i tak musisz zrobić wzorcowanie, każdy egzemplarz może pokazywać co innego, a po miesiącu/roku znowu się rozjadą.

Undecided  No chyba aż tak źle z tymi czujnikami to nie jest. Z twojego opisu to wynika że to jakieś nieporozumienie a nie czujnik. Czyli co do kosza i coś z serii laserowych np. 5003 lub 7003? Wiadomo że amatorskie nie będą dokładne. Sama cena już sugeruje że to nie może być super ale czy mamy jakąś alternatywę?
 
Odpowiedź
#4
A specyfikacje czujnika czytał ?? sam producent podaje że pomyłka do 20% po kalibracji wzorcowania 5% co i tak jest sporo...
 
Odpowiedź
#5
Znalazłem coś takiego. Wgrałem do 8266. Oczywiście jestem za zielony aby dopisać coś np na Blynka bo odczyt po kablu to nie to. Temperaturę oszukiwał mój czujnik o 4 *C Wilgotność i ciśnienie nawet dobrze. Pomoże ktoś dopisać aby zdalnie można było odczytywać dane.

Znaleziony i działający szzkic
Kod:
/***************************************************************************
  This is a library for the BME680 gas, humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME680 Breakout
  ----> http://www.adafruit.com/products/XXXX

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
***************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10
#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

float hum_weighting = 0.25; // so hum effect is 25% of the total air quality score
float gas_weighting = 0.75; // so gas effect is 75% of the total air quality score

float hum_score, gas_score;
float gas_reference = 250000;
float hum_reference = 40;
int   getgasreference_count = 0;

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println(F("BME680 test"));

  
  Wire.begin();
  if (!bme.begin()) {
    Serial.println("Could not find a valid BME680 sensor, check wiring!");
    while (1);
  } else Serial.println("Found a sensor");

  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_2X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_2X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320 °C for 150 ms
  // Teraz uruchom czujnik na okres wypalania, a nastepnie uzyj kombinacji wilgotnosci wzglednej i odpornosci na gaz, aby oszacowac jakos powietrza w pomieszczeniu w procentach.
  GetGasReference();
}

void loop() {
  Serial.print("Temperature = ");

  Serial.print(bme.readTemperature()-4);
  Serial.println(" °C");

  Serial.print("  Cisnienie = ");

  Serial.print(bme.readPressure() / 100.0F);
  Serial.println(" hPa");

  Serial.print(" Wilgotnosc = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");

  Serial.print("        Gas = ");
  Serial.print(bme.readGas());
  Serial.println(" R\n");

  //Calculate humidity contribution to IAQ index
  float current_humidity = bme.readHumidity();
  if (current_humidity >= 38 && current_humidity <= 42)
    hum_score = 0.25*100; // Humidity +/-5% around optimum
  else
  { //sub-optimal
    if (current_humidity < 38)
      hum_score = 0.25/hum_reference*current_humidity*100;
    else
    {
      hum_score = ((-0.25/(100-hum_reference)*current_humidity)+0.416666)*100;
    }
  }
  
  //Calculate gas contribution to IAQ index
  float gas_lower_limit = 5000;   // Bad air quality limit
  float gas_upper_limit = 50000;  // Good air quality limit
if (gas_reference > gas_upper_limit) gas_reference = gas_upper_limit;
  if (gas_reference < gas_lower_limit) gas_reference = gas_lower_limit;
  gas_score = (0.75/(gas_upper_limit-gas_lower_limit)*gas_reference -(gas_lower_limit*(0.75/(gas_upper_limit-gas_lower_limit))))*100;
  
  // PoĹ‚Ä…cz wyniki dla koĹ„cowej wartoĹ›ci indeksu IAQ (0-100%, gdzie 100% to powietrze dobrej jakoĹ›ci)
  float air_quality_score = hum_score + gas_score;

  Serial.println("Air Quality = "+String(air_quality_score,1)+"% pochodzi z 25% odczytu wilgotnosci i 75% odczytu gazu - 100% to powietrze dobrej jakosci");
  Serial.println("Humidity element was : "+String(hum_score/100)+" of 0.25");
  Serial.println("     Gas element was : "+String(gas_score/100)+" of 0.75");
  if (bme.readGas() < 120000) Serial.println("***** Slaba jakosc powietrza *****");
  Serial.println();
  if ((getgasreference_count++)%10==0) GetGasReference();
  Serial.println(CalculateIAQ(air_quality_score));
  Serial.println("------------------------------------------------");
  delay(5000);
}

void GetGasReference(){
  Serial.println("Uzyskanie nowej wartosci odniesienia gazu");
  int readings = 10;
  for (int i = 1; i <= readings; i++){ // read gas for 10 x 0.150mS = 1.5secs
    gas_reference += bme.readGas();
  }
  gas_reference = gas_reference / readings;
}
// Serial.println (score);
String CalculateIAQ(float score){
  String IAQ_text = "Jakosc powietrza jest ";
  score = (100-score)*5;
  if      (score >= 301)                  IAQ_text += "NIEBEZPIECZNA";
  else if (score >= 201 && score <= 300 ) IAQ_text += "BARDZO NIEZDROWA";
  else if (score >= 176 && score <= 200 ) IAQ_text += "NIEZDROWA";
  else if (score >= 151 && score <= 175 ) IAQ_text += "NIEZDROWA DLA WRAZLIWYCH GRUP";
  else if (score >=  51 && score <= 150 ) IAQ_text += "UMIARKOWANA";
  else if (score >=  00 && score <=  50 ) IAQ_text += "DOBRA";
  Serial.print (score);
  Serial.println (" - IAQ");
  return IAQ_text;
}
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości