# Air Quality Monitoring Unit (nRF9151 + SEN66 + BMP581)

## Overview
This project demonstrates how our custom unit collects and transmits environmental data using the **nRF9151 chipset**, **Sensirion SEN66**, and **Bosch BMP581** sensors.  
The data is processed on the device and published to a **MongoDB database** over MQTT.

## How It Works

### System Flow
1. **RTC** is configured for a 20-minute interval and updates the `alarm_expired` flag when the timer expires.  
2. **Sensor loop** runs every 2 minutes to measure PM values and environmental data.  
3. **Adaptive interval**: Based on the PM2.5 value, the publish interval may be updated (e.g., every 5 or 10 minutes instead of 20).  
4. When the `alarm_expired` flag is set to `true`, a **multi-threaded function** sends the data to MongoDB via MQTT.  
5. On **Google Cloud Platform (GCP)**, EMQX acts as the MQTT broker and receives the published data.  
6. The subscribed data is stored in **MongoDB** for further processing or visualization.  

### Initialization
When the unit starts:
1. Retrieves a unique **Device ID** from the nRF9151 chipset.  
2. Checks the status of connected sensors (SEN66 and BMP581).  
3. Configures system components:
   - PSM (Power Saving Mode)  
   - Modem  
   - RTC (Real-Time Clock)  
   - MQTT client  
   - Other necessary settings  

### Data Collection
- The SEN66 measures **particulate matter (PM)** levels every **2 minutes**.  
- The BMP581 provides pressure and related environmental data.  

### Adaptive Publish Interval
- The publish interval is dynamically adjusted based on **PM2.5 concentration**:  
  - PM2.5 >= 35.5 µg/m³** → data is published every **5 minutes**  
  - PM2.5 < 35.5 && PM2.5 >12.1 → data is published every **10 minutes**
  - Otherwise → default interval is used  **20 minutes**

### Multi-Threading

### Why Multithreading?
The decision to use **multi-threading** was made to ensure proper synchronization with the **RTC (Real-Time Clock)**.  

- If `publish_sensor_data()` is placed inside the main loop, it **does not execute immediately** when the RTC flag for publishing is set.  
- By running the publishing function in a **separate thread**, the program can:
  - React instantly to RTC events  
  - Maintain accurate timing for data publishing  
  - Avoid blocking the main sensor measurement loop  



