David GherghitaIoan Herisanu
Published © GPL3+

Air Quality Monitor using Raspberry Pi 4, SPS30 and Azure

Connect a particulate matter sensor to a Raspberry Pi and obtain easy-to-read graphs based on the read data using Microsoft Azure.

IntermediateProtip5 hours85,432
Air Quality Monitor using Raspberry Pi 4, SPS30 and Azure

Things used in this project

Hardware components

Sensirion SPS30
×1
Raspberry Pi 4 Model B
Raspberry Pi 4 Model B
×1
Breadboard (generic)
Breadboard (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
×1

Software apps and online services

Rust Programming Language
Microsoft Azure
Microsoft Azure
Yocto Project
Yocto Project

Story

Read more

Schematics

Circuit

Photo of the circuit on a breadboard.

Code

Rust

Rust
Rust program called by the Python script to print data from the sensor to the screen.
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

Python
Python script to get data from the Rust program and send it to the Azure cloud.
#!/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():
	# Connect device to IoT Hub
	conn_str = "TODO"
	device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)
	await device_client.connect()

	while True:
		# Read data from sensor
		cmd = ['sensor-read/target/release/sensor-read']
		process = subprocess.Popen(cmd, stdout=subprocess.PIPE)

		results = []
		for line in process.stdout:
			results.append(float(line))

		# Send message
		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())

Yocto layer

Yocto layer for configuring the distro.

Credits

David Gherghita

David Gherghita

2 projects • 2 followers
Ioan Herisanu

Ioan Herisanu

2 projects • 2 followers

Comments