PMS5003 Particulate Matter Sensor Test Run

Hi

In this article we’ll test out the PMS5003 sensor in order to see if it works. I’ve forgot to buy a connector board, so we will do a manual connection to the Raspberry Pi 3 B V2. This involves cutting the wires and adding some resistors.

Please note that you need:

  • 5 Jumper Wires
  • 2 Resistors 10K Ohm

Raspberry Pi Setup

Before connecting the sensor to the Pi we need to configure the Pi for this usecase.

Note that if you’re using this sensor with Raspberry Pi, then you’ll need to make a couple of changes to its configuration. Type sudo raspi-config in the terminal and then under “Interfacing options” and “Serial” disable the login shell and enable the serial port hardware. Edit your /boot/config.txt file and add the lines enable_uart=1 and dtoverlay=pi3-miniuart-bt to the bottom of the file.

From: https://shop.pimoroni.com/products/pms5003-particulate-matter-sensor-with-cable

After the setup from above is done, reboot the Pi and install the software.

sudo pip install pms5003
git clone https://github.com/pimoroni/pms5003-python

Note: In order to connect to the Raspberry Pi I’ve used Visual Studio Code and the Remote – SSH, this is unnecessary, editing files is VSCode is a personal preference.

Sensor Wiring

To identify the sensor’s wires I’ve consulted the PMS5003 specification and I’ve cut my sensor’s Picoblade connector, this enabled me to use jumper wires and attach my 10K ohms resistors to the wires. Then I’ve isolated the wires using some electrical tape.

Note: I’ve connected PIN 3 and PIN 6 to a 10K ohm pull up resistor at 3.3V because at the moment I don’t know if I need to reset the sensor or put it to sleep.

To simplify things further:

SENSOR 1 (VCC) -> RPI 5V

SENSOR 2 (GND) -> RPI Ground

SENSOR 3 & 6 (SET & RESET) -> 10k OHM -> RPI 3.3V

SENSOR 4 (RXD) -> RPI Gpio 14 (UART TX)

SENSOR 6 (TXD) -> RPI Gpio 15 (UART RX)

That’s it! It will look something like the following.

Verify that the sensor is connected then ssh into the Pi and run the all.py example from pms5003-python. You should see something like:

The results can be interpreted using the following reference table.

Thanks for reading!

Nucu Car Devlog: 0x03 – Android

Hello everyone!

I’ve been working lately on my little project involving Raspberry Pi and .NET, during my free time. Now, I’ve introduced a new technology, Android!

The project needed a front-end and It took me a long time to decide how to implement it and what technology to use.

I was conflicting between a cross platform desktop application or a web application. I initially thought Electron would have been a great choice since it covers both, but it doesn’t work out of the box with gRPC and I needed some proxies which complicated the things on the backend, not to mention JavaScript is horrible in every imaginable way.

Luckily for me, I started dabbing in Android and somehow I manage to get a simple activity up which reads the data from the NucuCar.Sensors component.

It connects to it via gRPC directly. I didn’t expect that setting up gRPC on the Android would be so easy to be honest, you can literally just follow the gRPC tutorial for Java and everything works.

Getting that to work got me motivated and I’ve fixed some bugs in the NucuCar.Telemetry component. This made it possible for NucuCar.Sensors to run for four straight days, non-stop without crashing, it’s still running at this moment.

The component reports sensor reading to Firestore every one minute, since there are 24h in a day it reports around 1.4K readings a day.

At this point I’m pretty proud of this project, I wrote a simple Python script to plot the Temperature, Humidity and VOC resistance from my apartment, for the last 3 days:

As you can see the spikes on 2020-11-28 12:00 indicate that I’ve opened the windows and let some fresh air come into the apartment. The temperature and the humidity dropped while VOC resistance rises. The higher the VOC value the better the air quality.

This project is open-source and it can be found on my Github profile.

Thanks for reading!

Nucu Car: Devlog 0x02

Hello,

I’m still working on my NucuCar project from time to time, I’m currently at my parents home and I left the raspberry pi at my apartment so I’m only testing the builds it on my computer. Luckily I can test the telemetry by using the CPU temperature sensor implemented by dotnet IoT.

For the next step, I wanted an effective way to store telemetry data in the cloud, preferably for free, since this is a hobby project after all.

