0.1.0 ACD10

This commit is contained in:
Rob Tillaart 2023-10-05 13:57:37 +02:00
parent d06dc4dfcd
commit 392b865332
20 changed files with 1256 additions and 0 deletions

View File

@ -0,0 +1,30 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- uno
# - due
# - zero
# - leonardo
- m4
- esp32
- esp8266
# - mega2560
- rpipico
libraries:
- "printHelpers"

4
libraries/ACD10/.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,4 @@
# These are supported funding model platforms
github: RobTillaart

View File

@ -0,0 +1,13 @@
name: Arduino-lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update
compliance: strict

View File

@ -0,0 +1,17 @@
---
name: Arduino CI
on: [push, pull_request]
jobs:
runTest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- run: |
gem install arduino_ci
arduino_ci.rb

View File

@ -0,0 +1,18 @@
name: JSON check
on:
push:
paths:
- '**.json'
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:
pattern: "\\.json$"

360
libraries/ACD10/ACD10.cpp Normal file
View File

@ -0,0 +1,360 @@
//
// FILE: ACD10.cpp
// AUTHOR: Rob Tillaart
// DATE: 2023-09-25
// VERSION: 0.1.0
// PUPROSE: Arduino library for for I2C ACD10 CO2 sensor
// URL: https://github.com/RobTillaart/ACD10
// http://www.aosong.com/en/products-77.html
#include "ACD10.h"
ACD10::ACD10(TwoWire *wire)
{
_wire = wire;
_error = 0;
_lastRead = 0;
_concentration = 0;
_temperature = 0;
_start = millis();
}
#if defined (ESP8266) || defined(ESP32)
bool ACD10::begin(uint8_t sda, uint8_t scl)
{
_wire->begin(sda, scl);
if (! isConnected())
{
return false;
}
return true;
}
#endif
bool ACD10::begin()
{
_wire->begin();
if (! isConnected())
{
return false;
}
return true;
}
bool ACD10::isConnected()
{
_wire->beginTransmission(_address);
return (_wire->endTransmission() == 0);
}
uint8_t ACD10::getAddress()
{
return _address;
}
/////////////////////////////////////////////
//
// READ CO2
//
bool ACD10::preHeatDone()
{
return preHeatMillisLeft() == 0;
}
uint32_t ACD10::preHeatMillisLeft()
{
uint32_t delta = millis() - _start;
if (delta >= 120000UL) return 0;
return 120000UL - delta;
}
int ACD10::requestSensor()
{
uint8_t buf[2] = { 0x03, 0x00 };
_requestStart = millis();
return _command(buf, 2);
}
bool ACD10::requestReady()
{
if (_requestStart == 0) // no request pending.
{
return false;
}
return ((millis() - _requestStart) > _requestTime);
}
int ACD10::readSensor()
{
if (requestReady() == false)
{
return ACD10_NOT_READY;
}
uint8_t buf[10];
if (_request(buf, 9) != 0)
{
return ACD10_REQUEST_ERROR;
}
_requestStart = 0; // set no request pending.
// CRC CHECK
if (buf[2] != _crc8(&buf[0], 2))
{
// Serial.println("CRC error 1");
return ACD10_CRC_ERROR;
}
if (buf[5] != _crc8(&buf[3], 2))
{
// Serial.println("CRC error 2");
return ACD10_CRC_ERROR;
}
if (buf[8] != _crc8(&buf[6], 2))
{
// Serial.println("CRC error 3");
return ACD10_CRC_ERROR;
}
// DUMP
// for (int i = 0; i < 9; i++)
// {
// if (buf[i] < 16) Serial.print("0");
// Serial.print(buf[i], HEX);
// Serial.print(" ");
// }
// Serial.println();
_concentration = buf[0];
_concentration <<= 8;
_concentration += buf[1];
_concentration <<= 8;
_concentration += buf[3];
_concentration <<= 8;
_concentration += buf[4];
_temperature = buf[6] * 256 + buf[7];
_lastRead = millis();
return ACD10_OK;
}
uint32_t ACD10::getCO2Concentration()
{
return _concentration;
}
uint16_t ACD10::getTemperature()
{
return _temperature;
}
uint32_t ACD10::lastRead()
{
return _lastRead;
}
void ACD10::setRequestTime(uint8_t milliseconds)
{
_requestTime = milliseconds;
}
uint8_t ACD10::getRequestTime()
{
return _requestTime;
}
/////////////////////////////////////////////
//
// CALIBRATION
//
bool ACD10::setCalibrationMode(uint8_t mode)
{
if (mode > 1) return false;
uint8_t buf[5] = { 0x53, 0x06, 0x00, 0x00, 0x00 };
buf[3] = mode;
buf[4] = _crc8(&buf[2], 2);
// Serial.println(buf[4], HEX);
_command(buf, 5);
return true;
}
uint8_t ACD10::readCallibrationMode()
{
uint8_t buf[3] = { 0x53, 0x06, 0x00 };
_command(buf, 2);
_request(buf, 3);
// if (buf[2] != _crc8(&buf[0], 2))
// {
// Serial.print(__FUNCTION__);
// Serial.println(": CRC error");
// }
return buf[1];
}
bool ACD10::setManualCalibration(uint16_t value)
{
if ((value < 400) || (value > 5000)) return false;
uint8_t buf[5] = { 0x52, 0x04, 0x00, 0x00, 0x00 };
buf[3] = value && 0xFF;
buf[2] = value >> 8;
buf[4] = _crc8(&buf[2], 2);
_command(buf, 5);
return true;
}
uint16_t ACD10::readManualCalibration()
{
uint8_t buf[3] = { 0x52, 0x04, 0x00 };
_command(buf, 2);
_request(buf, 3);
// if (buf[2] != _crc8(&buf[0], 2))
// {
// Serial.print(__FUNCTION__);
// Serial.println(": CRC error");
// }
uint16_t value = buf[0] * 256 + buf[1];
return value;
}
/////////////////////////////////////////////
//
// MISC
//
void ACD10::factoryReset()
{
uint8_t buf[3] = { 0x52, 0x02, 0x00};
_command(buf, 3);
}
bool ACD10::readFactorySet()
{
uint8_t buf[3] = { 0x52, 0x02, 0x00 };
_command(buf, 2);
_request(buf, 3);
// if (buf[2] != _crc8(&buf[0], 2))
// {
// Serial.print(__FUNCTION__);
// Serial.println(": CRC error");
// }
return (buf[1] == 0x01);
}
void ACD10::readFirmwareVersion(char * arr)
{
uint8_t buf[2] = { 0xD1, 0x00 };
_command(buf, 2);
_request((uint8_t *) arr, 10);
arr[10] = '\0';
}
void ACD10::readSensorCode(char * arr)
{
uint8_t buf[2] = { 0xD2, 0x01 };
_command(buf, 2);
_request((uint8_t *) arr, 10);
arr[10] = '\0';
}
/////////////////////////////////////////////
//
// DEBUG
//
int ACD10::getLastError()
{
int e = _error;
_error = 0;
return e;
}
///////////////////////////////////////////////
//
// PRIVATE
//
int ACD10::_command(uint8_t * arr, uint8_t size)
{
_wire->beginTransmission(_address);
for (int i = 0; i < size; i++)
{
_wire->write(arr[i]);
}
_error = _wire->endTransmission();
return _error;
}
int ACD10::_request(uint8_t * arr, uint8_t size)
{
int bytes = _wire->requestFrom(_address, size);
if (bytes == 0)
{
_error = -1;
return _error;
}
if (bytes < size)
{
_error = -2;
return _error;
}
for (int i = 0; i < size; i++)
{
arr[i] = _wire->read();
}
_error = 0;
return _error;
}
uint8_t ACD10::_crc8(uint8_t * arr, uint8_t size)
{
uint8_t crc = 0xFF;
for (int b = 0; b < size; b++)
{
crc ^= arr[b];
for (int bit = 0x80; bit; bit >>= 1)
{
if (crc & 0x80)
{
crc <<= 1;
crc ^= 0x31;
}
else
{
crc <<= 1;
}
}
}
return crc;
}
// -- END OF FILE --

