{"id":20989843,"url":"https://github.com/robtillaart/mtp40c","last_synced_at":"2025-05-14T18:32:14.178Z","repository":{"id":45309948,"uuid":"398756031","full_name":"RobTillaart/MTP40C","owner":"RobTillaart","description":"Arduino library for MTP40C CO2 + air pressure sensor","archived":false,"fork":false,"pushed_at":"2024-04-13T09:08:10.000Z","size":48,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-08-07T18:27:16.594Z","etag":null,"topics":["arduino","co2","sensor"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RobTillaart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"RobTillaart"}},"created_at":"2021-08-22T08:59:47.000Z","updated_at":"2024-01-14T12:46:21.000Z","dependencies_parsed_at":"2023-11-14T16:43:40.760Z","dependency_job_id":null,"html_url":"https://github.com/RobTillaart/MTP40C","commit_stats":{"total_commits":15,"total_committers":2,"mean_commits":7.5,"dds":0.06666666666666665,"last_synced_commit":"eccba08d99b759ced518debeabceb2fffa3eb428"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMTP40C","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMTP40C/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMTP40C/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMTP40C/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobTillaart","download_url":"https://codeload.github.com/RobTillaart/MTP40C/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225305714,"owners_count":17453436,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","co2","sensor"],"created_at":"2024-11-19T06:26:23.013Z","updated_at":"2024-11-19T06:26:23.708Z","avatar_url":"https://github.com/RobTillaart.png","language":"C++","funding_links":["https://github.com/sponsors/RobTillaart"],"categories":[],"sub_categories":[],"readme":"\n[![Arduino CI](https://github.com/RobTillaart/MTP40C/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)\n[![Arduino-lint](https://github.com/RobTillaart/MTP40C/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/MTP40C/actions/workflows/arduino-lint.yml)\n[![JSON check](https://github.com/RobTillaart/MTP40C/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/MTP40C/actions/workflows/jsoncheck.yml)\n[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/MTP40C.svg)](https://github.com/RobTillaart/MTP40C/issues)\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/MTP40C/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/RobTillaart/MTP40C.svg?maxAge=3600)](https://github.com/RobTillaart/MTP40C/releases)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/MTP40C.svg)](https://registry.platformio.org/libraries/robtillaart/MTP40C)\n\n\n# MTP40C / MTP40D\n\nArduino library for MTP40C and MTP40D CO2 sensor.\n\n(include image)\n\n\n## Description\n\nThe library for the MTP40C / MTP40D CO2 sensor is experimental as not all functionality is tested.\n\nBoth the MTP40C and MTP40D sensor is an NDIR (Non Dispersive InfraRed) CO2 sensor.\n\nThe sensor communicates over a 19200 baud serial (TTL) interface with a microprocessor or PC. \nThis implies that calls which can take up to 25 bytes can take as much as about 20 milliseconds.\n\nOn the other hand this low baud rate implies it will work over relative long distances.\nThis signal quality over longer distances is not investigated. \n\nThe MTP40D has more interface options, I2C, PWM and ALARM. \nThis library does not support these other interfaces for now.\nHowever minimal examples are added to have a starter but these \nneed to be tested if and how well these work.\n\n\n### Hardware interface\n\n\n#### MTP40-C\n\nHas no I2C, only TTL level RS232.\n\n```\n               TOPVIEW MTP40-C\n              +-------------+---+\n              |             | O |\n    Vin   1 --|             +---+\n    GND   2 --|             |\n    TX    3 --|             |\n    RX    4 --|             |\n    NC    5 --|             +---+\n              |             | O |\n              +-------------+---+\n```\n\n| Pin  | Name  | Description         |\n|:----:|:------|:--------------------|\n|  1   | Vin   | 4.2V--5.5V          |\n|  2   | GND   | idem                |\n|  3   | TX    | Transmit 19200 baud |\n|  4   | RX    | Receive 19200 baud  |\n|  5   | NC    | Not Connected       |\n\n\n#### MTP40-D\n\nHas TTL level RS232, I2C and PWM IO.\n\n```\n               TOPVIEW MTP40-D\n              +-------------+\n              |             | \n    VCC   5 --|             |-- 1 Vin\n    TX    6 --|             |-- 2 GND\n    RX    7 --|             |-- 3 ALARM\n    NC    8 --|             |-- 4 PWM / I2C\n    GND   9 --|             |\n              |             |\n              +-------------+\n```\n\n| Pin  | Name    | Description                 |\n|:----:|:--------|:----------------------------|\n|  1   | Vin     | 4.2V--5.5V                  |\n|  2   | GND     | idem                        |\n|  3   | ALARM   | HIGH above 2000 PPM, LOW below 1800 PPM (hysteresis) |\n|  4   | PWM/I2C | PWM out or I2C select       |\n|  5   | VCC_O   | 3V3 out for serial          |\n|  6   | TX      | Transmit 19200 baud or SDA  |\n|  7   | RX      | Receive 19200 baud or SCL   |\n|  8   | NC      | Not Connected               |\n|  9   | GND     | idem                        |\n\n\n#### Related\n\n- https://www.co2.earth/ - current outdoor CO2 level can be used for calibrating.\n- https://keelingcurve.ucsd.edu/ - historical outdoor CO2 level.\n- https://github.com/RobTillaart/MTP40F\n- https://github.com/RobTillaart/MHZCO2  MHZ19 series\n- https://github.com/RobTillaart/Cozir\n\n\n## Interface\n\n```cpp\n#include \"MTP40C.h\"\n```\n\n#### Warnings\n\nDuring tests with an UNO the communication over Software Serial did fail sometimes.\nTherefore it is important to **always check return values** to make your project more robust.\n\nDuring tests it became clear that the sensor needs time to process \ncommands e.g. **setSelfCalibration()**. By having a delay(100) between the calls\neverything ran far more stable (within my test). Todo seek optimum delay(), added in Future section below.\n\nThe CRC of the sensor responses are not verified by the library.\n\n\n#### Constructors\n\n- **MTP40(Stream \\* str)** constructor. should get a Serial port as parameter e.g. \\\u0026Serial, \\\u0026Serial1. This is the base class.\n- **MTP40C(Stream \\* str)** constructor. should get a Serial port as parameter e.g. \\\u0026Serial, \\\u0026Serial1 \nor a software Serial port. That Serial port must connect to the sensor. \n- **MTP40D(Stream \\* str)** constructor. should get a Serial port as parameter e.g. \\\u0026Serial, \\\u0026Serial1 \nor a software Serial port. That Serial port must connect to the sensor. \n- **bool begin(uint8_t address = 0x64)** initialize the device.\nSets the address to communicate to the sensor. Address values allowed 0 .. 247.\nUses the factory default value of 0x64 when no parameter is given.\nAlso resets internal settings.\n- **bool isConnected()** returns true if the address as set by **begin()** \nor the default address of 0x64 (decimal 100) can be found on the Serial 'bus'.\n- **uint8_t getType()** returns type, see below.\nReturn 255 for the MTP40 base class.\n\n|  Type  |  Model   |  Notes   |\n|:------:|:--------:|:--------:|\n|   2    |  MTP40C  |\n|   3    |  MTP40D  |\n|  255   |  MTP40   |  base class\n\n\n#### CO2 Measurement\n\n- **uint16_t getGasConcentration()** returns the CO2 concentration in PPM (parts per million).\nThe function returns **MTP40_INVALID_GAS_LEVEL** if the request fails.\n\n- **void suppressError(bool se)** sets or clears a flag that replaces the error value with \nthe last read value if the request fails.\nThis is useful when plotting the values and one do not want a sudden spike.\nOne can still check **lastError()** to see if the value was OK.\n- **bool getSuppressError()** gets the value of the suppress flag. \n- **int lastError()** returns last error set by **getGasConcentration()** \nor by **getAirPressureReference()** \nReading resets internal error to MTP40_OK;\n\n\n#### Configuration\n\n- **uint8_t getAddress()** request the address from the device.\nExpect a value from 0 .. 247.\nReturns **MTP40_INVALID_ADDRESS** (0xFF) if the request fails.\n- **bool setAddress(uint8_t address = 0x64)** set a new address for the device. \n0x64 as default. Returns false if not successful. \nIf **setSpecificAddress()** is called, this specific address will be used for further commands.\n\nThese address functions are only needed if handling multiple devices. (to be tested)\n- **void setGenericAddress()** uses the broadcast address 0xFE in all requests. \nThis is the default behaviour of the library.\n- **void setSpecificAddress()** uses the address specified in **begin()** or \n**setAddress()** or the default 0x64 in all requests.\n- **bool useSpecificAddress()** returns true if the specific address is used.\nReturns false if the generic / broadcast address is used.\n\nThe library can set a maximum timeout in the communication with the sensor.\nNormally this is not needed to set as the default of 100 milliseconds is long enough\nfor even the longest command. This timeout is needed if the sensor did not read the \ncommand correctly, preventing the host to wait indefinitely.\n- **void setTimeout(uint32_t to = 100)** sets the timeout. \nIf no parameter is given a default timeout of 100 milliseconds is set.\n- **uint32_t getTimeout()** get the value set above or the default. \nValue returned is time in milliseconds.\n\n\n## Calibration\n\nPlease read datasheet before using these functions to understand the process of calibration.\n\nNote the outdoor calibration CO2 level differs per day and one should check \na local airport or weather station for a good reference.\n\nThe University of San Diego keeps track of CO2 for a long time now.\nSee - https://keelingcurve.ucsd.edu/ \n\n\n#### Air pressure calibration\n\n- **float getAirPressureReference()** returns the air pressure reference from the device.\nReturns **MTP40_INVALID_AIR_PRESSURE** in case request fails.\nDefault is 1013.0.\n- **bool setAirPressureReference(float apr)** to calibrate the air pressure.\nOne can calibrate the sensor with an external device.\nValue for air pressure should between 700.0 and 1100.0. \nThe function returns **false** if the parameter is out of range or if the request fails.\n\n\n#### SPC calibration\n\nThis takes a relative short time (few minutes) to calibrate the sensor in a known \ngas concentration. \n\n- **bool setSinglePointCorrection(float spc)** takes several minutes. see datasheet.\nspc should be between 400 and 5000.\nThe function returns **false** if the parameter is out of range or if the request fails.\n- **bool getSinglePointCorrectionReady()** To see if SPC is finished or not. The call also fails if the request fails.\n\nAs far as known the SPC point can not be retrieved from the sensor.\n\n\n#### Self calibration\n\nSelf calibration is a process in which the sensor takes the minimum values over a longer period\nbetween 24 - 720 hours as the reference for minimum outdoor values.\nNote that 720 hours is 30 days / 1 month.\n\n- **bool openSelfCalibration()** start the self calibration cycle.\n- **bool closeSelfCalibration()** stop the self calibration cycle.\n- **uint8_t getSelfCalibrationStatus()** Returns if the selfCalibration is open or closed.\n**WARNING**: in our test the values in the datasheet seems to be not in sync with the sensor used. \nThe function returned **0x00 for CLOSED and 0xFF for OPEN**.\n- **bool setSelfCalibrationHours(uint16_t hrs)** Sets the number of hours between self calibration\nmoments. Valid values are 24 - 720 .\n- **uint16_t getSelfCalibrationHours()** returns the value set above.\n\n\n## Future\n\n#### Must\n\n- documentation\n\n#### Should\n\n- CRC verify responses from sensor\n- improve readability code (e.g. parameter names)\n- move code from .h to .cpp file\n\n#### Could\n\n- performance measurements\n- optimize performance\n  - caching? what?\n  - seek optimum delay() between calls.\n- reuse cmd buffer as response buffer?\n- investigate wire length\n- investigate serial bus with multiple devices? \n  - diodes\n  - multiplexer\n- investigate commands in PROGMEM?\n\n#### Wont (unless on request)\n\n\n## Sponsor \n\nThe development of this MTP40C library is sponsored by [TinyTronics, Netherlands](https://www.tinytronics.nl/shop/nl).\n\n\n## Support\n\nIf you appreciate my libraries, you can support the development and maintenance.\nImprove the quality of the libraries by providing issues and Pull Requests, or\ndonate through PayPal or GitHub sponsors.\n\nThank you,\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fmtp40c","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobtillaart%2Fmtp40c","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fmtp40c/lists"}