{"id":24866,"date":"2022-03-19T17:12:21","date_gmt":"2022-03-19T08:12:21","guid":{"rendered":"https:\/\/www.souichi.club\/?p=24866"},"modified":"2022-03-19T17:14:01","modified_gmt":"2022-03-19T08:14:01","slug":"ccs811","status":"publish","type":"post","link":"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/","title":{"rendered":"Measurement of eCO2 and VOC (Volatile Organic Compounds) with CCS811"},"content":{"rendered":"\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-69f48d3d274b9\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #454e5c;color:#454e5c\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #454e5c;color:#454e5c\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-69f48d3d274b9\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#CCS811\" >CCS811<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#What_is_eCO2\" >What is eCO2?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#What_is_TVOC\" >What is TVOC?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#Specifications\" >Specifications<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#Appearance\" >Appearance<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#NTC_Thermistor\" >NTC Thermistor<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#Baseline_application_time\" >Baseline application time<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#Other_Parts\" >Other Parts<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#ESP32_module\" >ESP32 module<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#OLED_Module\" >OLED Module<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#Library_Installation\" >Library Installation<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#CCS811-2\" >CCS811<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#SSD1306\" >SSD1306<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#Wiring_Diagram\" >Wiring Diagram<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#Scketch\" >Scketch<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#ccs811_oledino\" >ccs811_oled.ino<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#supplementary_explanation\" >supplementary explanation<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#ccs811_hw_reset\" >ccs811_hw_reset<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#ccs811_wake\" >ccs811_wake<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#ccs811_sleep\" >ccs811_sleep<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#setup\" >setup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#loop\" >loop<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/www.souichi.club\/en\/m5stack\/ccs811\/#Execution\" >Execution<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"CCS811\"><\/span>CCS811<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>This article describes the measurement of eCO2 (equivalent carbon dioxide) and TVOC (total volatile organic compounds) with ESP32 and CCS811 module and display on OLED display.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_is_eCO2\"><\/span>What is eCO2?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The CO2 (carbon dioxide) that can be measured by CCS811 is called eCO2 (equivalent CO2), which is not exactly the same as CO2.<\/p>\n\n\n\n<p>The following description can be found <a href=\"https:\/\/www.sparkfun.com\/news\/2369\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"on this site\">on this site<\/a>.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>&#8220;It&#8217;s important to recognize that the CCS811 cannot measure CO2 and that the &#8220;equivalent CO2\u2033 being reported by the CCS811 has nothing to do with actual CO2 present in the area.&#8221;<\/p><cite>https:\/\/www.sparkfun.com\/news\/2369<\/cite><\/blockquote>\n\n\n\n<p>When the cap of a magic pen was opened and placed close to the sensor, the CO2 concentration of a commercial CO2 measuring instrument (NDIR-based product costing about $180) did not change, but the eCO2 value of the CCS811 increased.<\/p>\n\n\n\n<p>When the CCS811&#8217;s eCO2 value increased in response to volatile gases, it seemed that the CCS811&#8217;s eCO2 value also increased in response to volatile gases, although it could be used as a CO2 measurement if there were &#8220;no gases around.<\/p>\n\n\n\n<p>However, from the viewpoint of &#8220;whether indoor ventilation is necessary or not,&#8221; there is no problem with eCO2, and in fact, eCO2 may be easier to use because it reacts to volatile gases in addition to carbon dioxide.<\/p>\n\n\n\n<p>If you want to measure purely CO2 concentration, I think MH-Z19C (NDIR method), which I wrote about in a <a href=\"https:\/\/www.souichi.club\/en\/m5stack\/co2sensor-mhz19c\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"previous article\">previous article<\/a>, is better.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_is_TVOC\"><\/span>What is TVOC?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>TVOC (Total Volatile Organic Compounds) is a generic term for organic compounds that become gas in the atmosphere.<\/p>\n\n\n\n<p>TVOC is effective as an indicator for detecting &#8220;air pollution&#8221; because its value increased in response to gases such as paint, ink, and gasoline.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Specifications\"><\/span>Specifications<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The main specifications are as follows<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>eCO2: 400 &#8211; 8,192 ppm (parts per million)<\/li><li>TVOC: 0 &#8211; 1187 ppb (parts per billion)<\/li><li>I2C communication: Address 0x5A or 0x5B<\/li><li>Voltage: 3.3V<\/li><li>Conditioning time: Valid values are output at least 20 minutes after startup<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Appearance\"><\/span>Appearance<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Pins, from top.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>RST: Used for hardware reset<\/li><li>INT: Output when measurement ends or threshold is exceeded (not used this time)<\/li><li>WAK: Used to switch between startup and hibernation to save power. High:hibernation, Low:startup<\/li><li>SCL: SCL<\/li><li>SDA: SDA<\/li><li>3.3V: Power supplied by ESP32<\/li><li>GND: GND<\/li><\/ul>\n\n\n\n<p>There is a terminal for connecting an NTC thermistor at the bottom center.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a class=\"r_image\" href=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-01.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-01.jpg?resize=282%2C283&#038;ssl=1\" alt=\"CCS811 surface\" class=\"wp-image-24829\" width=\"282\" height=\"283\" srcset=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-01.jpg?w=1127&amp;ssl=1 1127w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-01.jpg?resize=768%2C771&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-01.jpg?resize=80%2C80&amp;ssl=1 80w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-01.jpg?resize=320%2C320&amp;ssl=1 320w\" sizes=\"auto, (max-width: 282px) 100vw, 282px\" \/><\/a><\/figure>\n\n\n\n<p>The image of the back side is as follows.<\/p>\n\n\n\n<p>The pin slightly below the center is the I2C address control pin, which is 0x5B (default) when open, and 0x5A when shorted, allowing the I2C address to be changed.<\/p>\n\n\n\n<p>The pull-up resistor in the lower center is normally left short-circuited.<\/p>\n\n\n\n<p>When opened, the pull-up resistor is disabled.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a class=\"r_image\" href=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-02.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-02.jpg?resize=242%2C226&#038;ssl=1\" alt=\"CCS811 back side\" class=\"wp-image-24830\" width=\"242\" height=\"226\" srcset=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-02.jpg?w=969&amp;ssl=1 969w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-02.jpg?resize=768%2C716&amp;ssl=1 768w\" sizes=\"auto, (max-width: 242px) 100vw, 242px\" \/><\/a><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"NTC_Thermistor\"><\/span>NTC Thermistor<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>There is an optional NTC(Negative Thermal Coefficient) thermistor that can be added by soldering to compensate for gas concentration based on ambient temperature, but it seems that the temperature guarantee is no longer supported (the connector is still there).<\/p>\n\n\n\n<p>It said that an external <a href=\"https:\/\/www.souichi.club\/en\/raspberrypi\/bme280\/\" target=\"_blank\" rel=\"noreferrer noopener\">sensor such as BME280<\/a> is recommended instead of NTC .<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Baseline_application_time\"><\/span>Baseline application time<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>There is a function that automatically corrects resistance values in response to variations in sensor manufacturing and changes over time.<\/p>\n\n\n\n<p>Since the correction is made in 24 hours, it is better to assume that the correct value is output after 24 hours or more, in addition to the aforementioned conditioning time (20 minutes).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Other_Parts\"><\/span>Other Parts<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Other main parts prepared are as follows.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ESP32_module\"><\/span>ESP32 module<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The pin layout is the same as <a href=\"https:\/\/www.souichi.club\/en\/m5stack\/esp32-pin-layout\/#ESP32_DEVKIT_V1\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 DEVKIT V1<\/a> (30 pins).<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a class=\"r_image\" href=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-01.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-01.jpg?resize=480%2C277&#038;ssl=1\" alt=\"ESP-WROOM-32 module\" class=\"wp-image-24993\" width=\"480\" height=\"277\" srcset=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-01.jpg?w=1920&amp;ssl=1 1920w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-01.jpg?resize=768%2C443&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-01.jpg?resize=1536%2C886&amp;ssl=1 1536w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"OLED_Module\"><\/span>OLED Module<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The 0.96-inch OLED (Organic Light Emitting Diode) display was used.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a class=\"r_image\" href=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-02.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-02.jpg?resize=320%2C279&#038;ssl=1\" alt=\"OLED Display surface\" class=\"wp-image-24997\" width=\"320\" height=\"279\" srcset=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-02.jpg?w=1280&amp;ssl=1 1280w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-02.jpg?resize=768%2C670&amp;ssl=1 768w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a class=\"r_image\" href=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-03.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-03.jpg?resize=320%2C280&#038;ssl=1\" alt=\"OLED Display back side\" class=\"wp-image-24999\" width=\"320\" height=\"280\" srcset=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-03.jpg?w=1280&amp;ssl=1 1280w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-03.jpg?resize=768%2C671&amp;ssl=1 768w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><\/figure>\n\n\n\n<p>The specifications are as follows<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Size: 0.96 inches<\/li><li>Voltage: 3.3V to 5V<\/li><li>Resolution: 128 \u00d7 64<\/li><li>I2C connection: 0x3C (default) or 0x3D<\/li><li>SSD1306 Compatible<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Library_Installation\"><\/span>Library Installation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The development environment was Arduino IDE (Ver 1.8.19).<\/p>\n\n\n\n<p>Install the necessary libraries in advance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"CCS811-2\"><\/span>CCS811<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p><a href=\"https:\/\/github.com\/sparkfun\/SparkFun_CCS811_Arduino_Library\/archive\/master.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Download the library<\/a> from <a href=\"https:\/\/github.com\/sparkfun\/SparkFun_CCS811_Arduino_Library\/\" target=\"_blank\" rel=\"noreferrer noopener\">sparkfun&#8217;s Github<\/a> and add the library from the Arduino IDE by going to Sketch-&gt;Include Library-&gt;Add .ZIP Library.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"SSD1306\"><\/span>SSD1306<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Install the SSD1306 library for OLED displays.<\/p>\n\n\n\n<p>From the Arduino IDE, go to Tools &gt; Manage Libraries and search for &#8220;SSD1306&#8221; in the search field to install Adafruit SSD1306.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a class=\"r_image\" href=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-04.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-04.png?resize=590%2C332&#038;ssl=1\" alt=\"Adafruit SSD1306 Library\" class=\"wp-image-25004\" width=\"590\" height=\"332\" srcset=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-04.png?w=787&amp;ssl=1 787w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-04.png?resize=768%2C432&amp;ssl=1 768w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Wiring_Diagram\"><\/span>Wiring Diagram<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The wiring is as follows.<\/p>\n\n\n\n<p>INT is not connected this time, and RST and WAK are used. However, if you simply want to acquire and display values without considering power saving, it is not necessary to connect them.<\/p>\n\n\n\n<p>It is possible to acquire values only by connecting GND, 3.3V, SDA, and SCL.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a class=\"r_image\" href=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-05.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-05.png?resize=812%2C540&#038;ssl=1\" alt=\"CCS811 Wiring Diagram\" class=\"wp-image-25006\" width=\"812\" height=\"540\" srcset=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-05.png?w=1624&amp;ssl=1 1624w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-05.png?resize=768%2C511&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-en-05.png?resize=1536%2C1021&amp;ssl=1 1536w\" sizes=\"auto, (max-width: 812px) 100vw, 812px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Scketch\"><\/span>Scketch<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The sketch measures eCO2 and TVOC at approximately 60-second intervals and displays them on the display.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ccs811_oledino\"><\/span>ccs811_oled.ino<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"line-numbers\"><code class=\"lang-cpp\">\/*\n * Created on Sun Feb 27 21:46:24 2022\n *  \n * CCS811 Co2 Sensor &amp; OLED Display\n * \n * @author: Souichirou Kikuchi\n *\/\n \n#include &lt;Wire.h&gt; \/\/ I2C\n#include &lt;SparkFunCCS811.h&gt; \/\/ CCS811\n#include &lt;Adafruit_SSD1306.h&gt; \/\/ OLED Display\n\n#define CCS811_ADDRESS 0x5B \/\/ CCS811 I2C Address\n#define SCREEN_ADDRESS 0x3C \/\/ OLED Display Address\n\n\/\/ I2C Pin\nconstexpr short int SDA_PIN = 21;\nconstexpr short int SCL_PIN = 22;\n\nconstexpr short int RESET_PIN = 5;\nconstexpr short int WAKE_UP_PIN = 4;\n\n\/\/ OLED Display\nconstexpr short int SCREEN_WIDTH = 128; \/\/ OLED display width, in pixels\nconstexpr short int SCREEN_HEIGHT = 64; \/\/ OLED display height, in pixels\nconstexpr short int OLED_RESET = 4; \/\/ Reset pin # (or -1 if sharing Arduino reset pin)\n\nCCS811 eco2_sensor(CCS811_ADDRESS); \/\/ eCo2 Sensor \nAdafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &amp;Wire, OLED_RESET); \/\/ OLEDDisplay\n\nvoid ccs811_hw_reset() { \/\/ CCS811 Hardware Reset\n    pinMode(RESET_PIN, OUTPUT);\n    digitalWrite(RESET_PIN, LOW);\n    delay(10);\n    digitalWrite(RESET_PIN, HIGH);\n}\n\nvoid ccs811_wake() { \/\/ Wake up\n    digitalWrite(WAKE_UP_PIN, LOW);\n    delay(10);\n}\n\nvoid ccs811_sleep() { \/\/ Lower power consumption\n    digitalWrite(WAKE_UP_PIN, HIGH);\n}\n\nvoid setup()\n{\n    int cnt;\n    const short int MAX_RETRY = 10;\n\n    Serial.begin(115200);\n    Serial.println(\"Program Start\");\n\n    pinMode(WAKE_UP_PIN, OUTPUT);\n    ccs811_hw_reset();\n    ccs811_wake();\n\n    \/\/ I2C\n    Wire.begin(SDA_PIN, SCL_PIN);\n\n    \/\/ CCS811\n    cnt = 0;\n    while ((eco2_sensor.begin() == false) and (cnt &lt; MAX_RETRY)) {\n        Serial.print(\"CCS811 initialize attempt\");\n        Serial.println(cnt);\n        delay(1000);\n        cnt++;\n    }\n    if (cnt &gt;= MAX_RETRY){\n        Serial.println(\"CCS811 initialize Error.\");\n    } else {\n        Serial.println(\"CCS811 Initialized.\");\n    }\n    ccs811_sleep();\n\n    \/\/ OLED Display Initialize\n    if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {\n        Serial.println(F(\"SSD1306 allocation failed\"));\n    }\n    \/\/ Display settings\n    display.setTextSize(1); \/\/ size 1\uff5e5\n    display.setTextColor(SSD1306_WHITE);\n    display.display();\n    delay(10000);\n}\n\nvoid loop()\n{\n    short int co2_ppm;\n    short int voc_ppb;\n    int co2_ttl;\n    int voc_ttl;\n    std::vector&lt;int&gt; co2List;\n    std::vector&lt;int&gt; vocList;\n    constexpr short int DATA_COUNT = 5; \/\/ Number of data acquisition\n\n    ccs811_wake();\n    co2List.clear();\n    vocList.clear();\n    \/\/ Maximum and minimum values are truncated\n    if (eco2_sensor.dataAvailable()) {\n        for (int i = 0; i &lt; DATA_COUNT; i++) {\n            eco2_sensor.readAlgorithmResults();\n            co2List.push_back(eco2_sensor.getCO2());\n            vocList.push_back(eco2_sensor.getTVOC());\n            delay(1000);\n        }\n    } else {\n        Serial.println(\"CCS811 not Available\");\n    }\n    ccs811_sleep();\n\n    std::sort(co2List.begin(), co2List.end());\n    std::sort(vocList.begin(), vocList.end());\n    co2List.pop_back(); \/\/ Delete trailing (maximum) data \n    vocList.pop_back();\n    co2List.erase(co2List.begin()); \/\/ Delete the first (minimum) data\n    vocList.erase(vocList.begin());\n\n    \/\/ average\n    co2_ttl = 0;\n    voc_ttl = 0;\n    \/\/ for (int i = 0; i &lt; DATA_COUNT-2; i++) {\n    for (int i = 0; i &lt; co2List.size(); i++) {\n\n        Serial.println(co2List[i]);\n        \n        co2_ttl += co2List[i];\n        voc_ttl += vocList[i];\n    }\n    co2_ppm = co2_ttl \/ co2List.size();\n    voc_ppb = voc_ttl \/ vocList.size();\n\n    display.clearDisplay(); \/\/ Buffer Clear\n    display.setCursor(0, 0); \/\/ X Y\n    display.println(\"eCO2:\" + String(co2_ppm) + \" ppm\");\n    display.setCursor(0, 30); \/\/ X Y\n    display.println(\"VOC:\" + String(voc_ppb) + \" ppb\");\n    display.display();\n\n    delay(60000); \/\/ 60\u79d2\n}<\/code><\/pre>\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"supplementary_explanation\"><\/span>supplementary explanation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ccs811_hw_reset\"><\/span>ccs811_hw_reset<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Function to hardware reset the CCS811.<\/p>\n\n\n\n<p>Low and High are sent to the reset pin to reset.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ccs811_wake\"><\/span>ccs811_wake<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Function to start up CCS811.<\/p>\n\n\n\n<p>Low is sent to the Wake up pin.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ccs811_sleep\"><\/span>ccs811_sleep<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Function to put the CCS811 into power-saving mode.<\/p>\n\n\n\n<p>High is sent to the Wake up pin.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"setup\"><\/span>setup<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Initial Processing.<\/p>\n\n\n\n<p>Hardware reset and initialization of the CCS811 and initialization of the OLED display.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"loop\"><\/span>loop<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>CCS811, however, when I tried to obtain the value continuously every second, I found that there was a slight difference each time.<\/p>\n\n\n\n<p>In addition, it was confirmed that a large value was sometimes suddenly detected, and one second later, the value returned to the original value or thereabouts.<\/p>\n\n\n\n<p>Example: 447 \u2192 449 \u2192 680 \u2192 445 \u2192 450 \u2026<\/p>\n\n\n\n<p>For this reason, I consider it problematic to assume that a value is positive after only one measurement, so I obtain the value several times in succession, truncate the maximum and minimum values, and take the average of all values except the truncated ones.<\/p>\n\n\n\n<p>In the program, the maximum and minimum values are truncated after five consecutive measurements, and the average of the three intermediate data is taken.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Execution\"><\/span>Execution<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The execution is shown below.<\/p>\n\n\n\n<p>eCo2 concentration and TVOC are measured at 60 second intervals and displayed on the display.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a class=\"r_image\" href=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-06.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-06.jpg?resize=480%2C364&#038;ssl=1\" alt=\"execution\" class=\"wp-image-24856\" width=\"480\" height=\"364\" srcset=\"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-06.jpg?w=1920&amp;ssl=1 1920w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-06.jpg?resize=768%2C582&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-06.jpg?resize=1536%2C1165&amp;ssl=1 1536w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><\/figure>\n\n\n\n<p>This concludes this article.<\/p>\n\n\n<div class=\"postscript_balloon\">Finally.<\/div>\n\n\n<p>I hope this article will be useful to someone somewhere.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Article on the measurement of eCO2 (equivalent CO2) and TVOC (Total Volatile Organic Compounds) with ESP32 and CCS811 and display on OLED display.<\/p>\n","protected":false},"author":5,"featured_media":24856,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"en_US","_original_post":"https:\/\/www.souichi.club\/?p=24811","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[238],"tags":[],"class_list":["post-24866","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-m5stack","en-US"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.souichi.club\/wp-content\/uploads\/ccs811-06.jpg?fit=1920%2C1456&ssl=1","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/posts\/24866","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/comments?post=24866"}],"version-history":[{"count":19,"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/posts\/24866\/revisions"}],"predecessor-version":[{"id":25018,"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/posts\/24866\/revisions\/25018"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/media\/24856"}],"wp:attachment":[{"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/media?parent=24866"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/categories?post=24866"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.souichi.club\/wp-json\/wp\/v2\/tags?post=24866"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}