The PM2.5 particulate sensor readings are now being recorded into a text file on a SD Card, every 3 minutes. The 3 minute interval is arbitrary at this point in the project.
The file format is Comma-Separated Values (CSV). Each line of the file contains two elements:
- Timestamp in Universal Time Coordinated (UTC) format. UTC is an industry-standard way to represent a timestamp. It is not affected by timezones or daylight savings time.
- PM2.5 Atmosphere reading from the Plantower PMS5003 particulate sensor
Here is an example slice of data from a recording:
1543831740, 4 1543831920, 4 1543832100, 2 1543832280, 4 1543832460, 6 1543832640, 4 1543832820, 4 1543833000, 3 1543833180, 4
Asynchronous Programming
The MicroPython programming piece is implemented using an asynchronous programming approach.
Why asynchronous programming for the Street Sense project?
Consider ... the Street Sense device has several functions that will run concurrently, for example:
- reading data from the sensors using I2C and UART hardware interfaces
- checking for DS3231 real time clock alarms
- reading audio samples from the I2S microphone
- checking for button presses
- writing sensor data and audio samples to the SD Card
- publishing sensor data to an internet cloud database with MQTT over a WiFi connection
Implementing these concurrent operations is a natural fit for asynchronous programming. The MicroPython project provides a uasyncio library for implementing a program with an asynchronous approach.
Getting up-to-speed
My embedded system programming experience has been with 32-bit real-time operating systems (RTOS) with preemptive, priority based task schedulers. In these operating systems concurrent tasks are "time-sliced" by the RTOS. It is a very different way to program than co-operative scheduling with asynchronous programming.
I discovered a helpful learning resource focused on MicroPython - the uasyncio tutorial by Peter Hinch. This tutorial provides detailed examples on implementing asynchronous programming in MicroPython. The tutorial also describes the asyn library, which provides various "primitives" to synchronize activity between the Street Sense device features. Two synchronization primitives are particularly useful in the first implementation: Events and Barriers.
For example, the asyn library Barrier primitive is used to align the sensor reading activity to the 3-minute interval alarm.
As I get better at asynchronous programming I expect to improve and refactor the code with each iteration. The first iteration of the MicroPython code is stored in a Github repository.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.