Подключение датчика окружающей среды BME680 к Arduino

Подключение датчика окружающей среды BME680 к Arduino

Хотите создать персональный трекер качества воздуха, который покажет, достаточно ли хорошая вентиляция в вашей спальне, мастерской или на рабочем месте? Установите модуль датчика окружающей среды BME680 на Arduino и следите за всеми параметрами воздуха в помещении.

Современный модуль BME680 позволяет измерять температуру, давление, влажность и качество воздуха в помещении, и самое приятное — он совместим с Arduino!

Датчик окружающей среды BME680

В основе модуля лежит датчик окружающей среды нового поколения от Bosch — BME680.

Interface BME680 Environmental Sensor with Arduino

Этот небольшой датчик обладает возможностями измерения температуры, влажности, атмосферного давления и газов VOC (летучих органических соединений). Он содержит миниатюрный MOx-датчик (на основе оксида металла). Нагретый оксид металла изменяет сопротивление в зависимости от VOC в воздухе, поэтому его можно использовать для обнаружения газов и спиртов, таких как этанол, алкоголь и угарный газ, а также для измерения качества воздуха. Таким образом, BME680 может работать как полностью автономный датчик окружающей среды.

Как и большинство газовых датчиков, этот датчик чувствителен к нескольким газам и спиртам, но не может определить, какой именно. Он выдаёт одно значение сопротивления с общим содержанием VOC. Поэтому лучше всего он подходит для измерения изменений в известной концентрации газа, а не для определения того, какой газ изменяется.

Как и `BME280 `_, этот прецизионный датчик может измерять влажность с точностью ±3%, атмосферное давление с абсолютной точностью ±1 гПа и температуру с точностью ±1,0°C. Измерения давления настолько точны, что его можно использовать даже в качестве альтиметра с точностью ±1 метр.

Вот полные характеристики:

Температура

-40°C до 85°C

Влажность

0 до 100% RH с точностью ±3%

Давление

300Pa до 1100 hPa с абсолютной точностью ±1 hPa

Высота

0 до 30,000 ft (9.2 км) с точностью ±1 метр

Для получения дополнительной информации обратитесь к техническому описанию ниже.

Что такое летучие органические соединения (VOC)?

Летучие органические соединения (VOC) выделяются в виде газов из определённых продуктов, которые мы используем для строительства и обслуживания наших домов (таких как освежители воздуха, чистящие средства, косметика, мазут, бензин, краски, лаки, ковровые покрытия и виниловые полы и т.д.). VOC включают разнообразные химические вещества, некоторые из которых могут иметь краткосрочные и долгосрочные негативные последствия для здоровья.

Распространённые примеры VOC, которые могут присутствовать в нашей повседневной жизни: бензол, этиленгликоль, формальдегид, метиленхлорид, тетрахлорэтилен, толуол, ксилол и 1,3-бутадиен.

Требования к питанию

Модуль поставляется с прецизионным стабилизатором напряжения XC6206 3,3V и транслятором уровней напряжения, поэтому вы можете использовать его с любимым микроконтроллером 3,3V или 5V без каких-либо опасений.

Interface BME680 Environmental Sensor with Arduino

BME680 потребляет менее 1 мА во время измерений и всего 0,15 мкА в режиме сна. Такое низкое энергопотребление позволяет использовать его в устройствах с батарейным питанием, таких как смартфоны, носимые устройства или умные часы.

Цифровые интерфейсы

Датчик обменивается данными по I2C или SPI.

Датчик использует интерфейс I2C для связи с Arduino. Он поддерживает два отдельных I2C-адреса: 0x77Hex и 0x76Hex. Это позволяет использовать два BME680 на одной шине или избежать конфликтов адресов с другим устройством на шине.

Interface BME680 Environmental Sensor with Arduino

Вывод SDO определяет I2C-адрес модуля. Этот вывод имеет встроенный подтягивающий резистор. Поэтому, когда вывод SDO не подключён, I2C-адрес по умолчанию — 0x77Hex, а при подключении к GND линия подтягивается к LOW и I2C-адрес становится 0x76Hex.

Датчик также может обмениваться данными через интерфейс SPI.

Для справки:

Если вам нужно выбрать между двумя интерфейсами, SPI обычно лучше, если требуется более высокая скорость передачи (до 10 МГц). I2C, с другой стороны, лучше подходит, если на вашем микроконтроллере ограничено количество свободных выводов.

Как работает MEMS-датчик газа BME680?

В отличие от `MQ2 `_ или `MQ3 `_, газовый датчик BME680 изготовлен по технологии MEMS (микроэлектромеханических систем). Обнаружение газа на основе MEMS обеспечивает значительное уменьшение размеров, снижение энергопотребления и возможность расширения функциональности и избирательности.

Типичный MEMS-датчик газа состоит из слоя полупроводника на основе оксида металла (чувствительный материал), который реагирует с целевым газом, как минимум двух электродов для мониторинга изменений электрического сопротивления/тока и микронагревателя для повышения рабочей температуры.

Interface BME680 Environmental Sensor with Arduino