After testing multiple solutions I’ve settled with Firebase, I tried to write a telemetry publisher for it using it’s SDK which internally uses gRPC and everything went well until I put it on the board. It turns out that dotnet gRPC doesn’t work on raspberry pi. I got the basic server working using a hack but that’s about it, so I moved to the REST API and I’ve implemented a simple translator which translates raw C# dictionaries into compatible Firebase RESTful post request Json payload.

The project got a little bigger and at the current state it was quite messy, a restructuring is needed and this is what I’ve done:

NucuCar.Domain

Initially I’ve designed the NucuCar.Domain project to contain .proto files and data classes without too much implementation, however, many Telemetry Publishers such as Azure, Disk were in this package and it was kind of wrong because they contain too much implementation and they were dependent on heavy external packages and they would bring too much of a burden.

The TelemetryPublisher abstract class and the ITelemeter interface both which don’t contain implementation remained in NucuCar.Domain and the concrete publishers along with the worker were extracted in NucuCar.Telemetry.

I’ve also extracted the Firebase translator into a package of it’s own, and published it on NuGet, making this my first published package. 😀

NucuCar.Common

In NucuCar.Common, I’ve moved some of the classes which were utility classes and were still present in NucuCar.Domain, the ConnectionParser class and a class which provides basic argument guarding.

Another thing that I needed and I’ve implemented in NucuCar.Common is a HttpClient wrapper class, I found very verbose to serialize Json every time and deserialize it when sending data to Firebase.

Thus I made a simple wrapper to simplify the process, while also introducing a retry mechanism and cancellation and timeout support.

Conclusion

Overall I’m quite happy with the end result and I’m looking forward to see what interesting things I can implement in the future.

I’m not sure if I want this to be a remote controlled toy car project anymore, it sounds good but I think it would be more practical If I could connect multiple sensors, create a simple interface and monitor my apartment using this, perhaps add some support to automatically water my plants, that would be nice.

The project is open source and can be found on my Github.

Thanks for reading!

Firebase Rest on Raspberry Pi

I’ve tried to use Google’s Firebase with the Firebase Admin SDK in my C# project. The good news is that the Admin SDK is easy to use and all you need to do is call two methods. The authentication part is handled by an environment variable which points to some .json file which you download. The bad news is that the SDK depends on gRPC and the dotnet version of it doesn’t work well on the Raspberry Pi.

What I’m going to do is to replace the admin SDK with simple REST API calls, this way I can post data to Firebase from anywhere, at this moment I only want to post data from the Raspberry Pi.

I’ve been browsing the REST API Reference docs in in order to figure it out how to make requests and after some time of experimenting and reading the documentation I’ve translated by hand a simple telemetry request from my Raspberry Pi into a restful Firebase request.

This is how it looks like in the Firebase format:

PATCH https://firestore.googleapis.com/v1/projects/project_name/databases/(default)/documents/collection_name/doc_id

{
	"name": "batman",
	"fields": {
		"source": {
			"stringValue": "NucuCar.Sensors"
		},
		"timestamp": {
			"timestampValue": "2019-12-01T23:26:13.5537227+02:00"
		},
		"data": {
			"arrayValue": {
				"values": [
					{
						"mapValue": {
							"fields": {
								"sensor_state": {
									"integerValue": 2
								},
								"cpu_temperature": {
									"doubleValue": 48
								},
								"_id": {
									"stringValue": "CpuTemperature"
								}
							}
						}
					},
					{
						"mapValue": {
							"fields": {
								"sensor_state": {
									"integerValue": 2
								},
								"temperature": {
									"doubleValue": 32
								},
								"humidity": {
									"doubleValue": 100.0
								},
								"pressure": {
									"doubleValue": 6222
								},
								"voc": {
									"doubleValue": 0.0
								},
								"_id": {
									"stringValue": "Bme690-Sensor"
								}
							}
						}
					}
				]
			}
		}
	}
}

All what’s left to do now is to write a translator which translates raw C# dictionaries into the format from above. I want to reuse this without much hassle if my telemetry data format changes.

After a bit of trial and error I’ve managed to implement a translator, thus completely dropping the dependency for Firebase’s Admin SDK. I haven’t implemented authentication handling yet, but it’s on my board.

Thank you for reading!