96
libraries/ACD10/ACD10.h Normal file
View File

@ -0,0 +1,96 @@
#pragma once
//
// FILE: ACD10.h
// AUTHOR: Rob Tillaart
// DATE: 2023-09-25
// VERSION: 0.1.0
// PUPROSE: Arduino library for for I2C ACD10 CO2 sensor
// URL: https://github.com/RobTillaart/ACD10
// http://www.aosong.com/en/products-77.html
#include "Arduino.h"
#include "Wire.h"
#define ACD10_LIB_VERSION (F("0.1.0"))
#define ACD10_DEFAULT_ADDRESS 0x2A
// ERROR CODES
// values <> 0 are errors.
#define ACD10_OK 0x00
#define ACD10_CRC_ERROR 0x01
#define ACD10_NOT_READY 0x10
#define ACD10_REQUEST_ERROR 0x11
class ACD10
{
public:
ACD10(TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
bool begin(uint8_t sda, uint8_t scl);
#endif
bool begin();
bool isConnected();
uint8_t getAddress();
// READ
bool preHeatDone();
uint32_t preHeatMillisLeft();
int requestSensor();
bool requestReady();
int readSensor();
uint32_t getCO2Concentration();
uint16_t getTemperature();
uint32_t lastRead();
void setRequestTime(uint8_t milliseconds = 80);
uint8_t getRequestTime();
// CALIBRATION
// 0 = manual 1 = auto
bool setCalibrationMode(uint8_t mode);
uint8_t readCallibrationMode();
bool setManualCalibration(uint16_t value);
uint16_t readManualCalibration();
// MISC
void factoryReset();
bool readFactorySet();
void readFirmwareVersion(char * arr); // should have length 11++
void readSensorCode(char * arr); // should have length 11++
// DEBUG
int getLastError();
private:
uint8_t _address = 0x2A;
TwoWire* _wire;
int _command(uint8_t * arr, uint8_t size);
int _request(uint8_t * arr, uint8_t size);
uint8_t _crc8(uint8_t * arr, uint8_t size);
uint32_t _start = 0;
uint32_t _lastRead = 0;
uint32_t _concentration = 0; // why datasheet states 32 bit as 400-5000 fit in 16 bit??
uint16_t _temperature = 0;
uint8_t _requestTime = 80;
uint32_t _requestStart = 0;
uint8_t _error;
};
// -- END OF FILE --

View File

@ -0,0 +1,14 @@
# Change Log ACD10
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.1.0] - 2023-09-25
- initial version

