0.1.3 ACD10

This commit is contained in:
Rob Tillaart 2024-01-01 20:25:27 +01:00
parent 3c330e8f73
commit 2db5f197b6
17 changed files with 198 additions and 63 deletions

View File

@ -2,8 +2,8 @@
// FILE: ACD10.cpp // FILE: ACD10.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// DATE: 2023-09-25 // DATE: 2023-09-25
// VERSION: 0.1.2 // VERSION: 0.1.3
// PUPROSE: Arduino library for for I2C ACD10 CO2 sensor // PURPOSE: Arduino library for for I2C ACD10 CO2 sensor
// URL: https://github.com/RobTillaart/ACD10 // URL: https://github.com/RobTillaart/ACD10
// http://www.aosong.com/en/products-77.html // http://www.aosong.com/en/products-77.html
@ -19,6 +19,8 @@ ACD10::ACD10(TwoWire *wire)
_concentration = 0; _concentration = 0;
_temperature = 0; _temperature = 0;
_preHeatStart = millis(); _preHeatStart = millis();
_requestTime = 80;
_requestStart = 0;
} }
@ -29,6 +31,9 @@ bool ACD10::begin()
_lastRead = 0; _lastRead = 0;
_concentration = 0; _concentration = 0;
_temperature = 0; _temperature = 0;
_requestTime = 80;
_requestStart = 0;
if (! isConnected()) if (! isConnected())
{ {
return false; return false;
@ -292,7 +297,7 @@ int ACD10::getLastError()
int ACD10::_command(uint8_t * arr, uint8_t size) int ACD10::_command(uint8_t * arr, uint8_t size)
{ {
_wire->beginTransmission(_address); _wire->beginTransmission(_address);
for (int i = 0; i < size; i++) for (uint8_t i = 0; i < size; i++)
{ {
_wire->write(arr[i]); _wire->write(arr[i]);
} }
@ -303,7 +308,7 @@ int ACD10::_command(uint8_t * arr, uint8_t size)
int ACD10::_request(uint8_t * arr, uint8_t size) int ACD10::_request(uint8_t * arr, uint8_t size)
{ {
int bytes = _wire->requestFrom(_address, size); uint8_t bytes = _wire->requestFrom(_address, size);
if (bytes == 0) if (bytes == 0)
{ {
_error = -1; _error = -1;
@ -315,7 +320,7 @@ int ACD10::_request(uint8_t * arr, uint8_t size)
return _error; return _error;
} }
for (int i = 0; i < size; i++) for (uint8_t i = 0; i < size; i++)
{ {
arr[i] = _wire->read(); arr[i] = _wire->read();
} }
@ -327,10 +332,10 @@ int ACD10::_request(uint8_t * arr, uint8_t size)
uint8_t ACD10::_crc8(uint8_t * arr, uint8_t size) uint8_t ACD10::_crc8(uint8_t * arr, uint8_t size)
{ {
uint8_t crc = 0xFF; uint8_t crc = 0xFF;
for (int b = 0; b < size; b++) for (uint8_t b = 0; b < size; b++)
{ {
crc ^= arr[b]; crc ^= arr[b];
for (int bit = 0x80; bit; bit >>= 1) for (uint8_t bit = 0x80; bit; bit >>= 1)
{ {
if (crc & 0x80) if (crc & 0x80)
{ {

View File

@ -3,8 +3,8 @@
// FILE: ACD10.h // FILE: ACD10.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// DATE: 2023-09-25 // DATE: 2023-09-25
// VERSION: 0.1.2 // VERSION: 0.1.3
// PUPROSE: Arduino library for for I2C ACD10 CO2 sensor // PURPOSE: Arduino library for for I2C ACD10 CO2 sensor
// URL: https://github.com/RobTillaart/ACD10 // URL: https://github.com/RobTillaart/ACD10
// http://www.aosong.com/en/products-77.html // http://www.aosong.com/en/products-77.html
@ -13,7 +13,7 @@
#include "Wire.h" #include "Wire.h"
#define ACD10_LIB_VERSION (F("0.1.2")) #define ACD10_LIB_VERSION (F("0.1.3"))
#define ACD10_DEFAULT_ADDRESS 0x2A #define ACD10_DEFAULT_ADDRESS 0x2A
// ERROR CODES // ERROR CODES
@ -76,12 +76,12 @@ private:
int _request(uint8_t * arr, uint8_t size); int _request(uint8_t * arr, uint8_t size);
uint8_t _crc8(uint8_t * arr, uint8_t size); uint8_t _crc8(uint8_t * arr, uint8_t size);
uint32_t _preHeatStart = 0; uint32_t _preHeatStart;
uint32_t _lastRead = 0; uint32_t _lastRead;
uint32_t _concentration = 0; // why datasheet states 32 bit as 400-5000 fit in 16 bit?? uint32_t _concentration; // why datasheet states 32 bit as 400-5000 fit in 16 bit??
uint16_t _temperature = 0; uint16_t _temperature;
uint8_t _requestTime = 80; uint8_t _requestTime;
uint32_t _requestStart = 0; uint32_t _requestStart;
uint8_t _error; uint8_t _error;
}; };

View File

@ -6,12 +6,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.1.3] - 2024-01-01
- fix examples
- add multiplex demo
- update readme.md
- minor edits
## [0.1.2] - 2023-11-23 ## [0.1.2] - 2023-11-23
- add temperature disclaimer in readme.md. - add temperature disclaimer in readme.md.
- update keywords.txt - update keywords.txt
- minor edits - minor edits
## [0.1.1] - 2023-10-05 ## [0.1.1] - 2023-10-05
- refactor **begin()** - refactor **begin()**
- add **ACD10_readSensor_wire1.ino** ESP32 et al. - add **ACD10_readSensor_wire1.ino** ESP32 et al.

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2023-2023 Rob Tillaart Copyright (c) 2023-2024 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -27,7 +27,7 @@ a normal building setting.
The sensor is not suitable for CO2 heavy "industrial" environments. The sensor is not suitable for CO2 heavy "industrial" environments.
**Warning** The temperature range the sensor can measure is **UNKNOWN** **Warning** The temperature range the sensor can measure is **UNKNOWN**
as there is no documentation how to convert the raw data to meaningfull one. as there is no documentation how to convert the raw data to meaningful one.
#### Pre-heat period #### Pre-heat period
@ -60,6 +60,11 @@ The device has a fixed I2C address of 0x2A (42).
The I2C communication supports 3-5V so any 3.3V MCU should be able to connect. The I2C communication supports 3-5V so any 3.3V MCU should be able to connect.
Do not forget appropriate pull up resistors on the I2C SDA and SCL lines. Do not forget appropriate pull up resistors on the I2C SDA and SCL lines.
If you need to control more ACD10 sensors you can use a multiplexer e.g. TCA9548
- https://github.com/RobTillaart/TCA9548
See example **TCA9548_demo_ACD10.ino**
#### Datasheet warning #### Datasheet warning
@ -216,7 +221,7 @@ Read the datasheet about calibration process (twice).
Incorrect calibration leads to incorrect output. Incorrect calibration leads to incorrect output.
- **bool setCalibrationMode(uint8_t mode)** 0 = manual mode, 1 = automatic mode. - **bool setCalibrationMode(uint8_t mode)** 0 = manual mode, 1 = automatic mode.
returns false if mode out of range ( > 1). Returns false if mode out of range ( > 1).
- **uint8_t readCallibrationMode()** return set mode. - **uint8_t readCallibrationMode()** return set mode.
- **void setManualCalibration(uint16_t value)** as the range of the device is - **void setManualCalibration(uint16_t value)** as the range of the device is
from 400 to 5000, the parameter value should be in this range. from 400 to 5000, the parameter value should be in this range.
@ -247,20 +252,17 @@ Minimum length is 11.
- improve documentation - improve documentation
- get hardware to test - get hardware to test
#### Should #### Should
- investigate the acquisition time of 80 milliseconds - investigate the acquisition time of 80 milliseconds
- can it be made shorter by default? - can it be made shorter by default?
- improve error handling - improve error handling
#### Could #### Could
- rethink function names? - rethink function names?
- create unit tests if possible - create unit tests if possible
#### Wont #### Wont

View File

@ -1,7 +1,8 @@
// //
// FILE: ACD10_demo.ino // FILE: ACD10_demo.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance // PURPOSE: test basic behaviour and performance
// URL: https://github.com/RobTillaart/ACD10
#include "Wire.h" #include "Wire.h"

View File

@ -1,7 +1,8 @@
// //
// FILE: ACD10_isConnected.ino // FILE: ACD10_isConnected.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance // PURPOSE: test basic behaviour and performance
// URL: https://github.com/RobTillaart/ACD10
#include "Wire.h" #include "Wire.h"

View File

@ -1,7 +1,8 @@
// //
// FILE: ACD10_preheat_test.ino // FILE: ACD10_preheat_test.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance // PURPOSE: test basic behaviour and performance
// URL: https://github.com/RobTillaart/ACD10
#include "Wire.h" #include "Wire.h"

View File

@ -1,8 +1,8 @@
// //
// FILE: ACD10_readSensor.ino // FILE: ACD10_readSensor.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance // PURPOSE: test basic behaviour and performance
// URL: https://github.com/RobTillaart/ACD10
#include "Wire.h" #include "Wire.h"
#include "ACD10.h" #include "ACD10.h"

View File

@ -1,7 +1,8 @@
// //
// FILE: ACD10_readSensorCode.ino // FILE: ACD10_readSensorCode.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance // PURPOSE: test basic behaviour and performance
// URL: https://github.com/RobTillaart/ACD10
#include "Wire.h" #include "Wire.h"

View File

@ -1,7 +1,8 @@
// //
// FILE: ACD10_readSensor_performance.ino // FILE: ACD10_readSensor_performance.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance // PURPOSE: test basic behaviour and performance
// URL: https://github.com/RobTillaart/ACD10
#include "Wire.h" #include "Wire.h"
@ -11,6 +12,34 @@
ACD10 mySensor; ACD10 mySensor;
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);
}
void setup() void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
@ -40,32 +69,4 @@ 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 -- // -- END OF FILE --

View File

@ -1,7 +1,8 @@
// //
// FILE: ACD10_readSensor.ino // FILE: ACD10_readSensor.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PUPROSE: test basic behaviour and performance // PURPOSE: test basic behaviour and performance
// URL: https://github.com/RobTillaart/ACD10
#include "Wire.h" #include "Wire.h"

View File

@ -0,0 +1,29 @@
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:
- "TCA9548"

View File

@ -0,0 +1,88 @@
//
// FILE: TCA9548_demo_ACD10.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo TCA9548 I2C multiplexer
// URL: https://github.com/RobTillaart/TCA9548
// URL: https://github.com/RobTillaart/ACD10
#include "ACD10.h"
#include "TCA9548.h"
PCA9546 MP(0x70);
uint8_t channels = 0;
ACD10 living; // channel 0
ACD10 kitchen; // channel 1
ACD10 outside; // channel 2
uint32_t lastTime = 0;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("TCA9548_LIB_VERSION: ");
Serial.println(TCA9548_LIB_VERSION);
Serial.print("ACD10_LIB_VERSION: ");
Serial.println(ACD10_LIB_VERSION);
Serial.println();
Wire.begin();
// initialize multiplexer
if (MP.begin() == false)
{
Serial.println("Multiplexer error");
}
channels = MP.channelCount();
// initialize the temperature sensors
MP.selectChannel(0);
if (living.begin() == false)
{
Serial.println("living error");
}
MP.selectChannel(1);
if (kitchen.begin() == false )
{
Serial.println("kitchen error");
}
MP.selectChannel(2);
if (outside.begin() == false )
{
Serial.println("outside error");
}
}
void loop()
{
if ((millis() - lastTime) > 5000)
{
lastTime = millis();
MP.selectChannel(0);
living.requestSensor();
while (!living.requestReady()) {};
living.readSensor();
Serial.print(living.getCO2Concentration());
Serial.print("\t");
MP.selectChannel(1);
kitchen.requestSensor();
while (!kitchen.requestReady()) {};
kitchen.readSensor();
Serial.print(kitchen.getCO2Concentration());
Serial.print("\t");
MP.selectChannel(2);
outside.requestSensor();
while (!outside.requestReady()) {};
outside.readSensor();
Serial.print(outside.getCO2Concentration());
Serial.print("\n");
}
}
// -- END OF FILE --

View File

@ -15,7 +15,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/ACD10.git" "url": "https://github.com/RobTillaart/ACD10.git"
}, },
"version": "0.1.2", "version": "0.1.3",
"license": "MIT", "license": "MIT",
"frameworks": "*", "frameworks": "*",
"platforms": "*", "platforms": "*",

View File

@ -1,5 +1,5 @@
name=ACD10 name=ACD10
version=0.1.2 version=0.1.3
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for the ACD10 CO2 sensor. sentence=Arduino library for the ACD10 CO2 sensor.

View File

@ -3,7 +3,7 @@
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// DATE: 2023-09-25 // DATE: 2023-09-25
// PURPOSE: unit tests for the ACD10 library // PURPOSE: unit tests for the ACD10 library
// https://github.com/RobTillaart/ACD10 // URL: https://github.com/RobTillaart/ACD10
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md // https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
// //
@ -28,7 +28,6 @@
#include "ACD10.h" #include "ACD10.h"
unittest_setup() unittest_setup()
{ {
fprintf(stderr, "ACD10_LIB_VERSION: %s\n", (char *) ACD10_LIB_VERSION); fprintf(stderr, "ACD10_LIB_VERSION: %s\n", (char *) ACD10_LIB_VERSION);