0.3.0 Cozir

This commit is contained in:
rob tillaart 2021-08-15 19:38:45 +02:00
parent e67bc3a86a
commit 50c8a2e0f7
10 changed files with 739 additions and 351 deletions

View File

@ -12,96 +12,114 @@ Arduino library for COZIR range of temperature, humidity and CO2 sensors.
## Description ## Description
The Cozir library is **experimental** as I do not have a sensor to test the library. The Cozir library is **experimental** as I do not have a sensor to test the library.
The polling mode as used in the examples seems to work quite well. The polling mode as used in the examples seems to work quite well as this is tested by DirtGambit.
This library supports only the Serial interface. An I2C based library will be written
when I have access to a Cozir sensor that supports I2C.
Idea is to make the interface identical if possible.
#### Notes #### Notes
- the **CozirDemoHWSerial.ino** example needs to run on a MEGA or a Teensy, - the **CozirDemoHWSerial.ino** example needs to run on a MEGA or a Teensy,
at least a board with more than one Serial port. at least a board with more than one Serial port.
- Read the datasheet before using this library. It helps to understand the working of the Cozir sensor. - Read the datasheet before using this library.
It helps to understand the working of the Cozir sensor.
## Interface ## Interface
Read the datasheet (again) Read the datasheet (again).
### Constructor and initialisation ### Constructor and initialisation
- **COZIR(Stream \*)** constructor - **COZIR(Stream \* str)** constructor.
- **void init()** sets operatingMode to CZR_POLLING - **void init()** sets operatingMode to CZR_POLLING.
- **void SetOperatingMode(uint8_t mode)** set the operating mode either to **CZR_COMMAND**, **CZR_POLLING** or **CZR_STREAMING** - **bool isInitialized()** returns true if enough time has passed after the call to **init()** for the sensor.
### Operating mode
- **void setOperatingMode(uint8_t mode)** set the operating mode either to **CZR_COMMAND**, **CZR_POLLING** or **CZR_STREAMING**
- **uint8_t getOperatingMode()** returns the mode set, **CZR_STREAMING** is the default.
Please note that **init()** sets the operating mode to **CZR_POLLING**.
### Core ### Core
- **float Celsius()** idem - **float celsius()** idem.
- **float Fahrenheit()** idem, wrapper around **Celsius()** - **float fahrenheit()** idem, 'wrapper' around **celsius()**
- **float Humidity()** idem - **float humidity()** idem.
- **float Light()** idem - **float light()** idem.
- **uint32_t CO2() ** idem. - **uint32_t CO2()** idem.
- **uint16_t getPPMFactor()** returns 1, 10, 100 See Page 14. - **uint16_t getPPMFactor()** returns 1, 10, 100 See Page 14.
### Calibration ### Calibration
Read datasheet before use Read datasheet before using these functions:
- **uint16_t FineTuneZeroPoint(uint16_t v1, uint16_t v2)** - **uint16_t fineTuneZeroPoint(uint16_t v1, uint16_t v2)**
- **uint16_t CalibrateFreshAir()** - **uint16_t calibrateFreshAir()**
- **uint16_t CalibrateNitrogen()** - **uint16_t calibrateNitrogen()**
- **uint16_t CalibrateKnownGas(uint16_t value)** - **uint16_t calibrateKnownGas(uint16_t value)**
#### Calibration NOT Recommended #### Calibration NOT Recommended
Following 3 functions are **NOT RECOMMENDED** by the datasheet. Following 3 functions are **NOT RECOMMENDED** by the datasheet.
Feel free to uncomment but use at your own risk. Read datasheet before use. Feel free to uncomment and use at your own risk.
Read datasheet before using these functions:
- **uint16_t CalibrateManual(uint16_t value)** - **uint16_t calibrateManual(uint16_t value)**
- **uint16_t SetSpanCalibrate(uint16_t value)** - **uint16_t setSpanCalibrate(uint16_t value)**
- **uint16_t GetSpanCalibrate()** - **uint16_t getSpanCalibrate()**
### Digifilter ### Digifilter
use with care, read datasheet before use use with care, read datasheet before use.
| value | meaning | | value | meaning |
|:-----:|:--------| |:-----:|:--------|
| 0 | Special, see datasheet page ... | | 0 | Special, see datasheet page ... |
| 1 | fast, but can be noisy | | 1 | fast, but can be noisy |
| 32 | default, good average | | 32 | default, good average |
| 255 | slow, max smoothed | | 255 | slow, max smoothed |
- **void SetDigiFilter(uint8_t value)** - **void setDigiFilter(uint8_t value)**
- **uint8_t GetDigiFilter()** - **uint8_t getDigiFilter()**
### Streaming MODE ### Streaming MODE
Warning: Not tested , Warning: Not tested ,
- **void SetOutputFields(uint16_t fields)** Sets the fields in the output stream. - **void setOutputFields(uint16_t fields)** Sets the fields in the output stream as a 16 bit mask. See table below.
- **void ClrOutputFields()** clears all the fields. - **void clearOutputFields()** clears all the fields.
- **void GetRecentFields()** After a call to GetRecentFields() you must read the serial port yourself as the internal buffer of this Class cannot handle the possible large output. It can be over 100 bytes long lines! - **uint16_t getOutputFields()** returns the 16 bit mask of set output fields.
- **bool inOutputFields(uint16_t field)** returns true if the field is set.
- **void getRecentFields()** After a call to getRecentFields() you must read the serial stream yourself.
The internal buffer of this Class cannot handle the possible large output. Lines can be over 100 bytes long!
The fields must be set as a bit mask, the order of the fields in the output is undetermined. So parse carefully. The fields must be set as a bit mask, the order of the fields in the output is undetermined.
So one need to parse the output of the sensor carefully.
| Field | Value | Notes | | Field | Value | Notes |
|:------------------|:-------|:------| |:------------------|:-------|:---------|
| CZR_LIGHT | 0x2000 | | | CZR_LIGHT | 0x2000 | |
| CZR_HUMIDITY | 0x1000 | | | CZR_HUMIDITY | 0x1000 | |
| CZR_FILTLED | 0x0800 | | | CZR_FILTLED | 0x0800 | |
| CZR_RAWLED | 0x0400 | | | CZR_RAWLED | 0x0400 | |
| CZR_MAXLED | 0x0200 | | | CZR_MAXLED | 0x0200 | |
| CZR_ZEROPOINT | 0x0100 | | | CZR_ZEROPOINT | 0x0100 | |
| CZR_RAWTEMP | 0x0080 | | | CZR_RAWTEMP | 0x0080 | |
| CZR_FILTTEMP | 0x0040 | | | CZR_FILTTEMP | 0x0040 | |
| CZR_FILTLEDSIGNAL | 0x0020 | | | CZR_FILTLEDSIGNAL | 0x0020 | |
| CZR_RAWLEDSIGNAL | 0x0010 | | | CZR_RAWLEDSIGNAL | 0x0010 | |
| CZR_SENSTEMP | 0x0008 | | | CZR_SENSTEMP | 0x0008 | |
| CZR_FILTCO2 | 0x0004 | | | CZR_FILTCO2 | 0x0004 | |
| CZR_RAWCO2 | 0x0002 | | | CZR_RAWCO2 | 0x0002 | |
| CZR_NONE | 0x0001 | reset | | CZR_NONE | 0x0001 | reset |
| CZR_HTC | 0x1082 | shortcut | | CZR_HTC | 0x1082 | shortcut |
| CZR_ALL | 0x3FFE | debug | | CZR_ALL | 0x3FFE | debug |
@ -111,32 +129,64 @@ The fields must be set as a bit mask, the order of the fields in the output is u
Read datasheet Page 11-12 about the addresses and their meaning. Read datasheet Page 11-12 about the addresses and their meaning.
Use with care. Use with care.
- **void SetEEPROM(uint8_t address, uint8_t value)** In 0.3.0 the EEPROM function have been replaced by specific accessor
- **uint8_t GetEEPROM(uint8_t address)** functions. Read datasheet for the details.
- **void setAutoCalibrationPreload(uint16_t value)**
- **uint16_t getAutoCalibrationPreload()**
- **void setAutoCalibrationInterval(uint16_t value)**
- **uint16_t getAutoCalibrationInterval()**
- **void setAutoCalibrationOn()**
- **void setAutoCalibrationOff()**
- **bool getAutoCalibration()**
- **void setAutoCalibrationBackgroundConcentration(uint16_t value)**
- **uint16_t getAutoCalibrationBackgroundConcentration()**
- **void setAmbientConcentration(uint16_t value)**
- **uint16_t getAmbientConcentration()**
- **void setBufferClearTime(uint16_t value)**
- **uint16_t getBufferClearTime()**
| Name | Address | Default | Notes | #### EEPROM addresses used by above functions.
|:---------|:-------:|:-------:|:------|
| AHHI | 0x00 | | reserved | Read datasheet for the details.
| ANLO | 0x01 | | reserved |
| ANSOURCE | 0x02 | | reserved | | Name | Address | Default | Notes |
| ACINITHI | 0x03 | 87 | | |:---------|:-------:|:-------:|:---------|
| ACINITLO | 0x04 | 192 | | | AHHI | 0x00 | ? | reserved |
| ACHI | 0x05 | 94 | | | ANLO | 0x01 | ? | reserved |
| ACLO | 0x06 | 128 | | | ANSOURCE | 0x02 | ? | reserved |
| ACONOFF | 0x07 | 0 | | | ACINITHI | 0x03 | 87 | |
| ACPPMHI | 0x08 | 1 | | | ACINITLO | 0x04 | 192 | |
| ACPPMLO | 0x09 | 194 | | | ACHI | 0x05 | 94 | |
| AMBHI | 0x0A | 1 | | | ACLO | 0x06 | 128 | |
| AMBLO | 0x0B | 194 | | | ACONOFF | 0x07 | 0 | |
| BCHI | 0x0C | 0 | | | ACPPMHI | 0x08 | 1 | |
| BCLO | 0x0D | 8 | | | ACPPMLO | 0x09 | 194 | |
| AMBHI | 0x0A | 1 | |
| AMBLO | 0x0B | 194 | |
| BCHI | 0x0C | 0 | |
| BCLO | 0x0D | 8 | |
### Misc ### Miscellaneous
- **void GetVersionSerial()** requests version over serial. The user should read (and parse) the serial output as it can become large. Also the user must reset the operating mode either to **CZR_POLLING** or **CZR_STREAMING** - **void getVersionSerial()** requests version over serial.
- **void GetConfiguration()** requests configuration over serial. The user should read (and parse) the serial output as it can become large. Also the user must reset the operating mode either to **CZR_POLLING** or **CZR_STREAMING** The user should read (and parse) the serial output as it can become large.
Also the user must reset the operating mode either to **CZR_POLLING** or **CZR_STREAMING**
- **void getConfiguration()** requests configuration over serial.
The user should read (and parse) the serial output as it can become large.
Also the user must reset the operating mode either to **CZR_POLLING** or **CZR_STREAMING**
## Future
- test test test test and ...
- add a **setEEPROMFactoryDefault()**?
- example two Cozir sensors
- example Cozir with I2C display?
- build a Arduino COZIR simulator for testing.
- Cozir I2C class for newer generation ~ same interface
## Operation ## Operation

