Шановні друзі!
26 та 31 грудня магазин працюватиме до 16 години. 1 та 2 січня магазин працювати не буде.
Вітаємо всіх з Різдвом та Новим Роком!
Мобильная версия Форум Arduino Документация Гарантийные условия 0 0
UA RU
График работы магазина:
Пн-Пт: 8.00 - 19.00
Сб: 10.00 - 17.00
Вс: выходной
Каталог
Напиши статью и получи скидку!

Виготовляєм однодротовий метеодатчик на основі BME680

2023-10-31

Все статьи →

Датчик температури, вологості, тиску і якості повітря BME680 має інтерфейси для підключення I2C та SPI, але, на жаль, ці інтерфейси не дозволяють підключати датчик на значній відстані, оскільки вони призначені для внутрішньосхемної взаємодії. Як же бути?

Скористаємось модулем розширення портів з інтерфейсом 1-wire, який, серед іншого, має функцію конвертера в SPI-master.


Інтерфейс 1-wire може працювати на відстанях до 100м, а при якісних кабелях навіть до 300м. Крім того, до однієї шини можна підключати майже необмежену кількість slave-пристроїв, кожен з яких адресується за унікальною адресою. Таким чином дальність підключення по SPI можна значно збільшити, а кількість сигнальних дротів скоротити з чотирьох (CS,SCK,MISO,MOSI) до лише одного, але ціною за це буде значне зниження швидкості обміну, яка теоретично не перевищить 8200 біт/с при повнодуплексній передачі по SPI.

Плата модуля розширення портів має невеличку макетну частину, на якій можна спаяти якусь нескладну схему. Модуль з BME680 підключається за дуже простою схемою:

Діод Шотткі в схемі використаний в якості перетворювача логічних рівнів з 5В в 3.3В, оскільки для сигналу CS розробники плати цього не зробили. Спершу паяємо "доріжки" і діод:

Потім припаюємо плату з BME680:

Намагаємось розмістити дві плати якомога ближче, щоб пристрій помістився в корпус, але залишаємо проміжок між мікросхемою модуля розширення портів і платою з BME680 десь 0.5мм. Гвинтовий клемник в корпус не поміститься, замість нього можна використати, наприклад, кутовий роз'єм JST-XH 2.54мм 3-pin, а щоб розмістити його посередині навпроти отвору в корпусі, перерізаємо доріжку на платі між продубльованими отворами DQ і з одного з них за допомогою перемички робим вивід VCC.

Перед збіркою в корпус ретельно промиваєм плату спиртом від залишків флюсу, оскільки в вологому середовищі флюс поглинає вологу і може проводити струм. Плата модуля розширення портів майже ідеально поміщається в китайський корпус для датчиків.

Готовий датчик підключається трьома дротами GND,VCC,DQ. При використанні витої пари для підключення по 1-wire я завжди раджу помаранчевий призначати для VCC, зелений - для DQ, а біло-помаранчевий разом з біло-зеленим - для GND.

При підключенні до Arduino підключаємо DQ до будь-якого цифрового виходу і не забуваємо між DQ і VCC включити резистор підтяжки від 1кОм до 4.7кОм. Змінюємо в скетчі лише номер піна DQ і адресу свого модуля розширення портів. Функція bme680(addr, CS, &t, &h, &p); дозволяє читати параметри з довільного модуля розширення портів на шині 1-wire за його адресою addr, функція повертає ненульове значення у випадку помилки, наприклад, якщо addr відсутній на шині, або до вказаного модуля розширення портів підключений не BME680.

При підключенні до Linux є відмінності лише пов'язані з тим, який майстер шини 1-wire використовується, а робота з модулем розширення портів і датчиком BME680 універсальна. Наведу приклад для Raspberry Pi та програмного майстра шини 1-wire w1-gpio, який перетворює один з виводів гребінки Raspberry Pi в вивід DQ. Оскільки цифрові виводи Raspberry Pi лише 3.3 вольтові, а в 1-wire використовується 5В, то потрібно використати стандартну схему конвертера логічних рівнів. Щоб включити w1-gpio, наприклад, на виводі 7 гребінки (це GPIO4), додаємо в /boot/config.txt наступну стрічку і перезавантажуємо.

dtoverlay=w1-gpio,gpiopin=4

В dmesg знайдений на шині 1-wire модуль розширення портів буде відображено так:

w1_master_driver w1_bus_master1: Attaching one wire slave 20.594e480f4245 crc 95

