Name | mhz14a JSON |
Version |
0.1.3
JSON |
| download |
home_page | None |
Summary | Python library for MH-Z14A CO₂ sensor |
upload_time | 2025-08-17 08:19:07 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.8 |
license | None |
keywords |
co2
mhz14a
raspberry-pi
sensor
uart
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# MH-Z14A Python Library
[](https://github.com/oaslananka/mhz14a/actions/workflows/ci.yml)
[](https://pypi.org/project/mhz14a/)
[](https://pypi.org/project/mhz14a/)
Python library and command-line interface for the MH-Z14A CO₂ sensor.
## Features
- Pure Python implementation with minimal dependencies (only `pyserial`)
- Type-safe with full type annotations
- Command-line interface for easy integration
- Context manager support
- Comprehensive error handling with retry logic
- Supports all sensor features: reading, calibration, ABC, range setting
## Installation
```bash
pip install mhz14a
```
## Quick Start
### Python Library
```python
from mhz14a import MHZ14A
# Using context manager (recommended)
with MHZ14A('/dev/mhz14a') as sensor:
ppm = sensor.read_co2()
print(f"CO₂: {ppm} ppm")
# Manual connection management
sensor = MHZ14A('/dev/mhz14a')
sensor._connect()
try:
ppm = sensor.read_co2()
print(f"CO₂: {ppm} ppm")
finally:
sensor._disconnect()
```
### Command-Line Interface
```bash
# Read CO₂ concentration
mhz14a --port /dev/mhz14a read
# Sample readings every 5 seconds, 10 times
mhz14a --port /dev/mhz14a sample --interval 5 --count 10
# Sample with JSON output
mhz14a --port /dev/mhz14a sample --interval 1 --count 5 --json
# Zero point calibration (in fresh air, 400 ppm)
mhz14a --port /dev/mhz14a zero
# Span calibration with known concentration
mhz14a --port /dev/mhz14a span --ppm 2000
# Enable/disable Automatic Baseline Correction
mhz14a --port /dev/mhz14a abc --on
mhz14a --port /dev/mhz14a abc --off
# Set measurement range
mhz14a --port /dev/mhz14a range --max 5000
```
## Raspberry Pi Setup
### Hardware Connection
Connect the MH-Z14A sensor to your Raspberry Pi using a USB-to-TTL converter (e.g., CH340):
- MH-Z14A VIN → 5V (or 3.3V depending on sensor version)
- MH-Z14A GND → GND
- MH-Z14A TXD → USB-TTL RXD
- MH-Z14A RXD → USB-TTL TXD
### udev Rule Setup
Create a persistent device name for your sensor:
1. Copy the provided udev rule:
```bash
sudo cp extras/99-mhz14a.rules /etc/udev/rules.d/
```
2. Reload udev rules:
```bash
sudo udevadm control --reload-rules
sudo udevadm trigger
```
3. Add your user to the `dialout` group:
```bash
sudo usermod -a -G dialout $USER
```
4. Log out and log back in for group changes to take effect.
The sensor will now be available as `/dev/mhz14a` instead of `/dev/ttyUSB0`.
### udev Rule Content
The `extras/99-mhz14a.rules` file contains:
```
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="mhz14a", MODE="0660", GROUP="dialout"
```
## Calibration
### Zero Point Calibration
⚠️ **Important**: Only perform zero calibration in fresh outdoor air (approximately 400 ppm CO₂):
1. Power on the sensor and wait at least 20 minutes for stabilization
2. Ensure the sensor is in fresh air (outdoors or well-ventilated area)
3. Run calibration:
```bash
mhz14a --port /dev/mhz14a zero
```
### Span Calibration
For span calibration, you need a known CO₂ concentration:
```bash
mhz14a --port /dev/mhz14a span --ppm 2000
```
### Automatic Baseline Correction (ABC)
ABC automatically adjusts the zero point based on the assumption that the lowest CO₂ reading in a 24-hour period represents fresh air (400 ppm).
- **Enable ABC** (default, suitable for most applications):
```bash
mhz14a --port /dev/mhz14a abc --on
```
- **Disable ABC** (for continuous high CO₂ environments):
```bash
mhz14a --port /dev/mhz14a abc --off
```
## Measurement Ranges
The sensor supports three measurement ranges:
- **2000 ppm** (0-2000 ppm): Higher resolution, suitable for indoor air quality
- **5000 ppm** (0-5000 ppm): Balanced range for most applications
- **10000 ppm** (0-10000 ppm): Maximum range for industrial applications
```bash
mhz14a --port /dev/mhz14a range --max 2000
mhz14a --port /dev/mhz14a range --max 5000
mhz14a --port /dev/mhz14a range --max 10000
```
## Python API Reference
### MHZ14A Class
```python
class MHZ14A:
def __init__(self, port: str, timeout: float = 1.0) -> None:
"""Initialize sensor with port and timeout."""
def read_co2(self) -> int:
"""Read CO₂ concentration in ppm."""
def zero_calibrate(self) -> None:
"""Perform zero point calibration (400 ppm fresh air)."""
def span_calibrate(self, ppm: int) -> None:
"""Perform span calibration with known concentration."""
def set_abc(self, enable: bool) -> None:
"""Enable or disable Automatic Baseline Correction."""
def set_range(self, max_ppm: int) -> None:
"""Set measurement range (2000, 5000, or 10000 ppm)."""
```
### Error Handling
All sensor operations can raise `MHZ14AError` exceptions:
```python
from mhz14a import MHZ14A, MHZ14AError
try:
with MHZ14A('/dev/mhz14a') as sensor:
ppm = sensor.read_co2()
print(f"CO₂: {ppm} ppm")
except MHZ14AError as e:
print(f"Sensor error: {e}")
```
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Acknowledgments
- MH-Z14A sensor documentation and protocol specifications
- Python serial communication community
Raw data
{
"_id": null,
"home_page": null,
"name": "mhz14a",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "Osman Aslan <admin@oaslananka.me>",
"keywords": "co2, mhz14a, raspberry-pi, sensor, uart",
"author": null,
"author_email": "Osman Aslan <admin@oaslananka.me>",
"download_url": "https://files.pythonhosted.org/packages/f8/2c/11764f7b699c6f7cbc6e17fb77cf3d7379c052568ec3b2f1d4139ac8d197/mhz14a-0.1.3.tar.gz",
"platform": null,
"description": "# MH-Z14A Python Library\n\n[](https://github.com/oaslananka/mhz14a/actions/workflows/ci.yml)\n[](https://pypi.org/project/mhz14a/)\n[](https://pypi.org/project/mhz14a/)\n\nPython library and command-line interface for the MH-Z14A CO\u2082 sensor.\n\n## Features\n\n- Pure Python implementation with minimal dependencies (only `pyserial`)\n- Type-safe with full type annotations\n- Command-line interface for easy integration\n- Context manager support\n- Comprehensive error handling with retry logic\n- Supports all sensor features: reading, calibration, ABC, range setting\n\n## Installation\n\n```bash\npip install mhz14a\n```\n\n## Quick Start\n\n### Python Library\n\n```python\nfrom mhz14a import MHZ14A\n\n# Using context manager (recommended)\nwith MHZ14A('/dev/mhz14a') as sensor:\n ppm = sensor.read_co2()\n print(f\"CO\u2082: {ppm} ppm\")\n\n# Manual connection management\nsensor = MHZ14A('/dev/mhz14a')\nsensor._connect()\ntry:\n ppm = sensor.read_co2()\n print(f\"CO\u2082: {ppm} ppm\")\nfinally:\n sensor._disconnect()\n```\n\n### Command-Line Interface\n\n```bash\n# Read CO\u2082 concentration\nmhz14a --port /dev/mhz14a read\n\n# Sample readings every 5 seconds, 10 times\nmhz14a --port /dev/mhz14a sample --interval 5 --count 10\n\n# Sample with JSON output\nmhz14a --port /dev/mhz14a sample --interval 1 --count 5 --json\n\n# Zero point calibration (in fresh air, 400 ppm)\nmhz14a --port /dev/mhz14a zero\n\n# Span calibration with known concentration\nmhz14a --port /dev/mhz14a span --ppm 2000\n\n# Enable/disable Automatic Baseline Correction\nmhz14a --port /dev/mhz14a abc --on\nmhz14a --port /dev/mhz14a abc --off\n\n# Set measurement range\nmhz14a --port /dev/mhz14a range --max 5000\n```\n\n## Raspberry Pi Setup\n\n### Hardware Connection\n\nConnect the MH-Z14A sensor to your Raspberry Pi using a USB-to-TTL converter (e.g., CH340):\n\n- MH-Z14A VIN \u2192 5V (or 3.3V depending on sensor version)\n- MH-Z14A GND \u2192 GND\n- MH-Z14A TXD \u2192 USB-TTL RXD\n- MH-Z14A RXD \u2192 USB-TTL TXD\n\n### udev Rule Setup\n\nCreate a persistent device name for your sensor:\n\n1. Copy the provided udev rule:\n ```bash\n sudo cp extras/99-mhz14a.rules /etc/udev/rules.d/\n ```\n\n2. Reload udev rules:\n ```bash\n sudo udevadm control --reload-rules\n sudo udevadm trigger\n ```\n\n3. Add your user to the `dialout` group:\n ```bash\n sudo usermod -a -G dialout $USER\n ```\n\n4. Log out and log back in for group changes to take effect.\n\nThe sensor will now be available as `/dev/mhz14a` instead of `/dev/ttyUSB0`.\n\n### udev Rule Content\n\nThe `extras/99-mhz14a.rules` file contains:\n```\nSUBSYSTEM==\"tty\", ATTRS{idVendor}==\"1a86\", ATTRS{idProduct}==\"7523\", SYMLINK+=\"mhz14a\", MODE=\"0660\", GROUP=\"dialout\"\n```\n\n## Calibration\n\n### Zero Point Calibration\n\n\u26a0\ufe0f **Important**: Only perform zero calibration in fresh outdoor air (approximately 400 ppm CO\u2082):\n\n1. Power on the sensor and wait at least 20 minutes for stabilization\n2. Ensure the sensor is in fresh air (outdoors or well-ventilated area)\n3. Run calibration:\n ```bash\n mhz14a --port /dev/mhz14a zero\n ```\n\n### Span Calibration\n\nFor span calibration, you need a known CO\u2082 concentration:\n\n```bash\nmhz14a --port /dev/mhz14a span --ppm 2000\n```\n\n### Automatic Baseline Correction (ABC)\n\nABC automatically adjusts the zero point based on the assumption that the lowest CO\u2082 reading in a 24-hour period represents fresh air (400 ppm).\n\n- **Enable ABC** (default, suitable for most applications):\n ```bash\n mhz14a --port /dev/mhz14a abc --on\n ```\n\n- **Disable ABC** (for continuous high CO\u2082 environments):\n ```bash\n mhz14a --port /dev/mhz14a abc --off\n ```\n\n## Measurement Ranges\n\nThe sensor supports three measurement ranges:\n\n- **2000 ppm** (0-2000 ppm): Higher resolution, suitable for indoor air quality\n- **5000 ppm** (0-5000 ppm): Balanced range for most applications\n- **10000 ppm** (0-10000 ppm): Maximum range for industrial applications\n\n```bash\nmhz14a --port /dev/mhz14a range --max 2000\nmhz14a --port /dev/mhz14a range --max 5000\nmhz14a --port /dev/mhz14a range --max 10000\n```\n\n## Python API Reference\n\n### MHZ14A Class\n\n```python\nclass MHZ14A:\n def __init__(self, port: str, timeout: float = 1.0) -> None:\n \"\"\"Initialize sensor with port and timeout.\"\"\"\n \n def read_co2(self) -> int:\n \"\"\"Read CO\u2082 concentration in ppm.\"\"\"\n \n def zero_calibrate(self) -> None:\n \"\"\"Perform zero point calibration (400 ppm fresh air).\"\"\"\n \n def span_calibrate(self, ppm: int) -> None:\n \"\"\"Perform span calibration with known concentration.\"\"\"\n \n def set_abc(self, enable: bool) -> None:\n \"\"\"Enable or disable Automatic Baseline Correction.\"\"\"\n \n def set_range(self, max_ppm: int) -> None:\n \"\"\"Set measurement range (2000, 5000, or 10000 ppm).\"\"\"\n```\n\n### Error Handling\n\nAll sensor operations can raise `MHZ14AError` exceptions:\n\n```python\nfrom mhz14a import MHZ14A, MHZ14AError\n\ntry:\n with MHZ14A('/dev/mhz14a') as sensor:\n ppm = sensor.read_co2()\n print(f\"CO\u2082: {ppm} ppm\")\nexcept MHZ14AError as e:\n print(f\"Sensor error: {e}\")\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\n- MH-Z14A sensor documentation and protocol specifications\n- Python serial communication community\n",
"bugtrack_url": null,
"license": null,
"summary": "Python library for MH-Z14A CO\u2082 sensor",
"version": "0.1.3",
"project_urls": {
"Documentation": "https://github.com/oaslananka/mhz14a-lib#readme",
"Homepage": "https://github.com/oaslananka/mhz14a-lib",
"Issues": "https://github.com/oaslananka/mhz14a-lib/issues",
"Repository": "https://github.com/oaslananka/mhz14a-lib.git"
},
"split_keywords": [
"co2",
" mhz14a",
" raspberry-pi",
" sensor",
" uart"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "1a6c29e361b4c519fefbbe00852cb2e34de451b59af4e492b8eaf3a66d8a754f",
"md5": "f10f0625c254c4eaf7d600ee9bff44a3",
"sha256": "d3b633401a464b4b52d21e37dec7ac52b412e603f1d95fdf6ff07d4757f41f1c"
},
"downloads": -1,
"filename": "mhz14a-0.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f10f0625c254c4eaf7d600ee9bff44a3",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 10026,
"upload_time": "2025-08-17T08:19:05",
"upload_time_iso_8601": "2025-08-17T08:19:05.487986Z",
"url": "https://files.pythonhosted.org/packages/1a/6c/29e361b4c519fefbbe00852cb2e34de451b59af4e492b8eaf3a66d8a754f/mhz14a-0.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f82c11764f7b699c6f7cbc6e17fb77cf3d7379c052568ec3b2f1d4139ac8d197",
"md5": "600a2e0ebb9a8af696932e397eecca08",
"sha256": "09ab7509e7abae6e599e502670ad6b64e7a1ededb38ccfbed98343965b046c39"
},
"downloads": -1,
"filename": "mhz14a-0.1.3.tar.gz",
"has_sig": false,
"md5_digest": "600a2e0ebb9a8af696932e397eecca08",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 15468,
"upload_time": "2025-08-17T08:19:07",
"upload_time_iso_8601": "2025-08-17T08:19:07.079439Z",
"url": "https://files.pythonhosted.org/packages/f8/2c/11764f7b699c6f7cbc6e17fb77cf3d7379c052568ec3b2f1d4139ac8d197/mhz14a-0.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-17 08:19:07",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "oaslananka",
"github_project": "mhz14a-lib#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "mhz14a"
}