Аппаратные средства и программное обеспечение
- Датчик качества воздуха 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
следующее:
IMAGE_ROOTFS_EXTRA_SPACE = «8388608»
— для выделения дополнительного пространства;ENABLE_I2C = «1»
иKERNEL_MODULE_AUTOLOAD_rpi += «i2c-dev i2c-bcm2708»
— для включения I2C;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
. Используем следующие рецепты:
ntp
— для получения точного времени.rustup
— для копирования скрипта установки Rust в rootfs.startup-script
— для копирования и инициализации скрипта, который организует подключение к WiFi-сети и запускает сервисntp
.tzdata
— для установки часового пояса. Этот файл нужно модифицировать в соответствии с используемым часовым поясом.wpa_supplicant
— для настройки WiFi-сети. В этот файл нужно внести данные беспроводной сети, к которой будет подключаться устройство.
Повторно соберём образ и скопируем его на SD-карту.
Подключение датчика к Raspberry Pi
Для подключения датчика к Raspberry Pi воспользуемся макетной платой и двумя резисторами на 10 кОм. Соберём всё в соответствии со схемой, приведённой на с. 16 технического описания датчика.
Подключение датчика SPS30 к Raspberry Pi
В ходе работы нам пригодится схема выводов GPIO Raspberry Pi 4.
Схема выводов GPIO Raspberry Pi 4
Вот как датчик подключается к Raspberry Pi:
- Пин
VDD (1)
SPS30 подключаем к пину4 (5V power)
Raspberry Pi. - Пин
SDA (2)
SPS30 подключаем к пину3 (GPIO 2 (SDA))
Raspberry Pi. - Пин
SCL (3)
SPS30 подключаем к пину5 (GPIO 3 (SCL))
Raspberry Pi. - Пин
SEL (4)
SPS30 подключаем к пину6 (Ground)
Raspberry Pi. - Пин
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())
Планируете собрать систему для мониторинга качества воздуха, похожую на ту, о которой шла речь в этой статье?
Комментариев нет:
Отправить комментарий