Adafruit BME688 & Waveshare ESP32-S3 Zero Mini

Hello,

my first post and first attempt at programming in about 30 years so please be gentle if I have done something really dim.

I have a BME688 Stemma board connected to the ESP32 via the 4 pin breakout cable.

The code below is from the Adafruit library with me attempting to modify so that it works via I2C rather than SPI and I have run into two issues

  • It compiled and uploaded fine first time but reported missing sensor
  • Now I get a com port error when i try to upload new code to the ESP32

the code, is as follows

/***************************************************************************
  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/3660

  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 and open-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 <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

#define I2C_SDA 12

#define I2C_SCL 13

#define SEALEVELPRESSURE_HPA (1013.25)

TwoWire I2CBME = TwoWire(0);

Adafruit_BME680 bme;

unsigned long delayTime;

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

  I2CBME.begin(I2C_SDA, I2C_SCL, 100000);

  bool status;

  bme.begin(0x76, &I2CBME);

  if (!status) {
    Serial.println(F("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() {
  // Tell BME680 to begin measurement.
  unsigned long endTime = bme.beginReading();
  if (endTime == 0) {
    Serial.println(F("Failed to begin reading :("));
    return;
  }
  Serial.print(F("Reading started at "));
  Serial.print(millis());
  Serial.print(F(" and will finish at "));
  Serial.println(endTime);

  Serial.println(F("You can do other work during BME680 measurement."));
  delay(50); // This represents parallel work.
  // There's no need to delay() until millis() >= endTime: bme.endReading()
  // takes care of that. It's okay for parallel work to take longer than
  // BME680's measurement time.

  // Obtain measurement results from BME680. Note that this operation isn't
  // instantaneous even if milli() >= endTime due to I2C/SPI latency.
  if (!bme.endReading()) {
    Serial.println(F("Failed to complete reading :("));
    return;
  }
  Serial.print(F("Reading completed at "));
  Serial.println(millis());

  Serial.print(F("Temperature = "));
  Serial.print(bme.temperature);
  Serial.println(F(" *C"));

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

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

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

  Serial.print(F("Approx. Altitude = "));
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(F(" m"));

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

The pins I have chosen on the ESP32 are shown as being I2C capable just struggling to find any obvious documnetation on whether they require initialising over and above what is in the above code.

I haven't done any programming since the early 90's so any pointers as to what I have got wrong would be appreciated.

Many thanks

Paul

try the I2C scanner

#include <Wire.h>
#include <i2cdetect.h>

#define I2C_SDA 12
#define I2C_SCL 13

void setup() {
  Wire.begin(I2C_SDA, I2C_SCL);
  //Wire.begin();
  Serial.begin(115200);
  Serial.println("i2cdetect example\n");
  Serial.print("Scanning address range 0x03-0x77\n\n");
  
}

void loop() {
  i2cdetect();
  delay(2000);
}

any reason not to use the default I2C pins pin 21 SDA and pin 22 SCL?

1 Like

thanks for the reply, according to the board layout shown on PI hut those pins aren't brought out to the headers (unless I am reading it wrong) so I choose the two in the top corner randomly

reading the thread title I see the device is a ESP32S3 Zero not a ESP32

looking at esp32-s3-zero-pinout pins 12 and 13 should work OK for the ESP32

the I2C detect program in post 2 should work OK

it seems my reading / typing skills may be lacking here - despite the module having address 77 written on it, I typed 76 - I2C scanner confirms it is definitely 77.

I will pay more attention to my typing in future

Thansk for the help

What value are you assigning to "status" in your code ?

I've got the impression that this esp32 version doesn't seem to work with in my case BME680.
I tried with Tasmota defining GPIO pins 8 + 9 and the BME680 was not detected, while it works fine with a bog standard esp32-vroom ?

using pins 8 and 9 of the ESP32S3 Zero for I2C should work - see ESP32S3 pin usage
have you tried running the I2C scanner - see post 2

Yes indeed i got the value of 77

77 is the I2C address commonly assigned to the BME280
have you tried the Adafruit_BME680 library ?

What in your I2C scanner code ? i assume Tasmota, otherwise why would it works with a esp32-vroom with default i2c pins 21+22?

Perhaps wait until the OP replies.
His code didn't give an output in the serial monitor, even when assigning " status =
bme.begin(0x76, &I2CBME);" or 0x77...

hi all,

After a bit more playing about and reading, the initial part of the code now looks like the below

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

#define I2C_SDA 12
#define I2C_SCL 13

Adafruit_BME680 bme;

unsigned long delayTime;

void setup() {
Wire.begin(I2C_SDA, I2C_SCL);
Serial.begin(115200);

The above works and was returning the expected results from the sensor when combined with the remainder of the original code, I have since altered it again as I was looking for the sensor to output some very specific results and am playing with the Bosch toolkit and forgot to save the whole working code to share here.

Thanks to those who provided advice

Paul

here is the complete piece of code that returned values for temp, pressure, RH, gas resistance and altitude - I realised I had it in a text file.

Paul

/***************************************************************************
  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/3660

  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 and open-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 <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

#define I2C_SDA 12
#define I2C_SCL 13
#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme;

unsigned long delayTime;

void setup() {
Wire.begin(I2C_SDA, I2C_SCL);
Serial.begin(115200);
while (!Serial);
Serial.println(F("Air Quality Monitor"));

  if (!bme.begin()) {
    Serial.println(F("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() {
  // Tell BME680 to begin measurement.
  unsigned long endTime = bme.beginReading();
  if (endTime == 0) {
    Serial.println(F("Failed to begin reading :("));
    return;
  }
  Serial.print(F("Reading started at "));
  Serial.print(millis());
  Serial.print(F(" and will finish at "));
  Serial.println(endTime);

  if (!bme.endReading()) {
    Serial.println(F("Failed to complete reading :("));
    return;
  }
  Serial.print(F("Reading completed at "));
  Serial.println(millis());

  Serial.print(F("Temperature = "));
  Serial.print(bme.temperature);
  Serial.println(F(" *C"));

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

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

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

  Serial.print(F("Approx. Altitude = "));
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(F(" m"));


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

I found an example of code similar to yours and followed the Espressif site for defining I2C pins. I used it in PlatformIO, but imagine it should work in the Arduino IDE minus the 1st line.

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

int sda_pin = 8; // GPIO8 as I2C SDA
int scl_pin = 9; // GPIO9 as I2C SCL

Adafruit_BME680 bme; // I2C

void setup() {
  Wire.setPins(sda_pin, scl_pin); // Set the I2C pins before begin
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(115200);
  while (!Serial);
  Serial.println(F("BME680 async test"));

  if (!bme.begin()) {
    Serial.println(F("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() {
  // Tell BME680 to begin measurement.
  unsigned long endTime = bme.beginReading();
  if (endTime == 0) {
    Serial.println(F("Failed to begin reading :("));
    return;
  }
  Serial.print(F("Reading started at "));
  Serial.print(millis());
  Serial.print(F(" and will finish at "));
  Serial.println(endTime);

  Serial.println(F("You can do other work during BME680 measurement."));
  delay(50); // This represents parallel work.
  // There's no need to delay() until millis() >= endTime: bme.endReading()
  // takes care of that. It's okay for parallel work to take longer than
  // BME680's measurement time.

  // Obtain measurement results from BME680. Note that this operation isn't
  // instantaneous even if milli() >= endTime due to I2C/SPI latency.
  if (!bme.endReading()) {
    Serial.println(F("Failed to complete reading :("));
    return;
  }
  Serial.print(F("Reading completed at "));
  Serial.println(millis());

  Serial.print(F("Temperature = "));
  Serial.print(bme.temperature);
  Serial.println(F(" *C"));

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

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

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

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

The ESP32-S3-Zero is great for it's size, i wonder if it could support a PMS5003 sensors in addition ?
That would mean a really complact air sensor device :slightly_smiling_face:

It is on my list to try the particulate sensors next - I just need to get this bit finished up as I am putting a BME680 board in each each room to gather data on the effectiveness of the ventilation system and have it fed back to the home automation system controling the services within the house.

2 posts were split to a new topic: ESP32s3 and BME680

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.