21
libraries/ACD10/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023-2023 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

260
libraries/ACD10/README.md Normal file
View File

@ -0,0 +1,260 @@
[![Arduino CI](https://github.com/RobTillaart/ACD10/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/ACD10/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/ACD10/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/ACD10/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/ACD10/actions/workflows/jsoncheck.yml)
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/ACD10.svg)](https://github.com/RobTillaart/ACD10/issues)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/ACD10/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/ACD10.svg?maxAge=3600)](https://github.com/RobTillaart/ACD10/releases)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/ACD10.svg)](https://registry.platformio.org/libraries/robtillaart/ACD10)
# ACD10
Arduino library for the ACD10 CO2 sensor (I2C).
## Description
**Experimental**
This library is to use the Aosong ACD10 CO2 sensor.
Besides CO2 concentration it also provides a temperature reading.
The sensor can be read over I2C and over Serial, however this library
only support the I2C interface.
The device has a fixed I2C address of 0x2A (42).
The CO2 concentration supported by the sensor has a range from 400 ~ 5000 ppm ±(50ppm + 5% reading).
This makes the sensor applicable for outdoor and indoor measurements in
a normal building setting. It is not suitable for CO2 heavy "industrial" environments.
When the sensor starts up it has a pre-heat period of 120 seconds.
The library provides functions to check the time since the constructor is called,
but note that this not necessarily implies the sensor is ON.
During the preheat period one can make measurements but one should use those
carefully as these are less accurate than after the preheat period.
Also important is the calibration of the sensor, although done in the factory,
a CO2 sensor needs regular calibration. See datasheet for details.
The temperature range it can measure is: **TODO UNKNOWN YET**
The sensor must be powered with 5V and usese about 225 mW.
This implies it uses 50 mA and needs a separate power supply. (Do not forget to connect GND.)
The I2C communication supports 3-5V so any 3.3V MCU should be able to connect.
(Do not forget pull up resistors).
#### Datasheet warning
Do not apply this product to safety protection devices or emergency stop equipment, and any other
applications that may cause personal injury due to the product's failure.
#### Operating conditions
- temperature: 0°C~ +50°C ==> so keep away from freezing cold or direct sunlight.
- humidity: 0% ~ 95% RH ==> non-condensing conditions.
- Data refresh frequency: 2 seconds
#### Hardware
```
TOPVIEW ACD10
+--------------------+
pin 6 | o |
pin 5 | o o | pin 1
| o | pin 2
| o | pin 3
| o | pin 4
| |
+--------------------+
```
| pin | name | description | Notes |
|:-----:|:--------:|:------------------|:-------:|
| 1 | SDA/RX | I2C data | 3-5V
| 2 | SCL/TX | I2C clock | 3-5V
| 3 | GND | Ground |
| 4 | VCC | Power +5V |
| 5 | SET | select com mode | HIGH (or nc) => I2C, LOW => Serial
| 6 | - | not connected |
If pin 5 is not connected, the default (HIGH) is to select I2C.
If pin 5 is connected to GND, Serial / UART mode is selected.
This latter mode is **NOT** supported by this library.
#### Related
- https://emariete.com/en/sensor-co2-mh-z19b/
- https://emariete.com/en/sensor-co2-low-consumption-mh-z1311a-winsen/
- https://revspace.nl/MHZ19
- https://www.co2.earth/ - current outdoor CO2 level can be used for calibrating.
- https://keelingcurve.ucsd.edu/ - historical outdoor CO2 level.
- https://github.com/RobTillaart/MTP40C
- https://github.com/RobTillaart/MTP40F
- https://github.com/RobTillaart/Cozir
#### Tested
TODO: Test on Arduino UNO and ESP32 ?
## I2C
The device has a fixed I2C address of 0x2A (42).
The I2C communication supports 3-5V so any 3.3V - 5.0V MCU should be able to connect.
Do not forget pull up resistors on SDA and SCL lines.
#### Multiple sensors.
The ACD10 sensor has a fixed I2C address 0x2A (42) so only
one sensor per I2C bus can be used.
If one needs more sensors there are some options.
- One could use an I2C multiplexer - https://github.com/RobTillaart/TCA9548 (I2C 8 channel multiplexer)
- One could use an MCU with multiple I2C buses.
- One could use a Two-Wire compatible SW I2C (outside scope of this library).
Using the VCC as a Chip Select is not advised as the ACD10
has a preheat time of 2 minutes.
#### Performance I2C
Only test **readSensor()** as that is the main function.
| Clock | time (us) | Notes |
|:----------:|:-----------:|:--------|
| 100 KHz | | default
| 200 KHz | |
| 300 KHz | |
| 400 KHz | |
| 500 KHz | |
| 600 KHz | |
TODO: run performance sketch.
## Interface
```cpp
#include "ACD10.h"
```
#### Constructor
- **ACD10(uint8_t address = ACD10_DEFAULT_ADDRESS, TwoWire \*wire = &Wire)**
- **bool begin(uint8_t sda, uint8_t scl)** (ESP32) initializes I2C,
and checks if device is visible on the I2C bus.
- **bool begin()** initializes I2C, and checks if device is visible on the I2C bus.
- **bool isConnected()** Checks if device address can be found on I2C bus.
- **uint8_t getAddress()** Returns address set in the constructor.
#### PreHeat
PreHeat functions assume the sensor is (and stays) connected to power.
- **bool preHeatDone()** returns true 120 seconds after constructor is called.
- **uint32_t preHeatMillisLeft()** returns the time in milliseconds
left before preHeat is complete.
#### Request and Read
The interface of the sensor is made asynchronous as there is a delay needed
of around 80 milliseconds between a request for new data and the availability
of that new data.
- **int requestSensor()** request a new measurement / data.
This must be called before the sensor can be read by **readSensor()**
- **bool requestReady()** has enough time passed since the call to **requestSensor()**
for the acquisition to happen and to call **readSensor()**?
- **int readSensor()** read the values from the sensor.
Returns status, 0 == OK, other values are error-codes.
- **uint32_t getCO2Concentration()** get the last read CO2 measurement in
PPM from the device.
Multiple calls will give the same value until new measurement is made.
- **uint16_t getTemperature()** get the last read temperature from the device.
Multiple calls will give the same value until new measurement is made.
- **uint32_t lastRead()** returns the moment of last **readSensor()** in milliseconds
since start.
Note the sensor can be read only once every two seconds, less often is better.
- **void setRequestTime(uint8_t milliseconds = 80)** set the time to make a measurement.
Default = 80 milliseconds.
This can be used to tweak / optimize performance a bit.
Use 5~10 milliseconds above the minimal value the sensor still works.
- **uint8_t getRequestTime()** returns the current request time in milliseconds.
#### Calibration
Read the datasheet about calibration process (twice).
Incorrect calibration leads to incorrect output.
- **bool setCalibrationMode(uint8_t mode)** 0 = manual mode, 1 = automatic mode.
returns false if mode out of range.
- **uint8_t readCallibrationMode()** return set mode.
- **void setManualCalibration(uint16_t value)** as the range of the device is
from 400 to 5000, the parameter value should be in this range.
- **uint16_t readManualCalibration()** read back the set manual calibration value.
Note: One should wait 5 milliseconds between the calibration calls (see datasheet).
#### Miscellaneous
- **void factoryReset()** idem.
- **bool readFactorySet()** Read back if factory reset was successful.
- **uint32_t readFirmwareVersion(char \* arr)** copies firmware version in array.
Minimum length is 11.
- **uint32_t readSensorCode(char \* arr)** copies sensor code in array.
Minimum length is 11.
#### Debug
- **uint8_t getLastError()** returns last error of low level communication.
## Future
#### Must
- improve documentation
- get hardware to test
#### Should
- investigate the acquisition time of 80 milliseconds
- can it be made shorter by default?
- improve error handling
#### Could
- rethink function names?
- create unit tests if possible
#### Wont
## Support
If you appreciate my libraries, you can support the development and maintenance.
Improve the quality of the libraries by providing issues and Pull Requests, or
donate through PayPal or GitHub sponsors.
Thank you,

View File

@ -0,0 +1,41 @@
//
// FILE: ACD10_demo.ino
// AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance
#include "Wire.h"
#include "ACD10.h"
ACD10 mySensor;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("ACD10_LIB_VERSION: ");
Serial.println(ACD10_LIB_VERSION);
Wire.begin();
mySensor.begin();
}
void loop()
{
mySensor.requestSensor();
while (mySensor.requestReady() == false) delay(10);
mySensor.readSensor();
Serial.print(mySensor.getCO2Concentration());
Serial.print("\t");
Serial.print(mySensor.getTemperature());
Serial.println();
delay(2000);
}
// -- END OF FILE --