Когда слой полупроводника на основе оксида металла нагревается до высокой температуры, кислород `адсорбируется `_ на поверхности. В чистом воздухе электроны из зоны проводимости оксида металла притягиваются к молекулам кислорода. Это формирует обеднённый электронами слой непосредственно под поверхностью частиц оксида металла и создаёт потенциальный барьер. В результате слой оксида металла становится высокоомным и препятствует протеканию электрического тока.

Однако в присутствии газов поверхностная плотность адсорбированного кислорода уменьшается, так как он реагирует с газами, что снижает потенциальный барьер. Электроны высвобождаются в слой оксида металла, позволяя току свободно протекать через датчик.

Interface BME680 Environmental Sensor with Arduino

Распиновка модуля BME680

Давайте рассмотрим распиновку.

Interface BME680 Environmental Sensor with Arduino

Выводы питания:

VCC — это вывод питания. Подключите его к выходу 5V Arduino.

GND — это общая земля для питания и логики.

Выводы логики SPI:

SCL — это вывод тактирования SPI, вход на микросхему.

SDA — это вывод входных последовательных данных (SDI/MOSI), для данных, отправляемых с микроконтроллера на BME680.

SDO — это вывод выходных последовательных данных (SDO/MISO), для данных, отправляемых с BME680 на микроконтроллер.

CS — это вывод выбора микросхемы (Chip Select), подтяните его к LOW для включения связи по SPI. Если вы хотите подключить несколько BME680 к одному микроконтроллеру, используйте общие выводы SDI, SDO и SCK, назначив каждому уникальный вывод CS.

Выводы логики I2C:

SCL — это также вывод тактирования I2C, подключите к линии тактирования I2C вашего микроконтроллера.

SDA — это также вывод данных I2C, подключите к линии данных I2C вашего микроконтроллера.

Подготовка модуля BME680 к использованию

Перед первым использованием датчика рекомендуется провести его `прогрев `_ в течение 48 часов, а затем включать на 30 минут в нужном режиме при каждом использовании. Причина в том, что уровень чувствительности датчика изменяется при первоначальном использовании, и сопротивление постепенно увеличивается по мере нагрева MOx-элемента до базового показания.

Схема подключения модуля BME680 к Arduino

Теперь, когда мы знаем всё о модуле, можно приступить к его подключению к Arduino!

Подключение по I2C

Используйте эту схему, если хотите подключиться через интерфейс I2C.

Начните с подключения вывода VCC к источнику питания — подходит 3V-5V. Используйте то же напряжение, что и логика вашего микроконтроллера. Для большинства Arduino это 5V. Для устройств с логикой 3,3V используйте 3,3V. Подключите GND к общей земле.

Подключите вывод SCL к выводу тактирования I2C, а вывод SDA — к выводу данных I2C на Arduino. Обратите внимание, что у каждой платы Arduino разные выводы I2C, которые необходимо подключать соответственно. На платах Arduino с компоновкой R3 выводы SDA (линия данных) и SCL (линия тактирования) расположены на штыревых разъёмах рядом с выводом AREF. Они также известны как A5 (SCL) и A4 (SDA).

На следующей иллюстрации показана схема подключения.

Interface BME680 Environmental Sensor with Arduino

Подключение по SPI

Поскольку датчик поддерживает SPI, вы можете использовать аппаратный или программный SPI. Однако рекомендуется использовать аппаратные выводы SPI, так как они значительно быстрее, чем программная реализация интерфейса на других выводах.

Опять же, у каждой платы Arduino разные выводы SPI, которые необходимо подключать соответственно. Для плат Arduino UNO/Nano V3.0 это цифровые выводы 13 (SCK), 12 (MISO), 11 (MOSI) и 10 (SS).

Если вы используете другую плату Arduino, рекомендуется проверить официальную документацию о `расположении выводов SPI `_ перед началом работы.

На следующей иллюстрации показана схема подключения.

Interface BME680 Environmental Sensor with Arduino

После подключения модуля к Arduino пора написать код!

Установка библиотеки

Чтобы начать считывать данные датчика, необходимо установить `библиотеку Adafruit_BME680 `_. Она доступна в менеджере библиотек Arduino.

Для установки библиотеки перейдите в Sketch > Include Library > Manage Libraries… Дождитесь, пока менеджер библиотек загрузит индекс и обновит список установленных библиотек.

Interface BME680 Environmental Sensor with Arduino

Отфильтруйте поиск, введя „adafruit bme680“. Нажмите на эту запись и выберите Install.

Interface BME680 Environmental Sensor with Arduino

Библиотека датчика BME280 использует `бэкенд Adafruit Sensor `_. Поэтому найдите в менеджере библиотек Adafruit Unified Sensor и установите его тоже (возможно, придётся немного прокрутить).

Interface BME680 Environmental Sensor with Arduino

Примеры скетчей BME680

Библиотека Adafruit_BME680 содержит несколько примеров скетчей. Вы можете использовать эти примеры как основу для разработки собственного кода.

Для доступа к примерам скетчей перейдите в File > Examples > Adafruit BME680 Library. Вы увидите набор примеров.

Interface BME680 Environmental Sensor with Arduino