View File

@ -1,18 +1,24 @@
// //
// FILE: Cozir.cpp // FILE: Cozir.cpp
// AUTHOR: DirtGambit & Rob Tillaart // AUTHOR: DirtGambit & Rob Tillaart
// VERSION: 0.2.6 // VERSION: 0.3.0
// PURPOSE: library for COZIR range of sensors for Arduino // PURPOSE: library for COZIR range of sensors for Arduino
// Polling Mode // Polling Mode
// URL: https://github.com/RobTillaart/Cozir // URL: https://github.com/RobTillaart/Cozir
// http://forum.arduino.cc/index.php?topic=91467.0 // http://forum.arduino.cc/index.php?topic=91467.0
// //
// HISTORY: // HISTORY:
// 0.3.0 2021-08-08 Major update - breaks interface (names mainly)
// add isInitialized(), add getOperatingMode(),
// add getOutputFields(), add inOutputFields(),
// add kelvin(), add EEPROM functions
// class methods camelCase
// extend unit tests
// 0.2.6 2021-01-31 fix #4 use Mode0 for versions and configuration // 0.2.6 2021-01-31 fix #4 use Mode0 for versions and configuration
// 0.2.5 2020-12-26 fix software Serial + version number (oops) // 0.2.5 2020-12-26 fix software Serial + version number (oops)
// 0.2.2 2020-12-17 add arduino-ci + unit tests // 0.2.2 2020-12-17 add Arduino-CI + unit tests
// 0.2.1 2020-06-05 fix library.json // 0.2.1 2020-06-05 fix library.json
// 0.2.0 2020-03-30 some refactor and own repo // 0.2.0 2020-03-30 some refactor and own repo
// 0.1.06 added support for HardwareSerial for MEGA (Rob T) // 0.1.06 added support for HardwareSerial for MEGA (Rob T)
// removed support for NewSoftSerial ==> stop pre 1.0 support) // removed support for NewSoftSerial ==> stop pre 1.0 support)
// 0.1.05 fixed bug: uint16_t request() to uint32_t request() in .h file (Rob T) // 0.1.05 fixed bug: uint16_t request() to uint32_t request() in .h file (Rob T)
@ -28,20 +34,52 @@
#include "cozir.h" #include "cozir.h"
#define CZR_INIT_DELAY 1200
#define CZR_REQUEST_TIMEOUT 200
// EEPROM ADRESSES
// P 11-12 manual
// Name Address Default value/ notes
#define CZR_AHHI 0x00 // reserved
#define CZR_ANLO 0x01 // reserved
#define CZR_ANSOURCE 0x02 // reserved
#define CZR_ACINITHI 0x03 // 87
#define CZR_ACINITLO 0x04 // 192
#define CZR_ACHI 0x05 // 94
#define CZR_ACLO 0x06 // 128
#define CZR_ACONOFF 0x07 // 0
#define CZR_ACPPMHI 0x08 // 1
#define CZR_ACPPMLO 0x09 // 194
#define CZR_AMBHI 0x0A // 1
#define CZR_AMBLO 0x0B // 194
#define CZR_BCHI 0x0C // 0
#define CZR_BCLO 0x0D // 8
COZIR::COZIR(Stream * str) COZIR::COZIR(Stream * str)
{ {
ser = str; _ser = str;
buffer[0] = '\0'; _buffer[0] = '\0';
} }
void COZIR::init() void COZIR::init()
{ {
// overide default streaming (takes too much performance) // override default streaming (takes too much performance)
SetOperatingMode(CZR_POLLING); setOperatingMode(CZR_POLLING);
// delay for initialization TODO should be timestamp based _initTimeStamp = millis();
// with an isInitialized function. Non blocking. // delay for initialization is kept until next major release.
delay(1200); // timestamp + isInitialized() is prepared.
// users can comment next line.
delay(CZR_INIT_DELAY);
}
bool COZIR::isInitialized()
{
return (millis() - _initTimeStamp) > CZR_INIT_DELAY;
} }
@ -53,10 +91,11 @@ void COZIR::init()
// CZR_POLLING and CZR_STREAMING use an equally amount // CZR_POLLING and CZR_STREAMING use an equally amount
// of power as both sample continuously... // of power as both sample continuously...
// //
void COZIR::SetOperatingMode(uint8_t mode) void COZIR::setOperatingMode(uint8_t mode)
{ {
sprintf(buffer, "K %u", mode); _operatingMode = mode;
Command(buffer); sprintf(_buffer, "K %u", mode);
_command(_buffer);
} }
@ -64,104 +103,105 @@ void COZIR::SetOperatingMode(uint8_t mode)
// //
// POLLING MODE // POLLING MODE
// //
// you need to set the polling mode explicitely before // you need to set the polling mode explicitly before
// using these functions. SetOperatingMode(CZR_POLLING); // using these functions. SetOperatingMode(CZR_POLLING);
// this is the default behaviour of this Class but // this is the default behaviour of this Class but
// not of the sensor!! // not of the sensor!!
// //
float COZIR::Celsius() float COZIR::celsius()
{ {
uint16_t rv = Request("T"); uint16_t rv = _request("T");
return 0.1 * (rv - 1000.0); // P17 negative values return 0.1 * (rv - 1000.0); // P17 negative values
} }
float COZIR::Humidity() float COZIR::humidity()
{ {
return 0.1 * Request("H"); return 0.1 * _request("H");
} }
// TODO UNITS UNKNOWN lux?? // UNITS UNKNOWN lux??
float COZIR::Light() float COZIR::light()
{ {
return 1.0 * Request("L"); return 1.0 * _request("L");
} }
uint32_t COZIR::CO2() uint32_t COZIR::CO2()
{ {
return Request("Z"); return _request("Z");
} }
uint16_t COZIR::getPPMFactor() uint16_t COZIR::getPPMFactor()
{ {
_ppmFactor = Request("."); _ppmFactor = _request(".");
return _ppmFactor; return _ppmFactor;
} }
// CALLIBRATION - USE THESE WITH CARE // CALLIBRATION - USE THESE WITH CARE
// use these only in pollingmode (on the Arduino) // use these only in polling mode (on the Arduino)
// FineTuneZeroPoint() // FineTuneZeroPoint()
// a reading of v1 will be reported as v2 // a reading of v1 will be reported as v2
// sort of mapping // sort of mapping
// check datasheet for detailed description // check datasheet for detailed description
uint16_t COZIR::FineTuneZeroPoint(uint16_t v1, uint16_t v2) uint16_t COZIR::fineTuneZeroPoint(uint16_t v1, uint16_t v2)
{ {
sprintf(buffer, "F %u %u", v1, v2); sprintf(_buffer, "F %u %u", v1, v2);
return Request(buffer); return _request(_buffer);
} }
// mostly the default calibrator // mostly the default calibrator
uint16_t COZIR::CalibrateFreshAir() uint16_t COZIR::calibrateFreshAir()
{ {
return Request("G"); return _request("G");
} }
uint16_t COZIR::CalibrateNitrogen() uint16_t COZIR::calibrateNitrogen()
{ {
return Request("U"); return _request("U");
} }
uint16_t COZIR::CalibrateKnownGas(uint16_t value) uint16_t COZIR::calibrateKnownGas(uint16_t value)
{ {
sprintf(buffer, "X %u", value); sprintf(_buffer, "X %u", value);
return Request(buffer); return _request(_buffer);
} }
//uint16_t COZIR::CalibrateManual(uint16_t value) //uint16_t COZIR::calibrateManual(uint16_t value)
//{ //{
//sprintf(buffer, "u %u", value); //sprintf(_buffer, "u %u", value);
//return Request(buffer); //return _request(_buffer);
//} //}
//uint16_t COZIR::SetSpanCalibrate(uint16_t value) //uint16_t COZIR::setSpanCalibrate(uint16_t value)
//{ //{
//sprintf(buffer, "S %u", value); //sprintf(_buffer, "S %u", value);
//return Request(buffer); //return _request(_buffer);
//} //}
//uint16_t COZIR::GetSpanCalibrate() //uint16_t COZIR::getSpanCalibrate()
//{ //{
// return Request("s"); // return _request("s");
//} //}
void COZIR::SetDigiFilter(uint8_t value) void COZIR::setDigiFilter(uint8_t value)
{ {
sprintf(buffer, "A %u", value); sprintf(_buffer, "A %u", value);
Command(buffer); _command(_buffer);
} }
uint8_t COZIR::GetDigiFilter() uint8_t COZIR::getDigiFilter()
{ {
return Request("a"); return _request("a");
} }
@ -169,18 +209,25 @@ uint8_t COZIR::GetDigiFilter()
// //
// STREAMING MODE // STREAMING MODE
// //
// outputfields should be OR-ed // output fields should be OR-ed
// e.g. SetOutputFields(CZR_HUMIDITY | CZR_RAWTEMP | CZR_RAWCO2); // e.g. SetOutputFields(CZR_HUMIDITY | CZR_RAWTEMP | CZR_RAWCO2);
// //
// you need to set the STREAMING mode explicitely // you need to set the STREAMING mode explicitly
// SetOperatingMode(CZR_STREAMING); // SetOperatingMode(CZR_STREAMING);
// //
// in STREAMING mode you must parse the output of serial yourself // in STREAMING mode you must parse the output of serial yourself
// //
void COZIR::SetOutputFields(uint16_t fields) void COZIR::setOutputFields(uint16_t fields)
{ {
sprintf(buffer, "M %u", fields); _outputFields = fields;
Command(buffer); sprintf(_buffer, "M %u", fields);
_command(_buffer);
}
bool COZIR::inOutputFields(uint16_t field)
{
return (_outputFields & field) == field;
} }
@ -188,30 +235,96 @@ void COZIR::SetOutputFields(uint16_t fields)
// After a call to GetRecentFields() you must read the serial port yourself as // After a call to GetRecentFields() you must read the serial port yourself as
// the internal buffer of this Class cannot handle the possible large output. // the internal buffer of this Class cannot handle the possible large output.
// It can be over 100 bytes long lines! // It can be over 100 bytes long lines!
void COZIR::GetRecentFields() void COZIR::getRecentFields()
{ {
Command("Q"); _command("Q");
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// EEPROM - USE WITH CARE // EEPROM CALLS - USE WITH CARE
// //
// SEE DATASHEET 7.2 EEPROM FOR DETAILS void COZIR::setAutoCalibrationPreload(uint16_t value)
//
void COZIR::SetEEPROM(uint8_t address, uint8_t value)
{ {
if (address > BCLO) return; _setEEPROM2(CZR_ACINITHI, value);
sprintf(buffer, "P %u %u", address, value); }
Command(buffer);
uint16_t COZIR::getAutoCalibrationPreload()
{
return _getEEPROM2(CZR_ACINITHI);
}
void COZIR::setAutoCalibrationInterval(uint16_t value)
{
_setEEPROM2(CZR_ACHI, value);
}
uint16_t COZIR::getAutoCalibrationInterval()
{
return _getEEPROM2(CZR_ACHI);
}
void COZIR::setAutoCalibrationOn()
{
_setEEPROM(CZR_ACONOFF, 1);
}
void COZIR::setAutoCalibrationOff()
{
_setEEPROM(CZR_ACONOFF, 0);
}
bool COZIR::getAutoCalibration()
{
return _getEEPROM(CZR_ACONOFF);
}
void COZIR::setAutoCalibrationBackgroundConcentration(uint16_t value)
{
_setEEPROM2(CZR_ACPPMHI, value);
}
uint16_t COZIR::getAutoCalibrationBackgroundConcentration()
{
return _getEEPROM2(CZR_ACPPMHI);
}
void COZIR::setAmbientConcentration(uint16_t value)
{
_setEEPROM2(CZR_AMBHI, value);
}
uint16_t COZIR::getAmbientConcentration()
{
return _getEEPROM2(CZR_AMBHI);
}
void COZIR::setBufferClearTime(uint16_t value)
{
_setEEPROM2(CZR_BCHI, value);
}
uint16_t COZIR::getBufferClearTime()
{
return _getEEPROM2(CZR_BCHI);
} }
uint8_t COZIR::GetEEPROM(uint8_t address) /*
// TODO first verify if single functions work.
void COZIR::setEEPROMFactoryReset()
{ {
sprintf(buffer, "p %u", address); setAutoCalibrationPreload(0x57C0);
return Request(buffer); setAutoCalibrationInterval(0x8E80);
setAutoCalibrationOff();
setAutoCalibrationBackgroundConcentration(0x01C2);
setAmbientConcentration(0x01C2);
setBufferClearTime(0x0008);
} }
*/
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
@ -220,23 +333,23 @@ uint8_t COZIR::GetEEPROM(uint8_t address)
// read serial yourself - // read serial yourself -
// //
// TODO Page 5: Mode 0 Command Mode // TODO Page 5: Mode 0 Command Mode
// This is primarily intended for use when extracting larger chunks // This is primarily intended for use when extracting larger chunks
// of information from the sensor (for example using the Y and * commands). // of information from the sensor (for example using the Y and * commands).
// In this mode, the sensor is stopped waiting for commands. // In this mode, the sensor is stopped waiting for commands.
// //
void COZIR::GetVersionSerial() void COZIR::getVersionSerial()
{ {
// overide modes to prevent interference in output // override modes to prevent interference in output
SetOperatingMode(CZR_COMMAND); setOperatingMode(CZR_COMMAND);
Command("Y"); _command("Y");
} }
void COZIR::GetConfiguration() void COZIR::getConfiguration()
{ {
// overide modes to prevent interference in output // override modes to prevent interference in output
SetOperatingMode(CZR_COMMAND); setOperatingMode(CZR_COMMAND);
Command("*"); _command("*");
} }
@ -244,35 +357,75 @@ void COZIR::GetConfiguration()
// //
// PRIVATE // PRIVATE
// //
void COZIR::Command(const char* str) void COZIR::_command(const char* str)
{ {
ser->print(str); _ser->print(str);
ser->print("\r\n"); _ser->print("\r\n");
} }
uint32_t COZIR::Request(const char* str) uint32_t COZIR::_request(const char* str)
{ {
Command(str); _command(str);
// read answer; there may be a 100ms delay! // read the answer from serial.
// TODO: PROPER TIMEOUT CODE. - what is longest answer possible? // TODO: PROPER TIMEOUT CODE.
// yield()? // - might be a big delay
// output always stops with /r/n. // - what is longest answer possible?
uint8_t idx = 0;
delay(200); uint32_t start = millis();
// while (millis() - start < CZR_REQUEST_TIMEOUT)
// start with empty buffer delay(CZR_REQUEST_TIMEOUT);
uint8_t idx = 0; while (true)
while(ser->available()) {
// delay(1);
if (_ser->available())
{ {
buffer[idx++] = ser->read(); char c = _ser->read();
_buffer[idx++] = c;
_buffer[idx] = '\0';
if (c == '\n') break;
} }
buffer[idx] = '\0'; }
uint32_t rv = atol(&_buffer[2]);
uint32_t rv = atol(&buffer[2]); if (idx > 2) return rv;
return rv; return 0;
} }
void COZIR::_setEEPROM(uint8_t address, uint8_t value)
{
if (address > CZR_BCLO) return;
sprintf(_buffer, "P %u %u", address, value);
_command(_buffer);
}
uint8_t COZIR::_getEEPROM(uint8_t address)
{
sprintf(_buffer, "p %u", address);
return _request(_buffer);
}
void COZIR::_setEEPROM2(uint8_t address, uint16_t value)
{
if (address > CZR_BCLO) return;
sprintf(_buffer, "P %u %u", address, value >> 8);
_command(_buffer);
sprintf(_buffer, "P %u %u", address + 1, value & 0xFF);
_command(_buffer);
}
uint16_t COZIR::_getEEPROM2(uint8_t address)
{
sprintf(_buffer, "p %u", address);
uint16_t val = _request(_buffer) << 8;
sprintf(_buffer, "p %u", address + 1);
return val + _request(_buffer);
}
// -- END OF FILE -- // -- END OF FILE --

View File

@ -2,7 +2,7 @@
// //
// FILE: Cozir.h // FILE: Cozir.h
// AUTHOR: DirtGambit & Rob Tillaart // AUTHOR: DirtGambit & Rob Tillaart
// VERSION: 0.2.6 // VERSION: 0.3.0
// PURPOSE: library for COZIR range of sensors for Arduino // PURPOSE: library for COZIR range of sensors for Arduino
// Polling Mode // Polling Mode
// URL: https://github.com/RobTillaart/Cozir // URL: https://github.com/RobTillaart/Cozir
@ -11,118 +11,152 @@
// READ DATASHEET BEFORE USE OF THIS LIB ! // READ DATASHEET BEFORE USE OF THIS LIB !
// //
#include "Arduino.h" #include "Arduino.h"
#define COZIR_LIB_VERSION (F("0.2.6"))
#define COZIR_LIB_VERSION (F("0.3.0"))
// OUTPUTFIELDS // OUTPUTFIELDS
// See datasheet for details. // See datasheet for details.
// These defines can be OR-ed for the SetOutputFields command // These defines can be OR-ed for the SetOutputFields command
#define CZR_LIGHT 0x2000 #define CZR_LIGHT 0x2000
#define CZR_HUMIDITY 0x1000 #define CZR_HUMIDITY 0x1000
#define CZR_FILTLED 0x0800 #define CZR_FILTLED 0x0800
#define CZR_RAWLED 0x0400 #define CZR_RAWLED 0x0400
#define CZR_MAXLED 0x0200 #define CZR_MAXLED 0x0200
#define CZR_ZEROPOINT 0x0100 #define CZR_ZEROPOINT 0x0100
#define CZR_RAWTEMP 0x0080 #define CZR_RAWTEMP 0x0080
#define CZR_FILTTEMP 0x0040 #define CZR_FILTTEMP 0x0040
#define CZR_FILTLEDSIGNAL 0x0020 #define CZR_FILTLEDSIGNAL 0x0020
#define CZR_RAWLEDSIGNAL 0x0010 #define CZR_RAWLEDSIGNAL 0x0010
#define CZR_SENSTEMP 0x0008 #define CZR_SENSTEMP 0x0008
#define CZR_FILTCO2 0x0004 #define CZR_FILTCO2 0x0004
#define CZR_RAWCO2 0x0002 #define CZR_RAWCO2 0x0002
#define CZR_NONE 0x0001
#define CZR_NONE 0x0001
// easy default setting for streaming // easy default setting for streaming
#define CZR_HTC (CZR_HUMIDITY | CZR_RAWTEMP | CZR_RAWCO2) #define CZR_HTC (CZR_HUMIDITY | CZR_RAWTEMP | CZR_RAWCO2)
// not in datasheet for debug only // not in datasheet for debug only
#define CZR_ALL 0x3FFE #define CZR_ALL 0x3FFE
// OPERATING MODES // OPERATING MODES
#define CZR_COMMAND 0x00 #define CZR_COMMAND 0x00
#define CZR_STREAMING 0x01 #define CZR_STREAMING 0x01
#define CZR_POLLING 0x02 #define CZR_POLLING 0x02
// EEPROM ADRESSES
// P 11-12 manual - maybe some deserve a function?
// Name Address Default value/ notes
#define AHHI 0x00 // reserved
#define ANLO 0x01 // reserved
#define ANSOURCE 0x02 // reserved
#define ACINITHI 0x03 // 87
#define ACINITLO 0x04 // 192
#define ACHI 0x05 // 94
#define ACLO 0x06 // 128
#define ACONOFF 0x07 // 0
#define ACPPMHI 0x08 // 1
#define ACPPMLO 0x09 // 194
#define AMBHI 0x0A // 1
#define AMBLO 0x0B // 194
#define BCHI 0x0C // 0
#define BCLO 0x0D // 8
class COZIR class COZIR
{ {
public: public:
COZIR(Stream *); COZIR(Stream * str);
void init(); // sets operatingMode to CZR_POLLING void init(); // sets operatingMode to CZR_POLLING
bool isInitialized();
// warning: CZR_STREAMING is experimental, minimal tested. // warning: CZR_STREAMING is experimental, minimal tested.
void SetOperatingMode(uint8_t mode); void setOperatingMode(uint8_t mode);
uint8_t getOperatingMode() { return _operatingMode; };
float Celsius();
float Fahrenheit() { return (Celsius() * 1.8) + 32; };
float Humidity();
float Light();
uint32_t CO2();
uint16_t getPPMFactor(); // P14 . command return 1, 10 or 100
// Callibration function, read datasheet before use float celsius();
uint16_t FineTuneZeroPoint(uint16_t v1, uint16_t v2); float fahrenheit() { return (celsius() * 1.8) + 32; };
uint16_t CalibrateFreshAir(); float kelvin() { return celsius() + 273.15; };
uint16_t CalibrateNitrogen(); float humidity();
uint16_t CalibrateKnownGas(uint16_t value); float light();
uint32_t CO2();
uint16_t getPPMFactor(); // P14 . command return 1, 10 or 100
// WARNING: following 3 functions are NOT RECOMMENDED,
// read datasheet before use
// uint16_t CalibrateManual(uint16_t value);
// uint16_t SetSpanCalibrate(uint16_t value);
// uint16_t GetSpanCalibrate();
// DIGIFILTER, use with care, read datasheet before use // Calibration function, read datasheet before use
// 32 = default value = 32, uint16_t fineTuneZeroPoint(uint16_t v1, uint16_t v2);
// 1 = fast (noisy) uint16_t calibrateFreshAir();
// 255 = slow (smoothed) uint16_t calibrateNitrogen();
// 0 = special. details see datasheet uint16_t calibrateKnownGas(uint16_t value);
void SetDigiFilter(uint8_t value);
uint8_t GetDigiFilter();
// STREAMING MODE - needs testing...
void SetOutputFields(uint16_t fields);
void ClrOutputFields() { SetOutputFields(CZR_NONE); };
// WARNING:
// After a call to GetRecentFields() you must read the serial port yourself as
// the internal buffer of this Class cannot handle the possible large output.
// It can be over 100 bytes long lines!
void GetRecentFields();
// EEPROM // WARNING: following 3 functions are NOT RECOMMENDED,
// TODO some specific wrappers? in the end it are only 6 different calls? // read datasheet before use
void SetEEPROM(uint8_t address, uint8_t value); // uint16_t calibrateManual(uint16_t value);
uint8_t GetEEPROM(uint8_t address); // uint16_t setSpanCalibrate(uint16_t value);
// uint16_t getSpanCalibrate();
// DIGIFILTER, use with care, read datasheet before use
// 32 = default value = 32,
// 1 = fast (noisy)
// 255 = slow (smoothed)
// 0 = special. details see datasheet
void setDigiFilter(uint8_t value);
uint8_t getDigiFilter();
// STREAMING MODE - needs testing...
void setOutputFields(uint16_t fields);
uint16_t getOutputFields() { return _outputFields; };
bool inOutputFields(uint16_t field);
void clearOutputFields() { setOutputFields(CZR_NONE); };
// WARNING:
// After a call to GetRecentFields() you must read the serial port yourself as
// the internal buffer of this Class cannot handle the possible large output.
// Answers can be over 100 bytes long!
void getRecentFields();
// EEPROM
void setAutoCalibrationPreload(uint16_t value);
uint16_t getAutoCalibrationPreload();
void setAutoCalibrationInterval(uint16_t value);
uint16_t getAutoCalibrationInterval();
void setAutoCalibrationOn();
void setAutoCalibrationOff();
bool getAutoCalibration();
void setAutoCalibrationBackgroundConcentration(uint16_t value);
uint16_t getAutoCalibrationBackgroundConcentration();
void setAmbientConcentration(uint16_t value);
uint16_t getAmbientConcentration();
void setBufferClearTime(uint16_t value);
uint16_t getBufferClearTime();
// TODO test EEPROM function first.
// void setEEPROMFactoryReset();
// META INFORMATION
void getVersionSerial();
void getConfiguration();
///////////////////////////////////////////////
//
// SEMI PRIVATE FOR UNIT TESTING THEM
//
void _setEEPROM(uint8_t address, uint8_t value);
uint8_t _getEEPROM(uint8_t address);
void _setEEPROM2(uint8_t address, uint16_t value);
uint16_t _getEEPROM2(uint8_t address);
void GetVersionSerial();
void GetConfiguration();
private: private:
Stream *ser; Stream * _ser;
char buffer[20]; char _buffer[20];
uint16_t _ppmFactor = 1;
void Command(const char* str); uint32_t _initTimeStamp = 0;
uint32_t Request(const char* str); uint16_t _ppmFactor = 1;
uint8_t _operatingMode = CZR_STREAMING;
uint16_t _outputFields = CZR_NONE;
void _command(const char* str);
uint32_t _request(const char* str);
}; };
// -- END OF FILE -- // -- END OF FILE --

View File

@ -29,9 +29,9 @@ void setup()
void loop() void loop()
{ {
float t = czr.Celsius(); float t = czr.celsius();
float f = czr.Fahrenheit(); float f = czr.fahrenheit();
float h = czr.Humidity(); float h = czr.humidity();
uint32_t c = czr.CO2(); uint32_t c = czr.CO2();
Serial.print("Celcius =\t"); Serial.println(t); Serial.print("Celcius =\t"); Serial.println(t);

View File

@ -29,9 +29,9 @@ void setup()
void loop() void loop()
{ {
float t = czr.Celsius(); float t = czr.celsius();
float f = czr.Fahrenheit(); float f = czr.fahrenheit();
float h = czr.Humidity(); float h = czr.humidity();
uint32_t c = czr.CO2(); uint32_t c = czr.CO2();
Serial.print("Celcius =\t"); Serial.println(t); Serial.print("Celcius =\t"); Serial.println(t);

View File

@ -25,7 +25,7 @@ void setup()
Serial.println(); Serial.println();
delay(100); delay(100);
czr.GetVersionSerial(); czr.getVersionSerial();
delay(5); delay(5);
while (Serial1.available()) while (Serial1.available())
{ {
@ -33,7 +33,7 @@ void setup()
} }
delay(100); delay(100);
czr.GetConfiguration(); czr.getConfiguration();
delay(5); delay(5);
while (Serial1.available()) while (Serial1.available())
{ {
@ -42,14 +42,14 @@ void setup()
delay(1000); delay(1000);
// reset to polling again. // reset to polling again.
czr.SetOperatingMode(CZR_POLLING); czr.setOperatingMode(CZR_POLLING);
} }
void loop() void loop()
{ {
float t = czr.Celsius(); float t = czr.celsius();
float f = czr.Fahrenheit(); float f = czr.fahrenheit();
float h = czr.Humidity(); float h = czr.humidity();
uint32_t c = czr.CO2(); uint32_t c = czr.CO2();
Serial.print("Celcius =\t"); Serial.println(t); Serial.print("Celcius =\t"); Serial.println(t);

View File

@ -1,31 +1,57 @@
# Syntax Coloring Map For COZIR # Syntax Colouring Map For COZIR
# Datatypes (KEYWORD1) # Data types (KEYWORD1)
COZIR KEYWORD1 COZIR KEYWORD1
# Methods and Functions (KEYWORD2) # Methods and Functions (KEYWORD2)
init KEYWORD2 init KEYWORD2
SetOperatingMode KEYWORD2
Celsius KEYWORD2 setOperatingMode KEYWORD2
Fahrenheit KEYWORD2 getOperatingMode KEYWORD2
Humidity KEYWORD2
Light KEYWORD2 celsius KEYWORD2
fahrenheit KEYWORD2
humidity KEYWORD2
light KEYWORD2
CO2 KEYWORD2 CO2 KEYWORD2
getPPMFactor KEYWORD2 getPPMFactor KEYWORD2
FineTuneZeroPoint KEYWORD2
CalibrateFreshAir KEYWORD2 fineTuneZeroPoint KEYWORD2
CalibrateNitrogen KEYWORD2 calibrateFreshAir KEYWORD2
CalibrateKnownGas KEYWORD2 calibrateNitrogen KEYWORD2
SetDigiFilter KEYWORD2 calibrateKnownGas KEYWORD2
GetDigiFilter KEYWORD2
SetOutputFields KEYWORD2 setDigiFilter KEYWORD2
ClrOutputFields KEYWORD2 getDigiFilter KEYWORD2
GetRecentFields KEYWORD2
SetEEPROM KEYWORD2 setOutputFields KEYWORD2
GetEEPROM KEYWORD2 getOutputFields KEYWORD2
GetVersionSerial KEYWORD2 inOutputFields KEYWORD2
GetConfiguration KEYWORD2 clrOutputFields KEYWORD2
getRecentFields KEYWORD2
setAutoCalibrationPreload KEYWORD2
getAutoCalibrationPreload KEYWORD2
setAutoCalibrationInterval KEYWORD2
getAutoCalibrationInterval KEYWORD2
setAutoCalibrationOn KEYWORD2
setAutoCalibrationOff KEYWORD2
getAutoCalibration KEYWORD2
setAutoCalibrationBackgroundConcentration KEYWORD2
getAutoCalibrationBackgroundConcentration KEYWORD2
setAmbientConcentration KEYWORD2
getAmbientConcentration KEYWORD2
setBufferClearTime KEYWORD2
getBufferClearTime KEYWORD2
getVersionSerial KEYWORD2
getConfiguration KEYWORD2
# Constants (LITERAL1) # Constants (LITERAL1)

View File

@ -18,7 +18,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/Cozir.git" "url": "https://github.com/RobTillaart/Cozir.git"
}, },
"version": "0.2.6", "version": "0.3.0",
"license": "MIT", "license": "MIT",
"frameworks": "arduino", "frameworks": "arduino",
"platforms": "*" "platforms": "*"

View File

@ -1,5 +1,5 @@
name=Cozir name=Cozir
version=0.2.6 version=0.3.0
author=Rob Tillaart <rob.tillaart@gmail.com>, DirtGambit author=Rob Tillaart <rob.tillaart@gmail.com>, DirtGambit
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for COZIR range of CO2 sensors. Polling mode only. sentence=Arduino library for COZIR range of CO2 sensors. Polling mode only.

View File

@ -68,6 +68,8 @@ unittest(test_software_serial)
fprintf(stderr, "COZIR.init()\n"); fprintf(stderr, "COZIR.init()\n");
co.init(); co.init();
assertEqual("K 2\r\n", state->digitalPin[transmitPin].toAscii(1, bigEndian)); assertEqual("K 2\r\n", state->digitalPin[transmitPin].toAscii(1, bigEndian));
delay(1300);
assertTrue(co.isInitialized());
} }
@ -90,17 +92,17 @@ unittest(test_constructor)
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.init(); co.init();
assertEqual("K 2\r\n", state->serialPort[0].dataOut); assertEqual("K 2\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.GetVersionSerial()\n"); fprintf(stderr, "COZIR.getVersionSerial()\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.GetVersionSerial(); co.getVersionSerial();
assertEqual("K 0\r\nY\r\n", state->serialPort[0].dataOut); assertEqual("K 0\r\nY\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.GetConfiguration()\n"); fprintf(stderr, "COZIR.getConfiguration()\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.GetConfiguration(); co.getConfiguration();
assertEqual("K 0\r\n*\r\n", state->serialPort[0].dataOut); assertEqual("K 0\r\n*\r\n", state->serialPort[0].dataOut);
} }
@ -115,25 +117,30 @@ unittest(test_setOperatingMode)
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.init(); co.init();
// init() sets CZR_POLLING
assertEqual("K 2\r\n", state->serialPort[0].dataOut); assertEqual("K 2\r\n", state->serialPort[0].dataOut);
assertEqual(co.getOperatingMode(), CZR_POLLING);
fprintf(stderr, "COZIR.SetOperatingMode(CZR_COMMAND)\n"); fprintf(stderr, "COZIR.SetOperatingMode(CZR_COMMAND)\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.SetOperatingMode(CZR_COMMAND); co.setOperatingMode(CZR_COMMAND);
assertEqual("K 0\r\n", state->serialPort[0].dataOut); assertEqual("K 0\r\n", state->serialPort[0].dataOut);
assertEqual(co.getOperatingMode(), CZR_COMMAND);
fprintf(stderr, "COZIR.SetOperatingMode(CZR_STREAMING)\n"); fprintf(stderr, "COZIR.SetOperatingMode(CZR_STREAMING)\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.SetOperatingMode(CZR_STREAMING); co.setOperatingMode(CZR_STREAMING);
assertEqual("K 1\r\n", state->serialPort[0].dataOut); assertEqual("K 1\r\n", state->serialPort[0].dataOut);
assertEqual(co.getOperatingMode(), CZR_STREAMING);
fprintf(stderr, "COZIR.SetOperatingMode(CZR_POLLING)\n"); fprintf(stderr, "COZIR.SetOperatingMode(CZR_POLLING)\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.SetOperatingMode(CZR_POLLING); co.setOperatingMode(CZR_POLLING);
assertEqual("K 2\r\n", state->serialPort[0].dataOut); assertEqual("K 2\r\n", state->serialPort[0].dataOut);
assertEqual(co.getOperatingMode(), CZR_POLLING);
} }
@ -148,33 +155,33 @@ unittest(test_read_sensor)
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.init(); co.init();
assertEqual("K 2\r\n", state->serialPort[0].dataOut); assertEqual("K 2\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.Celsius()\n"); fprintf(stderr, "COZIR.Celsius()\n");
state->serialPort[0].dataIn = "T 750\r\n"; // 1000 = 0°C state->serialPort[0].dataIn = "T 750\r\n"; // 1000 = 0°C
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
float Celsius = co.Celsius(); float celsius = co.celsius();
assertEqual("T\r\n", state->serialPort[0].dataOut); assertEqual("T\r\n", state->serialPort[0].dataOut);
assertEqualFloat(-25.0, Celsius, 0.0001); assertEqualFloat(-25.0, celsius, 0.0001);
state->serialPort[0].dataIn = "T 1257\r\n"; state->serialPort[0].dataIn = "T 1257\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
Celsius = co.Celsius(); celsius = co.celsius();
assertEqual("T\r\n", state->serialPort[0].dataOut); assertEqual("T\r\n", state->serialPort[0].dataOut);
assertEqualFloat(25.7, Celsius, 0.0001); assertEqualFloat(25.7, celsius, 0.0001);
fprintf(stderr, "COZIR.Humidity()\n"); fprintf(stderr, "COZIR.humidity()\n");
state->serialPort[0].dataIn = "H 627\r\n"; state->serialPort[0].dataIn = "H 627\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
float Humidity = co.Humidity(); float humidity = co.humidity();
assertEqual("H\r\n", state->serialPort[0].dataOut); assertEqual("H\r\n", state->serialPort[0].dataOut);
assertEqualFloat(62.7, Humidity, 0.0001); assertEqualFloat(62.7, humidity, 0.0001);
fprintf(stderr, "COZIR.Light()\n"); fprintf(stderr, "COZIR.light()\n");
state->serialPort[0].dataIn = "L 189\r\n"; state->serialPort[0].dataIn = "L 189\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
float Light = co.Light(); float light = co.light();
assertEqual("L\r\n", state->serialPort[0].dataOut); assertEqual("L\r\n", state->serialPort[0].dataOut);
assertEqual(189, Light); assertEqual(189, light);
fprintf(stderr, "COZIR.CO2()\n"); fprintf(stderr, "COZIR.CO2()\n");
state->serialPort[0].dataIn = "Z 432\r\n"; state->serialPort[0].dataIn = "Z 432\r\n";
@ -196,36 +203,36 @@ unittest(test_calibrate)
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.init(); co.init();
assertEqual("K 2\r\n", state->serialPort[0].dataOut); assertEqual("K 2\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.FineTuneZeroPoint(400, 382)\n"); fprintf(stderr, "COZIR.fineTuneZeroPoint(400, 382)\n");
state->serialPort[0].dataIn = "F 32950\r\n"; state->serialPort[0].dataIn = "F 32950\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
uint16_t FineTuneZeroPoint = co.FineTuneZeroPoint(400, 382); uint16_t fineTuneZeroPoint = co.fineTuneZeroPoint(400, 382);
assertEqual("F 400 382\r\n", state->serialPort[0].dataOut); assertEqual("F 400 382\r\n", state->serialPort[0].dataOut);
assertEqual(32950, FineTuneZeroPoint); assertEqual(32950, fineTuneZeroPoint);
fprintf(stderr, "COZIR.CalibrateFreshAir()\n"); fprintf(stderr, "COZIR.calibrateFreshAir()\n");
state->serialPort[0].dataIn = "G 32950\r\n"; state->serialPort[0].dataIn = "G 32950\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
uint16_t CalibrateFreshAir = co.CalibrateFreshAir(); uint16_t calibrateFreshAir = co.calibrateFreshAir();
assertEqual("G\r\n", state->serialPort[0].dataOut); assertEqual("G\r\n", state->serialPort[0].dataOut);
assertEqual(32950, CalibrateFreshAir); assertEqual(32950, calibrateFreshAir);
fprintf(stderr, "COZIR.CalibrateNitrogen()\n"); fprintf(stderr, "COZIR.calibrateNitrogen()\n");
state->serialPort[0].dataIn = "U 32590\r\n"; state->serialPort[0].dataIn = "U 32590\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
uint16_t CalibrateNitrogen = co.CalibrateNitrogen(); uint16_t calibrateNitrogen = co.calibrateNitrogen();
assertEqual("U\r\n", state->serialPort[0].dataOut); assertEqual("U\r\n", state->serialPort[0].dataOut);
assertEqual(32590, CalibrateNitrogen); assertEqual(32590, calibrateNitrogen);
fprintf(stderr, "COZIR.CalibrateKnownGas(100)\n"); fprintf(stderr, "COZIR.calibrateKnownGas(100)\n");
state->serialPort[0].dataIn = "X 33012\r\n"; state->serialPort[0].dataIn = "X 33012\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
uint16_t CalibrateKnownGas = co.CalibrateKnownGas(100); uint16_t calibrateKnownGas = co.calibrateKnownGas(100);
assertEqual("X 100\r\n", state->serialPort[0].dataOut); assertEqual("X 100\r\n", state->serialPort[0].dataOut);
assertEqual(33012, CalibrateKnownGas); assertEqual(33012, calibrateKnownGas);
} }
@ -240,17 +247,17 @@ unittest(test_digi_filter)
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.init(); co.init();
assertEqual("K 2\r\n", state->serialPort[0].dataOut); assertEqual("K 2\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.SetDigiFilter(42)\n"); fprintf(stderr, "COZIR.setDigiFilter(42)\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.SetDigiFilter(42); co.setDigiFilter(42);
assertEqual("A 42\r\n", state->serialPort[0].dataOut); assertEqual("A 42\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.GetDigiFilter()\n"); fprintf(stderr, "COZIR.getDigiFilter()\n");
state->serialPort[0].dataIn = "a 42\r\n"; state->serialPort[0].dataIn = "a 42\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
uint8_t digifilter = co.GetDigiFilter(); uint8_t digifilter = co.getDigiFilter();
assertEqual("a\r\n", state->serialPort[0].dataOut); assertEqual("a\r\n", state->serialPort[0].dataOut);
assertEqual(42, digifilter); assertEqual(42, digifilter);
} }
@ -267,41 +274,53 @@ unittest(test_streaming_mode)
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.init(); co.init();
assertEqual("K 2\r\n", state->serialPort[0].dataOut); assertEqual("K 2\r\n", state->serialPort[0].dataOut);
assertEqual(co.getOutputFields(), CZR_NONE);
fprintf(stderr, "COZIR.SetOperatingMode(CZR_STREAMING)\n"); fprintf(stderr, "COZIR.setOperatingMode(CZR_STREAMING)\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.SetOperatingMode(CZR_STREAMING); co.setOperatingMode(CZR_STREAMING);
assertEqual("K 1\r\n", state->serialPort[0].dataOut); assertEqual("K 1\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.SetOutputFields(CZR_HUMIDITY | CZR_RAWTEMP | CZR_RAWCO2)\n"); fprintf(stderr, "COZIR.setOutputFields(CZR_HUMIDITY | CZR_RAWTEMP | CZR_RAWCO2)\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.SetOutputFields(CZR_HUMIDITY | CZR_RAWTEMP | CZR_RAWCO2); co.setOutputFields(CZR_HUMIDITY | CZR_RAWTEMP | CZR_RAWCO2);
assertEqual("M 4226\r\n", state->serialPort[0].dataOut); assertEqual("M 4226\r\n", state->serialPort[0].dataOut);
assertEqual(co.getOutputFields(), CZR_HTC);
fprintf(stderr, "COZIR.GetRecentFields()\n"); fprintf(stderr, "COZIR.inOutputFields()\n");
assertTrue(co.inOutputFields(CZR_HUMIDITY));
assertTrue(co.inOutputFields(CZR_RAWTEMP));
assertTrue(co.inOutputFields(CZR_RAWCO2));
assertFalse(co.inOutputFields(CZR_LIGHT));
assertFalse(co.inOutputFields(~CZR_HTC));
fprintf(stderr, "COZIR.getRecentFields()\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.GetRecentFields(); co.getRecentFields();
assertEqual("Q\r\n", state->serialPort[0].dataOut); assertEqual("Q\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.ClrOutputFields()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.ClrOutputFields();
assertEqual("M 1\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.GetRecentFields()\n"); fprintf(stderr, "COZIR.clearOutputFields()\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.GetRecentFields(); co.clearOutputFields();
assertEqual("M 1\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.inOutputFields()\n");
assertTrue(co.inOutputFields(CZR_NONE));
assertFalse(co.inOutputFields(~CZR_NONE));
fprintf(stderr, "COZIR.getRecentFields()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.getRecentFields();
assertEqual("Q\r\n", state->serialPort[0].dataOut); assertEqual("Q\r\n", state->serialPort[0].dataOut);
// USER MUST READ RETURNED DATA AS IT CAN BE QUITE A LOT. // USER MUST READ RETURNED DATA AS IT CAN BE QUITE A LOT.
} }
unittest(test_eeprom) unittest(test_eeprom_I)
{ {
GodmodeState* state = GODMODE(); GodmodeState* state = GODMODE();
@ -313,21 +332,125 @@ unittest(test_eeprom)
co.init(); co.init();
assertEqual("K 2\r\n", state->serialPort[0].dataOut); assertEqual("K 2\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.SetEEPROM(10, 42)\n"); // needs redo
fprintf(stderr, "COZIR._setEEPROM(10, 42)\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.SetEEPROM(10, 42); co._setEEPROM(10, 42);
assertEqual("P 10 42\r\n", state->serialPort[0].dataOut); assertEqual("P 10 42\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.GetEEPROM(100)\n"); fprintf(stderr, "COZIR._getEEPROM(100)\n");
state->serialPort[0].dataIn = "p 42\r\n"; state->serialPort[0].dataIn = "p 42\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
uint8_t GetEEPROM = co.GetEEPROM(100); uint8_t getEEPROM = co._getEEPROM(100);
assertEqual("p 100\r\n", state->serialPort[0].dataOut); assertEqual("p 100\r\n", state->serialPort[0].dataOut);
assertEqual(42, GetEEPROM); assertEqual(42, getEEPROM);
} }
unittest(test_eeprom_II)
{
GodmodeState* state = GODMODE();
COZIR co(&Serial);
fprintf(stderr, "COZIR.init()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.init();
assertEqual("K 2\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.setAutoCalibrationPreload()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.setAutoCalibrationPreload(123);
assertEqual("P 3 0\r\nP 4 123\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.getAutoCalibrationPreload()\n");
state->serialPort[0].dataIn = "p 01\r\np 42\r\n";
state->serialPort[0].dataOut = "";
uint16_t ACP = co.getAutoCalibrationPreload();
assertEqual("p 3\r\np 4\r\n", state->serialPort[0].dataOut);
assertEqual(298, ACP);
fprintf(stderr, "COZIR.setAutoCalibrationInterval()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.setAutoCalibrationInterval(123);
assertEqual("P 5 0\r\nP 6 123\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.getAutoCalibrationInterval()\n");
state->serialPort[0].dataIn = "p 04\r\np 01\r\n";
state->serialPort[0].dataOut = "";
uint16_t interval = co.getAutoCalibrationInterval();
assertEqual("p 5\r\np 6\r\n", state->serialPort[0].dataOut);
assertEqual(1025, interval);
fprintf(stderr, "COZIR.setAutoCalibrationOn()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.setAutoCalibrationOn();
assertEqual("P 7 1\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.setAutoCalibrationOff()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.setAutoCalibrationOff();
assertEqual("P 7 0\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.getAutoCalibration()\n");
state->serialPort[0].dataIn = "p 01\r\n";
state->serialPort[0].dataOut = "";
uint8_t AC = co.getAutoCalibration();
assertEqual("p 7\r\n", state->serialPort[0].dataOut);
assertEqual(1, AC);
fprintf(stderr, "COZIR.setAutoCalibrationBackgroundConcentration()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.setAutoCalibrationBackgroundConcentration(524);
assertEqual("P 8 2\r\nP 9 12\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.getAutoCalibrationBackgroundConcentration()\n");
state->serialPort[0].dataIn = "p 03\r\np 10\r\n";
state->serialPort[0].dataOut = "";
uint16_t ACBC = co.getAutoCalibrationBackgroundConcentration();
assertEqual("p 8\r\np 9\r\n", state->serialPort[0].dataOut);
assertEqual(778, ACBC);
fprintf(stderr, "COZIR.setAmbientConcentration()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.setAmbientConcentration(1083);
assertEqual("P 10 4\r\nP 11 59\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.getAmbientConcentration()\n");
state->serialPort[0].dataIn = "p 05\r\np 00\r\n";
state->serialPort[0].dataOut = "";
uint16_t AMC = co.getAmbientConcentration();
assertEqual("p 10\r\np 11\r\n", state->serialPort[0].dataOut);
assertEqual(1280, AMC);
fprintf(stderr, "COZIR.setBufferClearTime()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.setBufferClearTime(83);
assertEqual("P 12 0\r\nP 13 83\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.getBufferClearTime()\n");
state->serialPort[0].dataIn = "p 06\r\np 01\r\n";
state->serialPort[0].dataOut = "";
uint16_t BCT = co.getBufferClearTime();
assertEqual("p 12\r\np 13\r\n", state->serialPort[0].dataOut);
assertEqual(1537, BCT);
}
unittest(test_PPM) unittest(test_PPM)
{ {
@ -342,12 +465,14 @@ unittest(test_PPM)
assertEqual("K 2\r\n", state->serialPort[0].dataOut); assertEqual("K 2\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.getPPMFactor()\n"); fprintf(stderr, "COZIR.getPPMFactor()\n");
state->serialPort[0].dataIn = ""; state->serialPort[0].dataIn = "p 01\r\n";
state->serialPort[0].dataOut = ""; state->serialPort[0].dataOut = "";
co.getPPMFactor(); uint16_t ppm = co.getPPMFactor();
assertEqual(".\r\n", state->serialPort[0].dataOut); assertEqual(".\r\n", state->serialPort[0].dataOut);
} assertEqual(1, ppm);
fprintf(stderr, "\n===========================================\n\n");
}
unittest_main() unittest_main()