diff --git a/libraries/Cozir/README.md b/libraries/Cozir/README.md index 834b9a0d..be2309d1 100644 --- a/libraries/Cozir/README.md +++ b/libraries/Cozir/README.md @@ -23,6 +23,11 @@ This version of the library supports only the **Serial** interface. Preferred is a hardware Serial port to connect the sensor but software Serial does work too. +The library (since 0.3.4) a separate class to parse the STREAMING data. +See COZIRParser below. +The Cozir class is focussed on polling and sending commands. + + #### Notes - Read the datasheet before using this library. @@ -212,16 +217,41 @@ Also the user must reset the operating mode either to **CZR_POLLING** or **CZR_S See examples. +## COZIRParser + +Class to parse the output of a COZIR sensor in stream mode. + +## Description + +(added in 0.3.4, experimental) + +The COZIRparser object has a main function called **nextChar(c)** +It needs to be called with all incoming characters from the sensor. + +If a new field is found **nextChar()** returns the field identifier +of the last parsed field (single char) to indicate its value has been +updated, otherwise it returns 0. +The updated value can be accessed with one of the functions, see cozir.h file. + +An example **Cozir_stream_parse.ino** is added to show how to use this class. + +Note: to send commands e.g. outputField selection, to the sensor the COZIR + class is used (which is mostly focussed on polling access). + + + ## Future - improve documentation + - COZIR Parser a separate readme? - matrix functions vs sensor ? - test - test streaming mode - test table / matrix ? - add examples - example COZIR with I2C display? - - example streaming mode parsing. + - example with GREEN YELLOW RED LED? + - examples for COZIRParser. - COZIR I2C class for newer generation ~ same functional interface - multiWire / pin a la PCF8574 lib diff --git a/libraries/Cozir/changelog.md b/libraries/Cozir/changelog.md index 04a19ecd..3ffea8c4 100644 --- a/libraries/Cozir/changelog.md +++ b/libraries/Cozir/changelog.md @@ -2,6 +2,12 @@ # Cozir Changelog +## 0.3.4 2022-02-22 +- added COZIRParser class for streaming mode +- added streaming examples +- minor edits + + ## 0.3.3 2022-02-21 - update readme, - update + add examples diff --git a/libraries/Cozir/cozir.cpp b/libraries/Cozir/cozir.cpp index 76e37013..3125f0d1 100644 --- a/libraries/Cozir/cozir.cpp +++ b/libraries/Cozir/cozir.cpp @@ -1,7 +1,7 @@ // // FILE: Cozir.cpp // AUTHOR: DirtGambit & Rob Tillaart -// VERSION: 0.3.3 +// VERSION: 0.3.4 // PURPOSE: library for COZIR range of sensors for Arduino // Polling Mode // URL: https://github.com/RobTillaart/Cozir @@ -417,4 +417,135 @@ uint16_t COZIR::_getEEPROM2(uint8_t address) +//////////////////////////////////////////////////////////////////////////////// +// +// C0ZIRParser +// +C0ZIRParser::C0ZIRParser() +{ + init(); +} + + +void C0ZIRParser::init() +{ + _light = 0; + _humidity = 0; + _LED_FILT = 0; + _LED_RAW = 0; + _LED_MAX = 0; + _zeroPoint = 0; + _temperature_RAW = 0; + _temperature_FILT = 0; + _LED_signal_FILT = 0; + _LED_signal_RAW = 0; + _temperature_Sensor = 0; + _CO2_FILT = 0; + _CO2_RAW = 0; + _samples = 0; + _PPM = 1; // Note default one + _value = 0; + _field = 0; +} + + +uint8_t C0ZIRParser::nextChar(char c) +{ + uint8_t rv = 0; + switch(c) + { + case '0' ... '9': + _value *= 10; + _value += (c - '0'); + break; + case 'L': + case 'T': + case 'H': + case 'z': + case 'Z': + case 'A': + case 'P': + rv = store(); + _field = c; + _value = 0; + break; + default: + break; + } + return rv; +} + + +float C0ZIRParser::celsius() +{ + return 0.1 * (_temperature_FILT - 1000.0); +} + + +////////////////////////////////// +// +// PRIVATE +// +uint8_t C0ZIRParser::store() +{ + switch(_field) + { + // LIGHT related + case 'L': + _light = _value; + return _field; + case 'D': + _LED_FILT = _value; + return _field; + case 'd': + _LED_RAW = _value; + return _field; + case 'l': + _LED_MAX = _value; + return _field; + case 'o': + _LED_signal_FILT = _value; + return _field; + case 'O': + _LED_signal_RAW = _value; + return _field; + + // TEMPERATURE & HUMIDITY + case 'V': + _temperature_RAW = _value; + return _field; + case 'v': + _temperature_Sensor = _value; + return _field; + case 'T': + _temperature_FILT = _value; + return _field; + case 'H': + _humidity = _value; + return _field; + + // CO2 related + case 'z': + _CO2_RAW = _value; + return _field; + case 'Z': + _CO2_FILT = _value; + return _field; + + // OTHER + case 'h': + _zeroPoint = _value; + return _field; + case 'a': + _samples = _value; + return _field; + case '.': + _PPM = _value; + return _field; + } + return 0; +} + + // -- END OF FILE -- + diff --git a/libraries/Cozir/cozir.h b/libraries/Cozir/cozir.h index 5768853e..b33e43f8 100644 --- a/libraries/Cozir/cozir.h +++ b/libraries/Cozir/cozir.h @@ -1,8 +1,7 @@ #pragma once // // FILE: Cozir.h -// AUTHOR: DirtGambit & Rob Tillaart -// VERSION: 0.3.3 +// VERSION: 0.3.4 // PURPOSE: library for COZIR range of sensors for Arduino // Polling Mode // URL: https://github.com/RobTillaart/Cozir @@ -15,12 +14,15 @@ #include "Arduino.h" -#define COZIR_LIB_VERSION (F("0.3.3")) +#define COZIR_LIB_VERSION (F("0.3.4")) -// OUTPUTFIELDS +// OUTPUT FIELDS // See datasheet for details. // These defines can be OR-ed for the SetOutputFields command +// +#define CZR_UNKNOWN_2 0x8000 // returns P 00128 ? +#define CZR_UNKNOWN_1 0x4000 // returns E 00016 ? #define CZR_LIGHT 0x2000 #define CZR_HUMIDITY 0x1000 #define CZR_FILTLED 0x0800 @@ -165,5 +167,78 @@ private: }; + +//////////////////////////////////////////////////////////////////////////////// +// +// C0ZIRParser +// +// used to parse the stream from a COZIR CO2 sensor. +// Note: one can comment fields / code not used to minimize footprint. +// +class C0ZIRParser +{ +public: + C0ZIRParser(); + + void init(); + + // returns field char if a field is completed, 0 otherwise. + uint8_t nextChar(char c); + + // FETCH LAST READ VALUES + float celsius(); + float fahrenheit() { return (celsius() * 1.8) + 32; }; + float kelvin() { return celsius() + 273.15; }; + float humidity() { return 0.1 * _humidity; }; + + uint16_t light() { return _light; }; + uint16_t ledFilt() { return _LED_FILT; }; + uint16_t ledRaw() { return _LED_RAW; }; + uint16_t ledMax() { return _LED_MAX; }; + uint16_t ledSignalFilt() { return _LED_signal_FILT; }; + uint16_t ledSignalRaw() { return _LED_signal_RAW; }; + + uint16_t zeroPoint() { return _zeroPoint; }; + uint16_t tempFilt() { return _temperature_FILT; }; + uint16_t tempRaw() { return _temperature_RAW; }; + uint16_t tempSensor() { return _temperature_Sensor; }; + + uint16_t CO2() { return _CO2_FILT; }; + uint16_t CO2Raw() { return _CO2_RAW; }; + + uint16_t samples() { return _samples; }; + uint16_t getPPMFactor() { return _PPM; } + + +private: + // FIELD ID character + uint16_t _light; // L + uint16_t _humidity; // H + uint16_t _LED_FILT; // D + uint16_t _LED_RAW; // d + uint16_t _LED_MAX; // l // el not one + uint16_t _zeroPoint; // h + uint16_t _temperature_RAW; // V + uint16_t _temperature_FILT; // T + uint16_t _LED_signal_FILT; // o // oo not zero + uint16_t _LED_signal_RAW; // O // oo not zero + uint16_t _temperature_Sensor; // v + uint16_t _CO2_FILT; // Z + uint16_t _CO2_RAW; // z + + // not output fields sec but useful. + uint16_t _samples; // a + uint16_t _PPM; // . // point + + + // parsing helpers + uint32_t _value; + uint8_t _field; + + // returns field char if a field is completed, 0 otherwise. + uint8_t store(); +}; + + // -- END OF FILE -- diff --git a/libraries/Cozir/examples/Cozir_SWSerial_echo/Cozir_SWSerial_echo.ino b/libraries/Cozir/examples/Cozir_SWSerial_echo/Cozir_SWSerial_echo.ino index cde93a72..52e2488b 100644 --- a/libraries/Cozir/examples/Cozir_SWSerial_echo/Cozir_SWSerial_echo.ino +++ b/libraries/Cozir/examples/Cozir_SWSerial_echo/Cozir_SWSerial_echo.ino @@ -22,7 +22,7 @@ void setup() { sws.begin(9600); - Serial.begin(9600); + Serial.begin(115200); Serial.println(__FILE__); Serial.println(); diff --git a/libraries/Cozir/examples/Cozir_echo/Cozir_echo.ino b/libraries/Cozir/examples/Cozir_echo/Cozir_echo.ino index ad5efa8d..e030084e 100644 --- a/libraries/Cozir/examples/Cozir_echo/Cozir_echo.ino +++ b/libraries/Cozir/examples/Cozir_echo/Cozir_echo.ino @@ -23,7 +23,7 @@ void setup() { Serial1.begin(9600); - Serial.begin(9600); + Serial.begin(115200); Serial.println(__FILE__); Serial.println(); diff --git a/libraries/Cozir/examples/Cozir_interactive/Cozir_interactive.ino b/libraries/Cozir/examples/Cozir_interactive/Cozir_interactive.ino index 750ee73a..c90aa444 100644 --- a/libraries/Cozir/examples/Cozir_interactive/Cozir_interactive.ino +++ b/libraries/Cozir/examples/Cozir_interactive/Cozir_interactive.ino @@ -37,6 +37,9 @@ void loop() char c = Serial.read(); switch (toupper(c)) { + case '0': + czr.setOperatingMode(CZR_COMMAND); + break; case '1': czr.setOperatingMode(CZR_STREAMING); break; @@ -118,6 +121,7 @@ void menu() Serial.println(); Serial.println("-- COZIR GC0034 --"); Serial.println(); + Serial.println(" 0 Command mode (low power)"); Serial.println(" 1 Continuous mode"); Serial.println(" 2 Polling mode"); Serial.println(); diff --git a/libraries/Cozir/examples/Cozir_stream_CO2/.arduino-ci.yml b/libraries/Cozir/examples/Cozir_stream_CO2/.arduino-ci.yml new file mode 100644 index 00000000..899c46aa --- /dev/null +++ b/libraries/Cozir/examples/Cozir_stream_CO2/.arduino-ci.yml @@ -0,0 +1,11 @@ +compile: + # Choosing to run compilation tests on 2 different Arduino platforms + platforms: + # - uno + - due + # - zero + - leonardo + # - m4 + # - esp32 + # - esp8266 + - mega2560 diff --git a/libraries/Cozir/examples/Cozir_stream_CO2/Cozir_stream_CO2.ino b/libraries/Cozir/examples/Cozir_stream_CO2/Cozir_stream_CO2.ino new file mode 100644 index 00000000..8a42146c --- /dev/null +++ b/libraries/Cozir/examples/Cozir_stream_CO2/Cozir_stream_CO2.ino @@ -0,0 +1,96 @@ +// +// FILE: Cozir_stream_CO2.ino +// AUTHOR: Rob Tillaart +// PURPOSE: demo of Cozir lib - stand alone stream parsing. +// URL: https://github.com/RobTillaart/Cozir +// http://forum.arduino.cc/index.php?topic=91467.0 +// +// Note: this sketch needs a MEGA or a Teensy that supports a second +// Serial port named Serial1 +// +// to be used with the Serial Plotter. + + +#include "Arduino.h" +#include "cozir.h" + +COZIR czr(&Serial1); + + +uint32_t F_CO2 = 0; // CO2 FILTERED +uint32_t R_CO2 = 0; // CO2 RAW +uint32_t tmp = 0; // temporary buffer + +// 0 = none +// Z = filtered co2 +// z = raw co2 +uint8_t field = 0; // which field is parsed + +uint32_t lastPrint = 0; // last time fields are displayed. + + +void setup() +{ + Serial1.begin(9600); + czr.init(); + + Serial.begin(115200); + // Serial.print("COZIR_LIB_VERSION: "); + // Serial.println(COZIR_LIB_VERSION); + // Serial.println(); + + Serial.print("FILTERED\t"); + Serial.println("RAW"); + Serial.println(); + + // set to streaming explicitly. + czr.setOperatingMode(CZR_STREAMING); + // set digifilter on an average value + czr.setDigiFilter(16); + // select RAW and FILTERED CO2 + czr.setOutputFields(CZR_DEFAULT); + delay(1000); +} + + +void loop() +{ + if (Serial1.available()) + { + char c = Serial1.read(); + switch (c) + { + case 'Z': // FILTERED CO2 + field = 'Z'; + break; + case 'z': // RAW CO2 + field = 'z'; + break; + case '0' ... '9': + tmp *= 10; + tmp += c - '0'; + break; + case ' ': + case '\n': + case '\r': + if (tmp > 0 && field == 'Z') F_CO2 = tmp; + if (tmp > 0 && field == 'z') R_CO2 = tmp; + tmp = 0; + break; + default: + break; + } + } + + if (millis() - lastPrint > 500) + { + lastPrint += 500; + Serial.print(F_CO2); + Serial.print("\t"); + Serial.print(R_CO2); + Serial.println(); + } +} + + +// -- END OF FILE -- diff --git a/libraries/Cozir/examples/Cozir_stream_parse/.arduino-ci.yml b/libraries/Cozir/examples/Cozir_stream_parse/.arduino-ci.yml new file mode 100644 index 00000000..899c46aa --- /dev/null +++ b/libraries/Cozir/examples/Cozir_stream_parse/.arduino-ci.yml @@ -0,0 +1,11 @@ +compile: + # Choosing to run compilation tests on 2 different Arduino platforms + platforms: + # - uno + - due + # - zero + - leonardo + # - m4 + # - esp32 + # - esp8266 + - mega2560 diff --git a/libraries/Cozir/examples/Cozir_stream_parse/Cozir_stream_parse.ino b/libraries/Cozir/examples/Cozir_stream_parse/Cozir_stream_parse.ino new file mode 100644 index 00000000..79dc9515 --- /dev/null +++ b/libraries/Cozir/examples/Cozir_stream_parse/Cozir_stream_parse.ino @@ -0,0 +1,80 @@ +// +// FILE: Cozir_stream_parse.ino +// AUTHOR: Rob Tillaart +// PURPOSE: demo of Cozir lib +// URL: https://github.com/RobTillaart/Cozir +// http://forum.arduino.cc/index.php?topic=91467.0 +// +// Note: this sketch needs a MEGA or a Teensy that supports a second +// Serial port named Serial1 +// +// to be used with the Serial Plotter. + + +#include "Arduino.h" +#include "cozir.h" + +COZIR czr(&Serial1); +C0ZIRParser czrp; + + +uint32_t F_CO2 = 0; // CO2 FILTERED +uint32_t R_CO2 = 0; // CO2 RAW +uint32_t tmp = 0; // temporary buffer + +// 0 = none +// Z = filtered co2 +// z = raw co2 +uint8_t field = 0; // which field is parsed + +uint32_t lastPrint = 0; // last time fields are displayed. + + +void setup() +{ + Serial1.begin(9600); + czr.init(); + + Serial.begin(115200); + // Serial.print("COZIR_LIB_VERSION: "); + // Serial.println(COZIR_LIB_VERSION); + // Serial.println(); + + Serial.print("FILTERED\t"); + Serial.println("RAW"); + Serial.println(); + + // set to streaming explicitly. + czr.setOperatingMode(CZR_STREAMING); + // set digifilter on an average value + czr.setDigiFilter(16); + // select RAW and FILTERED CO2 + czr.setOutputFields(CZR_DEFAULT); + // czr.setOutputFields(CZR_HUMIDITY | CZR_RAWTEMP | CZR_RAWCO2); + delay(1000); +} + + +void loop() +{ + if (Serial1.available()) + { + char c = Serial1.read(); + field = czrp.nextChar(c); + if (field != 0) + { + // shows all values + // Serial.print(czrp.celsius()); + // Serial.print("\t"); + // Serial.print(czrp.humidity()); + // Serial.print("\t"); + Serial.print(czrp.CO2()); + Serial.print("\t"); + Serial.print(czrp.CO2Raw()); + Serial.println(); + } + } +} + + +// -- END OF FILE -- diff --git a/libraries/Cozir/keywords.txt b/libraries/Cozir/keywords.txt index dc926d22..e8a628b7 100644 --- a/libraries/Cozir/keywords.txt +++ b/libraries/Cozir/keywords.txt @@ -2,6 +2,7 @@ # Data types (KEYWORD1) COZIR KEYWORD1 +C0ZIRParser KEYWORD1 # Methods and Functions (KEYWORD2) @@ -58,7 +59,7 @@ getConfiguration KEYWORD2 COZIR_LIB_VERSION LITERAL1 -# OUTPPUTFIELDS +# OUTPUT FIELDS CZR_LIGHT LITERAL1 CZR_HUMIDITY LITERAL1 @@ -74,6 +75,7 @@ CZR_SENSTEMP LITERAL1 CZR_FILTCO2 LITERAL1 CZR_RAWCO2 LITERAL1 CZR_NONE LITERAL1 +CZR_DEFAULT LITERAL1 CZR_HTC LITERAL1 CZR_ALL LITERAL1 diff --git a/libraries/Cozir/library.json b/libraries/Cozir/library.json index 9e84bc46..c0129039 100644 --- a/libraries/Cozir/library.json +++ b/libraries/Cozir/library.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/RobTillaart/Cozir.git" }, - "version": "0.3.3", + "version": "0.3.4", "license": "MIT", "frameworks": "arduino", "platforms": "*", diff --git a/libraries/Cozir/library.properties b/libraries/Cozir/library.properties index c9a30eaf..15283b38 100644 --- a/libraries/Cozir/library.properties +++ b/libraries/Cozir/library.properties @@ -1,5 +1,5 @@ name=Cozir -version=0.3.3 +version=0.3.4 author=Rob Tillaart , DirtGambit maintainer=Rob Tillaart sentence=Arduino library for COZIR range of CO2 sensors. Polling mode only.