Залишається лише повідомити ядру Linux, що до SPI інтерфейсу модуля розширення портів підключений датчик BME680 і в якості CS використовується P0:

# echo 0 bme680 >/sys/bus/w1/devices/w1_bus_master1/20-594e480f4245/spi_bind

В dmesg будуть повідомлення лише у разі помилки, якщо модуль ядра bme680_spi не зміг домовитись з пристроєм на шині SPI модуля, а якщо все гаразд, то з'являться символьний пристрій в /dev і каталог в /sys

# ls -l /dev/iio*

crw------- 1 root root 236, 0 жов 12 12:22 /dev/iio:device0

# ls -l /sys/bus/w1/devices/w1_bus_master1/20-594e480f4245/spi_master/spi3/spi3.0/iio\:device0

-r--r--r-- 1 root root 4096 жов 12 12:22 dev

-rw-r--r-- 1 root root 4096 жов 12 12:22 in_humidityrelative_input

-rw-r--r-- 1 root root 4096 жов 12 12:22 in_humidityrelative_oversampling_ratio

-rw-r--r-- 1 root root 4096 жов 12 12:22 in_pressure_input

-rw-r--r-- 1 root root 4096 жов 12 12:22 in_pressure_oversampling_ratio

-rw-r--r-- 1 root root 4096 жов 12 12:22 in_resistance_input

-rw-r--r-- 1 root root 4096 жов 12 12:22 in_temp_input

-rw-r--r-- 1 root root 4096 жов 12 12:22 in_temp_oversampling_ratio

-r--r--r-- 1 root root 4096 жов 12 12:22 name

-r--r--r-- 1 root root 4096 жов 12 12:22 oversampling_ratio_available

drwxr-xr-x 2 root root 0 жов 12 12:22 power

lrwxrwxrwx 1 root root 0 жов 12 12:22 subsystem -> ../../../../../../../bus/iio

-rw-r--r-- 1 root root 4096 жов 12 12:22 uevent

Значення температури, вологості та тиску можна отримати прямо з командного рядка:

# cat /sys/bus/w1/devices/w1_bus_master1/20-594e480f4245/spi_master/spi3/spi3.0/iio\:device0/in_temp_input 25320

# cat /sys/bus/w1/devices/w1_bus_master1/20-594e480f4245/spi_master/spi3/spi3.0/iio\:device0/in_humidityrelative_input 44.210000000

# cat /sys/bus/w1/devices/w1_bus_master1/20-594e480f4245/spi_master/spi3/spi3.0/iio\:device0/in_pressure_input 997.250000000

Але є одна незручність - номер пристрою spi3 залежить від того, скільки в системі до цього вже було зареєстровано пристроїв spi, тому повний шлях до файлів не є константою, яку можна було б використовувати в скриптах. На /sys/bus/w1/devices/w1_bus_master1/20-594e480f4245/spi_master/spi3/spi3.0/iio:device0 є символьне посилання з підсистеми iio

# ls -l /sys/bus/iio/devices/iio\:device0

lrwxrwxrwx 1 root root 0 жов 19 18:36 /sys/bus/iio/devices/iio:device0 -> ../../../devices/w1_bus_master1/20-594e480f4245/spi_master/spi3/spi3.0/iio:device0

Хоч номер пристрою iio:device0 також залежить від кількості пристроїв iio, вже зареєстрованих в системі та також не є константою, але за допомогою udev можна дуже просто зробити на цей каталог своє символьне посилання.

ACTION=="add", SUBSYSTEM=="w1", KERNEL=="20-594e480f4245",\

ATTR{spi_bind}+="0 bme680"

ACTION=="add", SUBSYSTEM=="iio", KERNELS=="20-594e480f4245",\

RUN+="/bin/ln -s /sys/bus/iio/devices/%k /var/run/bme680_kimnata",\

ENV{REMOVE_CMD}="/bin/rm /var/run/bme680_kimnata"

Перше правило під'єднати до SPI інтерфейсу заданого модуля розширення портів датчик BME680, а друге при успішній реєстрації в системі пристрою iio, пов'язаного саме з цим з BME680, виконає задану команду і створить змінну оточення для даного екземпляру iio пристрою. Змінна %k на момент виконання команди буде мати значення iio:deviceN з актуальним номером пристрою замість N. Щоб змінна оточення ENV{REMOVE_CMD} виконала завдання, передбачене її назвою, необхідно додати правило (якщо такого ще немає).

ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}"