View File

@ -0,0 +1,35 @@
//
// FILE: ACD10_isConnected.ino
// AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance
#include "Wire.h"
#include "ACD10.h"
ACD10 mySensor;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("ACD10_LIB_VERSION: ");
Serial.println(ACD10_LIB_VERSION);
Wire.begin();
mySensor.begin();
}
void loop()
{
Serial.println(mySensor.isConnected());
Serial.println(mySensor.getAddress());
delay(1000);
}
// -- END OF FILE --

View File

@ -0,0 +1,43 @@
//
// FILE: ACD10_preheat_test.ino
// AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance
#include "Wire.h"
#include "ACD10.h"
ACD10 mySensor;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("ACD10_LIB_VERSION: ");
Serial.println(ACD10_LIB_VERSION);
Wire.begin();
mySensor.begin();
}
void loop()
{
Serial.print(millis() / 1000);
if (mySensor.preHeatDone())
{
Serial.println("\tOK");
}
else
{
Serial.print("\tWarming up\t");
Serial.println(mySensor.preHeatMillisLeft());
}
delay(5000);
}
// -- END OF FILE --

View File

@ -0,0 +1,50 @@
//
// FILE: ACD10_readSensor.ino
// AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance
#include "Wire.h"
#include "ACD10.h"
ACD10 mySensor;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("ACD10_LIB_VERSION: ");
Serial.println(ACD10_LIB_VERSION);
Wire.begin();
mySensor.begin();
}
void loop()
{
// prepare a request every 5 seconds.
if (millis() - mySensor.lastRead() > 5000) // millis
{
mySensor.requestSensor();
}
// if request has had enough time read the sensor.
if (mySensor.requestReady())
{
mySensor.readSensor();
Serial.print(mySensor.getCO2Concentration());
Serial.print("\t");
Serial.print(mySensor.getTemperature());
Serial.println();
}
// do other things here.
delay(1000);
}
// -- END OF FILE --

