I'm having an issue with my BME680 environmental sensor in a multi-sensor setup. The odd thing is that I previously had a BME280 in the same setup that worked perfectly fine.
What works:
BME680 functions correctly when connected alone to an Arduino Uno R3
My other I2C sensors (UV light sensor at 0x0D and TSL2591 lux sensor at 0x23) are detected and work fine
What doesn't work:
When I connect the BME680 alongside my other two sensors sharing the same SDA/SCL pins, the BME680 is not detected at all
Running an I2C scanner only shows addresses 0x0D and 0x23, but no BME680 (which should appear at 0x76 or 0x77)
What I've tried so far:
Verified all wiring connections multiple times
Tried connecting the BME680 to a separate power source to rule out power issues
Confirmed the BME680 works perfectly when it's the only sensor connected
Previously had a BME280 in the exact same setup that worked fine with all sensors
Tested with two different Arduino boards (one Uno R3 and one standard Uno)
The fact that the BME280 worked fine in the same setup but the BME680 doesn't suggests there's something specific about the BME680's requirements that's causing issues when sharing the I2C bus.
Hardware:
Arduino Uno / Uno R3
BME680 environmental sensor
UV light sensor (I2C address 0x0D)
TSL2591 lux sensor (I2C address 0x23)
Questions:
Does the BME680 need special handling when sharing an I2C bus that the BME280 doesn't require?
Could this be related to the BME680's higher power requirements for the gas sensor element?
Are there timing/clock speed considerations for the BME680 that might be causing issues?
Any suggestions for other troubleshooting steps I should try?
Sorry, I am quite new to this.
Any help would be greatly appreciated! Thanks in advance.
You tried giving it a separate power supply and it did not help, so I would say no
I would expect it will run at the same speeds that BME280 will run at. What speed are you using?
Have you tried the BME680 with just one of the other sensors? Or with the BME280?
Are you using sensor modules containing these sensors, or the bare sensor chips? If the former, post links to the specs of the modules so the forum can check the other circuits on the modules, like the pull-up resistors on the I2C lines.
I am using all the default settings from adafruit's example code as I am not experienced. I haven't tried using it with only one other sensor as my work area is complicated and I could easily make a mistake. I am using the sensor module.
Just to let you know, if it seems like all possible issues have been exhausted, I bought some of my things from Aliexpress and I have had faulty sensors from them in the past. I.e the QMC5883L was mislabeled as the HMC5883L,etc.Also the board that doesn't say r3 was from Aliexpress, but i haven't had any problems with it.
Try all combinations, see what works and what doesn't.
I think the BME280 and BME680 will have the same address by default, so in order to test them together you will need to change the address of one of them.
I scanned it after I did that and I got:
I2C Scanner
Scanning...
I2C device found at address 0x77 !
done
I also think the problem may have revealed itself some more(scanned when all were connected):
I2C device found at address 0x0D ! - Magnetometer
I2C device found at address 0x29 ! - TS2591 light sensor
I2C device found at address 0x77 ! - BME680
done
I ran my full code again and got the weird results again. Full code:
#include <Wire.h>
#include <QMC5883LCompass.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_TSL2591.h>
#include <math.h> // For atan2() and degrees()
#include "Arduino.h"
#include "MHZCO2.h"
#include "Adafruit_BME680.h"
#include <SPI.h>
// Light Sensor
Adafruit_TSL2591 tsl = Adafruit_TSL2591(0x29); // Corrected I2C address for TSL2591
#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10
#define SEALEVELPRESSURE_HPA (1027.25)
Adafruit_BME680 bme680(&Wire); // I2C
unsigned short offset = 1.5;
unsigned short alt_offset = 45;
float temp_offset = 0.0;
// Magnetometer
QMC5883LCompass compass;
const short MQ4Pin = A0; // Methane
const short MQ8Pin = A1; // Hydrogen
const short MQ7Pin = A2; // Carbon Monoxide
const short MQ137Pin = A3; // Ammonia
const short UVON = 7;
const short AON = 8;
const short Ozone = 4;
//co2 sensor vars
// adjust to calibrate.
const float MAX_CONCENTRATION = 5000.0;
volatile uint16_t width;
unsigned long delayTime;
//co2 funcs
void IRQ()
{
static uint32_t start = 0;
int v = digitalRead(3);
if (v == HIGH) start = millis();
else width = millis() - start;
}
uint16_t PWM_concentration()
{
noInterrupts();
uint16_t TimeHigh = width; // milliseconds
interrupts();
uint16_t concentration = round(((TimeHigh - 2) * MAX_CONCENTRATION) * 0.001);
return concentration;
}
// end of co2 funcs
//bme func:
void printValues() {
if (! bme680.performReading()) {
Serial.println("Failed to perform reading :(");
return;
}
Serial.print("Temperature = ");
Serial.print(bme680.temperature);
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bme680.pressure / 100.0);
Serial.println(" hPa");
Serial.print("Humidity = ");
Serial.print(bme680.humidity);
Serial.println(" %");
Serial.print("Gas = ");
Serial.print(bme680.gas_resistance / 1000.0);
Serial.println(" KOhms");
Serial.print("Approx. Altitude = ");
Serial.print(bme680.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.println();
}
//end of bme functions
void setup() {
Serial.begin(9600);
//delay(1000);
//Serial.begin(9600);
//while (!Serial) {} // Wait for serial monitor (useful for some boards)
Serial.println("Hello, world!");
pinMode(UVON, OUTPUT);
pinMode(AON, OUTPUT);
pinMode(Ozone, OUTPUT);
Serial.println("Initializing sensors...");
// Initialize light sensor
if (!tsl.begin()) {
Serial.println("TSL2591 not found! Check wiring or address.");
while (1);
}
configureLightSensor();
// Initialize magnetometer
Wire.begin();
compass.init(); // Initialize the QMC5883L magnetometer
Serial.println("QMC5883L magnetometer initialized.");
//bme 280
if (!bme680.begin()) {
Serial.println("Could not find a valid BME680 sensor, check wiring!");
while (1);
}
// Set up oversampling and filter initialization
bme680.setTemperatureOversampling(BME680_OS_8X);
bme680.setHumidityOversampling(BME680_OS_2X);
bme680.setPressureOversampling(BME680_OS_4X);
bme680.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme680.setGasHeater(320, 150); // 320*C for 150 ms
// co2
Serial.println(__FILE__);
Serial.print("MHZCO2_LIB_VERSION: ");
Serial.println(MHZCO2_LIB_VERSION);
attachInterrupt(digitalPinToInterrupt(3), IRQ, CHANGE);
//end co2
// Preheat gas sensors
digitalWrite(AON, HIGH);
digitalWrite(Ozone, HIGH);
Serial.println("Preheating MQ sensors...");
//delay(20000);
Serial.println("preheating...");
delay(60000);
Serial.println("preheating...");
//delay(20000);
Serial.println("Sensor readings in ppm:");
}
void loop() {
// Multiplex Ammonia sensor and UV sensor
digitalWrite(AON, HIGH);
delay(30);
float ammoniaVoltage = analogRead(MQ137Pin) * (5.0 / 1023.0);
digitalWrite(AON, LOW);
delay(30);
digitalWrite(UVON, HIGH);
delay(30);
int UVvoltage = analogRead(MQ137Pin);
delay(10);
int UVvoltage2 = analogRead(MQ137Pin);
delay(10);
int UVvoltage3 = analogRead(MQ137Pin);
float ave = (UVvoltage + UVvoltage2 + UVvoltage3) / 3;
digitalWrite(UVON, LOW);
delay(30);
digitalWrite(Ozone, HIGH);
float ozoneVoltage = analogRead(MQ137Pin) * (5.0 / 1023.0);
digitalWrite(Ozone, LOW);
// Gas Sensors
float methaneVoltage = analogRead(MQ4Pin) * (5.0 / 1023.0);
float hydrogenVoltage = analogRead(MQ8Pin) * (5.0 / 1023.0);
float carbonMonoxideVoltage = analogRead(MQ7Pin) * (5.0 / 1023.0);
// Convert sensor readings to ppm
float methanePPM = methaneVoltage * 0.5;
float hydrogenPPM = hydrogenVoltage * 0.5;
float carbonMonoxidePPM = carbonMonoxideVoltage * 1.0;
float ammoniaPPM = ammoniaVoltage * 0.5;
float ozonePPM = ozoneVoltage * 0.05;
// Light Sensor
uint16_t broadband, infrared;
uint32_t lux;
broadband = tsl.getFullLuminosity() >> 16;
infrared = tsl.getFullLuminosity() & 0xFFFF;
lux = tsl.calculateLux(broadband, infrared);
// Magnetometer
compass.read(); // Read the QMC5883L sensor data
// Retrieve the X, Y, and Z values
short x = compass.getX();
short y = compass.getY();
short z = compass.getZ();
// Calculate the heading (angle in degrees)
float heading = atan2(y, x);
// Convert from radians to degrees
heading = degrees(heading);
// Normalize the heading to be between 0 and 360
if (heading < 0) {
heading += 360;
}
// Print results
Serial.println(F("-----------------------------------------------------------------"));
Serial.println(F(" Gas Sensor Readings "));
Serial.println(F("-----------------------------------------------------------------\n"));
Serial.print("Methane (MQ4) : ");
Serial.print(methanePPM);
Serial.println(" ppm");
Serial.print("Hydrogen (MQ8) : ");
Serial.print(hydrogenPPM);
Serial.println(" ppm");
Serial.print("Carbon Monoxide (MQ7): ");
Serial.print(carbonMonoxidePPM);
Serial.println(" ppm");
Serial.print("Ammonia (MQ137) : ");
Serial.print(ammoniaPPM);
Serial.println(" ppm");
Serial.print("Ozone (MQ131) : ");
Serial.print(ozonePPM);
Serial.println(" ppm");
Serial.print("CO2 : ");
Serial.print(PWM_concentration());
Serial.println(" ppm\n");
Serial.println(F("-----------------------------------------------------------------"));
Serial.println(F(" Light Sensor Readings "));
Serial.println(F("-----------------------------------------------------------------\n"));
Serial.print("Full Spectrum : ");
Serial.print(broadband);
Serial.println(" (broadband)");
Serial.print("Infrared : ");
Serial.print(infrared);
Serial.println(" (IR)");
Serial.print("Lux : ");
Serial.print(lux);
Serial.println(" lx");
Serial.print("UV : ");
Serial.print(ave);
Serial.println(" voltage\n");
Serial.println(F("-----------------------------------------------------------------"));
Serial.println(F(" Magnetometer Readings "));
Serial.println(F("-----------------------------------------------------------------\n"));
// Output the magnetometer data (X, Y, Z axis)
Serial.print("Magnetic Field X : ");
Serial.print(x);
Serial.println(" µT");
Serial.print("Magnetic Field Y : ");
Serial.print(y);
Serial.println(" µT");
Serial.print("Magnetic Field Z : ");
Serial.print(z);
Serial.println(" µT");
Serial.print("Heading (°): ");
Serial.println(heading);
Serial.println(F("-----------------------------------------------------------------"));
Serial.println(F(" BME 280 Readings "));
Serial.println(F("-----------------------------------------------------------------\n"));
printValues();
Serial.println(F(">>>>>>>>>>>>>>>>>>>>>>>New_Readings>>>>>>>>>>>>>>>>>>>>>>>>>\n"));
delay(5000);
}
void configureLightSensor() {
tsl.setGain(TSL2591_GAIN_MED);
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);
Serial.println("TSL2591 configured:");
Serial.print("Gain : Medium\n");
Serial.print("Integration Time : 100ms\n");
}
and all I got for the output was:
I really don't know what is going on, cause the scanner saw it but my code won't function and nothing gets printed. My memory is also fine:
Sketch uses 23024 bytes (71%) of program storage space. Maximum is 32256 bytes.
Global variables use 1838 bytes (89%) of dynamic memory, leaving 210 bytes for local variables. Maximum is 2048 bytes.
Thanks, for helping me out here.
Could you try to put all the strings you have (Serial.print("this is a string")) inside the F() macro as you did at the end of your sketch?
To check if you could win some space in your RAM.
How are supplied the sensors? By the Arduino itself? Could you try to supply them with external 5V (or 3.3V)?
Don't forget to make the GND common