Код Arduino — считывание газа, давления, влажности, температуры и высоты

Загрузите скетч bme680test из примеров в вашу Arduino IDE. Это базовый скетч Arduino. Загрузите его на Arduino. Вы должны увидеть температуру, давление, влажность, газ и приблизительную высоту в мониторе последовательного порта.

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

// Uncomment if you want to use SPI
//#define BME_SCK 13
//#define BME_MISO 12
//#define BME_MOSI 11
//#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme;
//Adafruit_BME680 bme(BME_CS); // Uncomment if you want to use SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

void setup() {
  Serial.begin(9600);
  while (!Serial);

  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 :(");
    return;
  }
  Serial.print("Temperature = ");
  Serial.print(bme.temperature);
  Serial.println(" *C");

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

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

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

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

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

Обратите внимание, что необходимо установить скорость монитора последовательного порта 115200 бод для проверки скетча.

Вы увидите множество данных: температуру, давление, влажность, газ и приблизительную высоту. Попробуйте перемещать датчик и наблюдайте, как изменяются данные.

Interface BME680 Environmental Sensor with Arduino

Объяснение кода:

Скетч начинается с подключения четырёх необходимых библиотек: Wire.h (для I2C), SPI.h (для SPI), Adafruit_Sensor.h и Adafruit_BME680.h.

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

В этом примере используется протокол связи I2C для обмена данными с датчиком. Однако код подготовлен и для использования SPI. Для этого достаточно раскомментировать следующие строки, определяющие выводы SPI.

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

Далее определяется переменная SEALEVELPRESSURE_HPA. Эта переменная хранит давление на уровне моря в миллибарах и используется для оценки высоты путём сравнения заданного давления с давлением на уровне моря. В этом скетче используется значение по умолчанию, но для точных результатов замените его текущим давлением на уровне моря для вашего местоположения.

#define SEALEVELPRESSURE_HPA (1013.25)

По умолчанию этот скетч использует протокол I2C. Следующая строка создаёт объект Adafruit_BME680 с именем bme на выводах I2C Arduino.

Adafruit_BME680 bme;

Если вы хотите использовать SPI, закомментируйте предыдущую строку и раскомментируйте следующие.

//Adafruit_BME680 bme(BME_CS);
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

В setup мы инициализируем последовательную связь с компьютером и вызываем функцию begin(). Функция begin() инициализирует интерфейс I2C и проверяет идентификатор чипа. Затем выполняет программный сброс чипа и ожидает калибровку датчика после пробуждения.

Serial.begin(9600);
while (!Serial);

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

Далее мы настраиваем некоторые параметры датчика.

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

Рассмотрим каждую функцию отдельно.

Для повышения эффективного разрешения измерений и снижения шума BME680 поддерживает передискретизацию (многократное измерение и усреднение). Три функции setTemperatureOversampling(), setHumidityOversampling() и setPressureOversampling() устанавливают передискретизацию для измерений температуры, влажности и давления соответственно. Эти функции принимают один из следующих параметров:

  • BME680_OS_NONE (отключает измерение)

  • BME680_OS_1X

  • BME680_OS_2X

  • BME680_OS_4X

  • BME680_OS_8X

  • BME680_OS_16X

BME680 также оснащён внутренним IIR-фильтром для уменьшения краткосрочных изменений показаний датчика, вызванных внешними воздействиями (такими как хлопанье дверью или обдув датчика воздухом). Функция setIIRFilterSize() настраивает IIR-фильтр. Фильтр можно настроить на различные коэффициенты, выбрав один из следующих параметров:

  • BME680_FILTER_SIZE_0 (без фильтрации)

  • BME680_FILTER_SIZE_1

  • BME680_FILTER_SIZE_3

  • BME680_FILTER_SIZE_7

  • BME680_FILTER_SIZE_15

  • BME680_FILTER_SIZE_31

  • BME680_FILTER_SIZE_63

  • BME680_FILTER_SIZE_127

Кроме того, нагревательную пластину газового датчика можно настроить на нагрев перед выполнением измерения газа. Функция setGasHeater() задаёт профиль нагрева и принимает два аргумента:

  • heaterTemp — температура нагрева (в °C)

  • heaterTime — время нагрева (в миллисекундах)

Например, bme.setGasHeater(320, 150) нагреет пластину газового датчика до 320°C на 150 миллисекунд.

В loop мы вызываем функцию bme.performReading() для выполнения измерения в блокирующем режиме. После этого мы можем обращаться к переменным экземпляра bme через оператор точки (.).

bme.temperature возвращает показание температуры.

bme.pressure возвращает показание атмосферного давления.

bme.humidity возвращает показание относительной влажности.

bme.gas_resistance возвращает сопротивление газа.

bme.readAltitude(SEALEVELPRESSURE_HPA) вычисляет высоту (в метрах) на основе указанного атмосферного давления (в гПа) и давления на уровне моря (в гПа).

if (! bme.performReading()) {
     Serial.println("Failed to perform reading :(");
     return;
}
Serial.print("Temperature = ");
Serial.print(bme.temperature);
Serial.println(" *C");

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

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

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

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