View File

@ -0,0 +1,42 @@
//
// FILE: ACD10_readSensorCode.ino
// AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance
#include "Wire.h"
#include "ACD10.h"
ACD10 mySensor;
char FWversion[12];
char sensorCode[12];
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("ACD10_LIB_VERSION: ");
Serial.println(ACD10_LIB_VERSION);
Wire.begin();
mySensor.begin();
mySensor.readFirmwareVersion(&FWversion[0]);
Serial.print("FIRMWARE: \t");
Serial.println(FWversion);
mySensor.readSensorCode(&sensorCode[0]);
Serial.print("SENSORCODE: \t");
Serial.println(sensorCode);
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,71 @@
//
// FILE: ACD10_readSensor_performance.ino
// AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance
#include "Wire.h"
#include "ACD10.h"
ACD10 mySensor;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("ACD10_LIB_VERSION: ");
Serial.println(ACD10_LIB_VERSION);
Wire.begin();
mySensor.begin();
test(100000);
test(200000);
test(300000);
test(400000);
test(500000);
test(600000);
test(700000);
test(800000);
Serial.println("\ndone...");
}
void loop()
{
}
void test(uint32_t speed)
{
Wire.setClock(speed);
delay(100);
uint32_t start = micros();
mySensor.requestSensor();
uint32_t duration1 = micros() - start;
while(mySensor.requestReady() == false) delay(10);
start = micros();
mySensor.readSensor();
uint32_t duration2 = micros() - start;
Serial.print("| ");
Serial.print(speed);
Serial.print(" | ");
Serial.print(duration1);
Serial.print(" | ");
Serial.print(duration2);
Serial.print(" |");
Serial.println();
// reset I2C bus
Wire.setClock(100000);
}
// -- END OF FILE --

