adafruit / Adafruit_BME680

117 stars 76 forks source link

Locks up after a period of time #51

Closed pdbayes closed 1 year ago

pdbayes commented 1 year ago

Hi. I have been using this library with both an esp32 and an Arduino uno. I switched from the esp as it kept locking up and had to be reset every few days. I am now using an Arduino Uno and it stops getting readings after about an hour. I had it running connected by usb to a pc and when I started the serial monitor it ran the setup routine and started working, so debugging is tricky. I changed to a 12v PSU but have the same result. I have swapped from begin reading to perform reading, still the same. I also changed from the Arduino doing the WiFi and connection to AWS IoT to using an Espressif Expresslink board to do that part. I am using the example code from here but with added serial communication to the Espressif board. Any ideas?

pdbayes commented 1 year ago

Here is the code.

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

/*#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

#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);
typedef enum response_codes
{
  EL_OK, EL_OVERFLOW, EL_PARSE_ERROR, EL_COMMAND_NOT_FOUND, EL_PARAMETER_ERROR,
  EL_INVALID_ESCAPE, EL_NO_CONNECTION, EL_TOPIC_OUT_OF_RANGE, EL_TOPIC_UNDEFINED,
  EL_INVALID_KEY_LENGTH, EL_INVALID_KEY_NAME, EL_UNKNOWN_KEY, EL_KEY_READONLY,
  EL_KEY_WRITEONLY, EL_UNABLE_TO_CONNECT, EL_TIME_NOT_AVAILABLE, EL_LOCATION_NOT_AVAILABLE,
  EL_MODE_NOT_AVAILABLE, EL_ACTIVE_CONNECTION, EL_HOST_IMAGE_NOT_AVAILABLE, EL_INVALID_ADDRESS,
  EL_INVALID_OTA_UPDATE, EL_INVALID_QUERY, EL_INVALID_SIGNATURE
}response_codes_t;

// Send a command and retrieve the response
String SendCommand(String command)
{
  Serial.print(command+"\n");
  String response = Serial.readString();
  return response;
}

// Get the response code from the begining of an ExpressLink response
response_codes_t checkResponse(String response)
{
  if(response.indexOf("OK")!= -1) return EL_OK;
  int errPosition = response.indexOf("ERR");
  response_codes_t errCode =  (response_codes_t) response.substring(3).toInt();
  return errCode;
}

void expressLinkConnect()
{
  String response;
  bool finished = false;

  response = SendCommand("AT+CONNECT?");
  if(response.indexOf("OK 1")==-1)
  {
    Serial.println("Connecting ExpressLink");
    do{
      response = SendCommand("AT+CONNECT");
      if(checkResponse(response) == EL_OK)
      {
        finished = true;
      }
      else
      {
        Serial.println(response);
      }
    }while(!finished);
    Serial.println("Connected to ExpressLink");
  }
}

void setup() {
  Serial.begin(115200);
  Wire.begin();
  SendCommand("AT+CONF Topic1=Weather");
  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() {
  expressLinkConnect();
  if (! bme.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }

  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(" %"));
  String Temperature = String(bme.temperature);

  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();
  float temperatureInC = bme.temperature;
  float pressureHpa = bme.pressure / 100.0;
  float relativeHumidity = bme.humidity;
  float gasResistance = bme.gas_resistance / 1000.0;
  float dewPoint = dewPointFast(bme.temperature,  bme.humidity);
  float cloudBase = (((bme.temperature - dewPoint)/2.5) *1000) + 100;

  expressLinkConnect();
  Serial.print("AT+SEND1 {\"temperatureInC\":");
  Serial.print(temperatureInC);
  Serial.print(",\"humidityPercentage\":");
  Serial.print(relativeHumidity);
  Serial.print(",\"pressureHpa\":");
  Serial.print(pressureHpa);
  Serial.print(",\"gasResistance\":");
  Serial.print(gasResistance);
  Serial.print(",\"dewPoint1\":");
  Serial.print(dewPoint);
  Serial.print(",\"cloudBase1\":");
  Serial.print(cloudBase);

  Serial.println("}");

  delay(10000);
}
float dewPointFast(float celsius, float humidity)
{
  float a = 17.271;
  float b = 237.7;
  float temp = (a * celsius) / (b + celsius) + log(humidity*0.01);
  float Td = (b * temp) / (a - temp);
  return Td;
}
caternuson commented 1 year ago

Do you get the same lock up behavior running the example sketch as is? Without the expressLinkConnect stuff?

pdbayes commented 1 year ago

Hi I got the same behaviour when I was using an ESP32 on WiFi connecting to an MQTT broker. I can try without the expresslink stuff but unless I leave the pc on and the serial monitor running I have no way of knowing if it's still running.

caternuson commented 1 year ago

I can try without the expresslink stuff but unless I leave the pc on and the serial monitor running I have no way of knowing if it's still running.

Please do. That test needs to be done for troubleshooting to rule out it being something with the wifi/mqtt stuff. If there is an issue with this library, then the behavior should be demonstrable using the library example. https://github.com/adafruit/Adafruit_BME680/blob/master/examples/bme680test/bme680test.ino and with the sensor connected as shown in the guide: https://learn.adafruit.com/adafruit-bme680-humidity-temperature-barometic-pressure-voc-gas/arduino-wiring-test

pdbayes commented 1 year ago

So, the sensor is working fine and carried on for around 18 hours before I decided to try with the express link board and then it was sending the readings to AWS for a short time and then stopped. It looks like attempts to connect are failing but it should just keep trying to connect until it succeeds. I am at a loss. Maybe a serial issue as the expresslink commands are using the same SUART as the console.

caternuson commented 1 year ago

It sounds like the issue is with AWS? Not with this library?

pdbayes commented 1 year ago

Yes, or maybe the uno can't cope with just the one SUART. Interestingly, resetting the uno with the serial monitor off seems to be sending messages to AWS now.