Тепер при появі на шині модуля розширення портів з ідентифікатором 20-594e480f4245 буде з'являтися символьне посилання на каталог з потрібними файлами:Зверніть увагу, в udev є подібна вбудована функція для створення символьних посилань SYMLINK+="dev_alias", але вона призначена виключно для символьних пристроїв в межах каталога /dev.

# ls -l /var/run/bme680_kimnata

lrwxrwxrwx 1 root root 32 жов 19 18:36 /var/run/bme680_kimnata -> /sys/bus/iio/devices/iio:device0

# cat /var/run/bme680_kimnata/in_temp_input

23440 # cat /var/run/bme680_kimnata/in_humidityrelative_input

42.491000000

# cat /var/run/bme680_kimnata/in_pressure_input

990.310000000

Імена файлів вже ні від чого не залежать і їх можна використовувати в скриптах, наприклад, ось таким скриптом на perl, який запускається з cron щохвилини, можна відправляти дані з датчика в rrdtool.

#!/usr/bin/perl

use RRDCached;

sub rv {if(open F,$_[0]){$_=0+<F>;close F}else{$_="U"}$_;}

$t=rv("/var/run/bme680_kimnata/in_temp_input");

$h=rv("/var/run/bme680_kimnata/in_humidityrelative_input");

$p=rv("/var/run/bme680_kimnata/in_pressure_input");

$r=rv("/var/run/bme680_kimnata/in_resistance_input");

$rrd = RRDCached->new("unix:/var/run/rrdcached.sock");

$rrd->update("bme680_room.rrd", "N:$t:$h:$p:$r");

$rrd->done();

На графіку відображені результати роботи за першу добу, в лівій половині графіка датчик був підключений через програмний майстер шини (w1-gpio), а в правій - через апаратний (DS2480B).

Отже, з w1-gpio щось негаразд, якщо у Вас виникла схожа картина, не поспішайте звинувачувати датчик. Якщо у Вас новий датчик, то Ви також можете спостерігати неперервний ріст значення опору газового сенсора - це норма, на сайті виробника пояснили, що опір стабілізується приблизно через тиждень неперервної роботи.

Корисні формули:

Датчик видає тиск в гектоПаскалях або мілібарах (це одне й те ж), переведення в міліметри ртутного стовпчика:

p_mmHg = p_mbar * 760 / 1013.25

Абсолютна вологість повітря в грамах водяної пари на кубічний метр обчислюється за наближеною формулою:

a = exp(17.62*t/(243.12+t))/(461.52*(t+273.15))*6112*h, де t - температура повітря в градусах Цельсія, h - відносна вологість в відсотках.

Температура точки роси в градусах Цельсія обчислюється за наближеною формулою:

d=243.12*f/(17.62-f), де f=17.62*t/(243.12+t)+ln(h/100)

Забруднення повітря в еквівалентних грамах на кубічний метр (забруднення, які викликають таку ж чисельну реакцію датчика, як і відповідна кількість водяної пари):

w=16.53*ln(50000/r)-a

Коефіцієнт пропорційності 16.53 був знайдений експериментально за методикою, описаною в статті, 50000 Ом - приблизний опір датчика, що відповідає абсолютно чистому повітрю без забруднювачів і водяної пари, r - виміряний опір датчика в Омах, a - абсолютна вологість в грамах на кубічний метр. Величина w є сумою реакцій на всі забруднювачі, пропорційність реакції на окремі хімічні речовини може відрізнятися в залежності від термопрофілю і частоти опитувань, ця інформація компанією Bosch не розкривається.

Якість повітря по нелінійній шкалі від 0 (нескінченно забруднене повітря) до 100 (абсолютно чисте повітря) можна отримати по формулі:

q=exp(-w/20)*100

Тут 20 - референсна забрудненість повітря в еквівалентних грамах на кубічний метр, яка відповідає значенню якості повітря exp(-1)*100~=36.8

Ваша оценка статьи:

Отлично
Хорошо
Удовлетворительно
Плохо
Очень плохо

Общая оценка:

Оценка "Виготовляєм однодротовий метеодатчик на основі BME680"
5 из 5
сделана на основе 1 оценки 1 клиентских отзыва.

Благодарим Вас за обращение! Ваш отзыв появится после модерации администратором.
TeleX
11.11.2023 15:50:20
Дякую, дуже повчально.
оплата картами Visa и MasterCard