View File

@ -0,0 +1,41 @@
# Syntax Colouring Map For ACD10
# Data types (KEYWORD1)
ACD10 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
isConnected KEYWORD2
getAddress KEYWORD2
preHeatDone KEYWORD2
preHeatMillisLeft KEYWORD2
requestSensor KEYWORD2
requestReady KEYWORD2
readSensor KEYWORD2
getCO2Concentration KEYWORD2
getTemperature KEYWORD2
lastRead KEYWORD2
setRequestTime KEYWORD2
getRequestTime KEYWORD2
setCalibrationMode KEYWORD2
readCallibrationMode KEYWORD2
setManualCalibration KEYWORD2
readManualCalibration KEYWORD2
factoryReset KEYWORD2
readFactorySet KEYWORD2
readFirmwareVersion KEYWORD2
readSensorCode KEYWORD2
getLastError KEYWORD2
# Constants (LITERAL1)
ACD10_LIB_VERSION LITERAL1

View File

@ -0,0 +1,23 @@
{
"name": "ACD10",
"keywords": "CO2,environment",
"description": "Arduino library for the ACD10 CO2 sensor.",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/ACD10.git"
},
"version": "0.1.0",
"license": "MIT",
"frameworks": "*",
"platforms": "*",
"headers": "ACD10.h"
}

View File

@ -0,0 +1,11 @@
name=ACD10
version=0.1.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for the ACD10 CO2 sensor.
paragraph=
category=Sensors
url=https://github.com/RobTillaart/ACD10
architectures=*
includes=ACD10.h
depends=

View File

@ -0,0 +1,66 @@
//
// FILE: unit_test_001.cpp
// AUTHOR: Rob Tillaart
// DATE: 2023-09-25
// PURPOSE: unit tests for the ACD10 library
// https://github.com/RobTillaart/ACD10
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
//
// supported assertions
// https://github.com/Arduino-CI/arduino_ci/blob/master/cpp/unittest/Assertion.h#L33-L42
// ----------------------------
// assertEqual(expected, actual)
// assertNotEqual(expected, actual)
// assertLess(expected, actual)
// assertMore(expected, actual)
// assertLessOrEqual(expected, actual)
// assertMoreOrEqual(expected, actual)
// assertTrue(actual)
// assertFalse(actual)
// assertNull(actual)
// assertNotNull(actual)
#include <ArduinoUnitTests.h>
#include "Arduino.h"
#include "ACD10.h"
unittest_setup()
{
fprintf(stderr, "ACD10_LIB_VERSION: %s\n", (char *) ACD10_LIB_VERSION);
}
unittest_teardown()
{
}
unittest(test_constants)
{
assertEqual(ACD10_DEFAULT_ADDRESS, 0x2A);
}
unittest(test_constructor)
{
ACD10 acd;
assertEqual(acd.getAddress(), ACD10_DEFAULT_ADDRESS);
assertEqual(acd.getRequestTime(), 80);
assertEqual(acd.getLastError(), 0);
assertEqual(acd.lastRead(), 0);
assertEqual(acd.getCO2Concentration(), 0);
assertEqual(acd.getTemperature(), 0);
}
unittest_main()
// -- END OF FILE --