Skip to content

Instantly share code, notes, and snippets.

@xxlukas42
Last active February 6, 2022 17:31
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save xxlukas42/a878f5c44f1ec108a460e9b9500b79f5 to your computer and use it in GitHub Desktop.
Save xxlukas42/a878f5c44f1ec108a460e9b9500b79f5 to your computer and use it in GitHub Desktop.
BME680 (GY-MCU680V1) Air quality measurement
//GY_MCU680 air quality sensor
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 0 // GPIO0
Adafruit_SSD1306 display(OLED_RESET);
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
const char* server = "api.thingspeak.com";
const char* api_key = "YOUR_API_KEY";
// Optional - you can define air pressure correction for your altitude
#define ALT_CORRECTION 3144
SoftwareSerial mySerial(D6, D5);
uint16_t temp1=0;
int16_t temp2=0;
unsigned char Re_buf[30],counter=0;
unsigned char sign=0;
int led = 13;
WiFiClient client;
unsigned long prev = millis();
// You need to use modified Adafruit library with support of small displays
// see here: https://github.com/mcauser/Adafruit_SSD1306/tree/esp8266-64x48
#if (SSD1306_LCDHEIGHT != 48)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void setup()
{
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
delay(1000);
//---------------------------------
Serial.println("Connecting to wifi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED){
// Blink LED when connecting to wifi
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
delay(150);
digitalWrite(LED_BUILTIN, HIGH);
delay(150);
}
Serial.println("WiFi connected");
//---------------------------------
pinMode(D2, INPUT);
pinMode(D1, OUTPUT);
mySerial.begin(9600);
mySerial.listen();
delay(5000);
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);
Serial.println("Setup complete");
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;
//Serial.println("Checking serial...");
while (mySerial.available()) {
//Serial.println("mySerial available");
Re_buf[counter]=(unsigned char)mySerial.read();
if(counter==0&&Re_buf[0]!=0x5A) {
Serial.println("Nothing received");
}
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];
float altPressure=(float(Pressure)+ALT_CORRECTION)/100;
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("|");
Serial.print(altPressure);
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);
// Display result on OLED display
dislayResult(IAQ);
if(millis() - prev > 60000){
postData(Temperature,Humidity,altPressure,IAQ,Gas,IAQ_accuracy);
prev = millis();
}
}
delay(1000);
}
}
}
void postData(float temperature, float humidity, float altPressure, int iaq, int gas, int iaq_accuracy){
digitalWrite(LED_BUILTIN, LOW);
// Send data to ThingSpeak
if (client.connect(server,80)) {
Serial.println("Connect to ThingSpeak - OK");
String dataToThingSpeak = "";
dataToThingSpeak+="GET /update?api_key=";
dataToThingSpeak+=api_key;
dataToThingSpeak+="&field1=";
dataToThingSpeak+=String(temperature);
dataToThingSpeak+="&field2=";
dataToThingSpeak+=String(humidity);
dataToThingSpeak+="&field3=";
dataToThingSpeak+=String(altPressure);
dataToThingSpeak+="&field4=";
dataToThingSpeak+=String(iaq);
dataToThingSpeak+="&field5=";
dataToThingSpeak+=String(gas);
dataToThingSpeak+="&field6=";
dataToThingSpeak+=String(iaq_accuracy);
dataToThingSpeak+=" HTTP/1.1\r\nHost: a.c.d\r\nConnection: close\r\n\r\n";
dataToThingSpeak+="";
client.print(dataToThingSpeak);
int timeout = millis() + 5000;
while (client.available() == 0) {
if (timeout - millis() < 0) {
Serial.println("Error: Client Timeout!");
client.stop();
return;
}
}
}
while(client.available()){
String line = client.readStringUntil('\r');
//Serial.print(line);
}
digitalWrite(LED_BUILTIN, HIGH);
}
void dislayResult(int iaq){
String disp;
if(iaq <= 50) disp="GOOD";
else if(iaq > 50 && iaq <= 100) disp = "AVER";
else if(iaq > 100 && iaq <= 150) disp = "L.BAD";
else if(iaq > 150 && iaq <= 200) disp = "BAD";
else if(iaq > 200 && iaq <= 300) disp = "WORSE";
else disp = "V.BAD";
display.setTextColor(WHITE);
display.drawLine(0, 24, 64, 24, WHITE);
display.setCursor(3+(5-disp.length())*8,5);
display.setTextSize(2);
display.fillRect(0, 0, 64, 23, BLACK);
display.println(disp);
display.setCursor(8,30);
display.setTextSize(1);
display.fillRect(0, 25, 64, 20, BLACK);
display.print("IAQ: ");
display.print(iaq);
display.display();
}
@JoseGoffinet
Copy link

Sorry but the add of ALT_CORRECTION on the pressure must have an effect on the calculation of altitude. It's not your cas?
Do you have an idea to adjust that matter ???

@xxlukas42
Copy link
Author

Hi Jose, this is an opposite case-you know the altitude but you need to recalculate the pressure to 0 m - sea level ALT (so you add that difference to correct pressure you get). I live near city meteo-station which provides very accurate pressure data so I callibrated my ALT_CORRECTION accordingly.

@oscarpeters
Copy link

I'm not getting any data from my BME680, the only data that i'm getting is the "checking serial...." non stop.
is there a chance that my GY-MCU680 is broken?

kind regards :)

@christoph292
Copy link

At first: Thank you for code!

I have one question, do you have any datasheets from the "sensorboard"?
Where do you get from the info how to setup the sensor through serial?
e.g.
` 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);`

@oscarpeters
Copy link

The information provided came from the serial monitor. I could not made it work with any example sketch, so I think I got a bad sample from china.
I also tried it with an I2C-bus scanner and there was nothing going on on the bus :'(

@lengbuyu
Copy link

lengbuyu commented Jun 1, 2020

Hello, About setup() this, what this mean
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);

where can find this serial command ?
Thank you so much :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment