Мониторинг качества воздуха с использованием Raspberry Pi 4, датчика Sensirion SPS30 и Microsoft Azure

от автора

В материале, перевод которого мы публикуем сегодня, речь пойдёт о том, как подключить датчик качества воздуха Sensirion Particulate Matter Sensor SPS30 к Raspberry Pi 4, и о том, как, пользуясь возможностями Microsoft Azure, представить сведения о качестве воздуха в удобном для восприятия виде.


Аппаратные средства и программное обеспечение

  • Датчик качества воздуха Sensirion Particulate Matter Sensor SPS30.
  • Одноплатный компьютер Raspberry Pi 4 Model B.
  • Макетная плата.
  • Соединительные провода.
  • Дистрибутив Linux, собранный с помощью Yocto Project.
  • Программы на Rust и Python.
  • Облачная платформа Microsoft Azure.

Сборка ОС

Для того чтобы использовать в этом проекте Raspberry Pi 4 нужно для начала собрать минимальный дистрибутив Linux с помощью Yocto Project.

Клонируем Yocto-слой BSP для Raspberry Pi отсюда и переключимся на коммит 497a90a. Кроме того, воспользуемся коммитом 35364c0ce отсюда и коммитом ca701cb92d отсюда. Соберём образ и скопируем его на SD-карту, пользуясь инструкциями из репозитория. Проверим работоспособность образа.

Модифицируем образ, добавив в файл rpi-build/conf/local.conf следующее:

  1. IMAGE_ROOTFS_EXTRA_SPACE = «8388608» — для выделения дополнительного пространства;
  2. ENABLE_I2C = «1» и KERNEL_MODULE_AUTOLOAD_rpi += «i2c-dev i2c-bcm2708» — для включения I2C;
  3. CORE_IMAGE_EXTRA_INSTALL += «bash nano tar zip openssh curl ca-certificates ntp tzdata packagegroup-core-buildessential python3 python3-pip i2c-tools git startup-script rustup» — для добавления дополнительных пакетов.

Продолжим модификацию образа, добавим путь к слою meta-mylayer в список BBLAYERS, который находится в файле rpi-build/conf/bblayers.conf. Используем следующие рецепты:

  1. ntp — для получения точного времени.
  2. rustup — для копирования скрипта установки Rust в rootfs.
  3. startup-script — для копирования и инициализации скрипта, который организует подключение к WiFi-сети и запускает сервис ntp.
  4. tzdata — для установки часового пояса. Этот файл нужно модифицировать в соответствии с используемым часовым поясом.
  5. wpa_supplicant — для настройки WiFi-сети. В этот файл нужно внести данные беспроводной сети, к которой будет подключаться устройство.

Повторно соберём образ и скопируем его на SD-карту.

Подключение датчика к Raspberry Pi

Для подключения датчика к Raspberry Pi воспользуемся макетной платой и двумя резисторами на 10 кОм. Соберём всё в соответствии со схемой, приведённой на с. 16 технического описания датчика.

Подключение датчика SPS30 к Raspberry Pi

В ходе работы нам пригодится схема выводов GPIO Raspberry Pi 4.

Схема выводов GPIO Raspberry Pi 4

Вот как датчик подключается к Raspberry Pi:

  1. Пин VDD (1) SPS30 подключаем к пину 4 (5V power) Raspberry Pi.
  2. Пин SDA (2) SPS30 подключаем к пину 3 (GPIO 2 (SDA)) Raspberry Pi.
  3. Пин SCL (3) SPS30 подключаем к пину 5 (GPIO 3 (SCL)) Raspberry Pi.
  4. Пин SEL (4) SPS30 подключаем к пину 6 (Ground) Raspberry Pi.
  5. Пин GND (5) SPS30 подключаем к пину 6 (Ground) Raspberry Pi.

Проверим соединение, выполнив на Raspberry Pi команду i2cdetect -y 1 и узнав, обнаружено ли устройство с адресом 0x69.

Чтение данных

Установим на Raspberry Pi Rust, воспользовавшись скриптом rustup.

Загрузим драйвер для датчика:

git clone https://github.com/david-gherghita/sps30-i2c-rs.git 

Проверим правильность работы системы следующей командой:

cargo run --example linux 

Отправка данных в облако

Создадим учётную запись на сайте Microsoft Azure.

На вкладке Azure Services создадим новую группу ресурсов (Resource Group).

Создание новой группы ресурсов

Создадим в группе ресурсов новый IoT-хаб (IoT Hub) и перейдём на его страницу.

В разделе Explorers щёлкнем по IoT Devices и добавим новое устройство. Тут нужно обратить внимание на поле Primary Connection String, так как именно эта строка будет использоваться для подключения платы к облаку.

Настройка нового устройства

Скомпилируем и запустим программу на Rust (её можно найти в разделе «Код»), используя cargo, и настроим зависимости проекта:

linux-embedded-hal = "0.3.0" sps30-i2c = "0.1.0" 

Заполним строку соединения (Primary Connection String), проверим путь к Rust-программе и запустим Python-программу (её тоже можно найти в разделе «Код»).

Если всё сделано правильно — можно будет увидеть, как в IoT-хаб поступают данные.

Данные поступают в IoT-хаб

Теперь вернёмся в Microsoft Azure, создадим задание Stream Analytics и добавим новый поток входных данных из IoT-хаба, проверив, чтобы в качестве Event serialization format был выбран JSON.

На вкладке Input Preview должны появиться новые данные.

Данные, полученные с Raspberry Pi

Для того чтобы просматривать эти данные в более удобном виде, в форме графиков, нужно добавить к заданию Stream Analytics выход типа Power Bi. В качестве Authentication Mode нужно указать User Token. Это нужно для того чтобы у нас была бы возможность использовать собственное рабочее пространство в роли рабочего пространства Power Bi.

Далее, модифицируем функцию выполнения запроса, приведя её к виду, показанному ниже. Это нужно для отправки данных в Power Bi.

SELECT     "mass_pm1.0",     "mass_pm2.5",     "mass_pm4.0",     "mass_pm10",     "number_pm0.5",     "number_pm1.0",     "number_pm2.5",     "number_pm4.0",     "number_pm10",     "typical_size",     CAST ("sensor_time" AS datetime) "sensor_time" INTO     "AQS-PowerBI" FROM     IoT 

Для того чтобы наконец воспользоваться данными в Power Bi, нужно перейти на соответствующую страницу, войти в своё рабочее пространство и, пользуясь простым графическим интерфейсом, создать отчёт на основе набора данных, полученного от задания Stream Analytics.

Визуализация данных

Схема подключения компонентов

Подключение компонентов

Код

Вот код Rust-программы, вызываемой Python-скриптом для вывода сведений, полученных с датчика.

use linux_embedded_hal::{Delay, I2cdev}; use sps30_i2c::Sps30;  fn main() {     let dev = I2cdev::new("/dev/i2c-1").unwrap();     let delay = Delay;     let mut sensor = Sps30::new_sps30(dev, delay);      let result = sensor.read_measured_values().unwrap();      println!("{}", result.mass_pm1_0);     println!("{}", result.mass_pm2_5);     println!("{}", result.mass_pm4_0);     println!("{}", result.mass_pm10);      println!("{}", result.number_pm0_5);     println!("{}", result.number_pm1_0);     println!("{}", result.number_pm2_5);     println!("{}", result.number_pm4_0);     println!("{}", result.number_pm10);      println!("{}", result.typical_size); } 

Вот Python-скрипт, который вызывает программу, написанную на Rust, получает сведения с датчика и отправляет их в Microsoft Azure.

#!/usr/bin/python3.8  import os import asyncio from azure.iot.device.aio import IoTHubDeviceClient from azure.iot.device import Message import time import subprocess  async def main():   # Подключение устройства к IoT-хабу   conn_str = "TODO"   device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)   await device_client.connect()    while True:     # Чтение показателей датчика     cmd = ['sensor-read/target/release/sensor-read']     process = subprocess.Popen(cmd, stdout=subprocess.PIPE)      results = []     for line in process.stdout:       results.append(float(line))      # Отправка сообщения     msg = Message('{\       "mass_pm1.0": %f,\       "mass_pm2.5": %f,\       "mass_pm4.0": %f,\       "mass_pm10": %f,\       "number_pm0.5": %f,\       "number_pm1.0": %f,\       "number_pm2.5": %f,\       "number_pm4.0": %f,\       "number_pm10": %f,\       "typical_size": %f,\     }' % tuple(results))     await device_client.send_message(msg)      time.sleep(15)  if __name__ == "__main__":   asyncio.run(main()) 

Планируете собрать систему для мониторинга качества воздуха, похожую на ту, о которой шла речь в этой статье?

ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/527234/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *