Giter Site home page Giter Site logo

wifwaf / mh-z19 Goto Github PK

View Code? Open in Web Editor NEW
192.0 9.0 39.0 3.49 MB

For Arduino Boards (&ESP32). Additional Examples/Commands., Hardware/Software Serial

License: GNU Lesser General Public License v3.0

C++ 100.00%
mh-z19 mh-z19b mhz19b mhz19 esp32 arduino sensor analog uart

mh-z19's Introduction

Version

A Quick Note on Fake MH-Z19's

A fake version is said to be in circulation which differs in hardware, and at a minimum, ppm stability. If you suspect your sensor is fake or want to be sure, then check with the video here by Hix Field and Revspace's article for more information.

MH-Z19X

An Arduino library for the MH-Z19X CO2 sensor, which unlocks commands while supporting both software/hardware serial.

Recovery for Dysfunctional Sensors:

See examples for the recovery code. *Note, Only use if your sensor is not recoverable by other means as it recklessly calls span.

Features:

  • Automatically sends "autocalibration off".
  • Filter mode, to detect invalid readings when sensor is recovering from power loss / boot (see example)
  • Option to print communcation between device and sensor (for debugging)
  • Communication error checking
  • Examples

My original notes (somewhat ravings) are here

Commands


Additions Existing
CO2 Unlimited CO2 Limited
CO2 as Raw Temperature as Whole Integer
Custom Range / Span Request CO2 Calibration
Reset Sensor ABC On / Off
Get Firmware Version Retrieve Accuracy
Get Background CO2 Value
Get Range Value
Get Last Response
^Get ABC Status

^* submitted by SFeli

"Usage"


The library can be found in the IDE/IO library manager. Alternatively, simply clone this library to your working library folder and include "MHZ19.h" in your main sketch.

If you are having issues with specific boards, please contact me (find my details below)

"A Bit About the Sensor"


Advice: The MH-Z19 works best in the Range of 2000ppm, outside of this accuracy begins to fall away; this is supported by documentation. I would suggest keeping to this range if you require accuracy.

Relevant Datasheets

  • The Englisih datasheet for the MH-Z19: MH-Z19

  • The English datasheet for the non-JST MH-Z19B version: MH-Z19B NON-JST.

  • The Chinese datasheet for the JST MH-Z19B version (more detailed): MH-Z19B JST.

Auto Calibration: The MH-Z19 is a sensor that is designed to be powered on and rarely turned off. The sensor calibrates over time (if autocalibration is on) using the lowest CO2 observed in the prior 24 hours). After 3 weeks, a value is stored with an accuracy rating, this can be requested using getAccuracy(). ABC must be disabled each day, however this is handled by the library.

Calibration: If you plan to manually calibrate sensor (in my experience this is often be better) then it's important to be aware that Zero calibration does not refer to 0ppm (often a nitrogen environment), instead it refers to 400ppm.

Background Calibration: It's currently unclear how to change this, if possible at all. The value stored on the MH-Z19 and is set to 400ppm. This is used as the zeroing point.

Zero Calibration: This can be made in two ways: By pulling the zero HD low (0V) for 7 Secs, or be sending command 135 (0x87). As above, the Zero refers to the background CO2 value of 400ppm, not 0ppm. Currently testing is the ability to send an adjustment with command at byte 7, however it is unclear the affects this has.

Range: This is essentially your highest and lowest CO2 being measured. 2000ppm is advised. Changing the value usually requires span calibration (diffiuclt), however if you intend to measure abvoe 2000 ppm this can increase accuracy.

Span: I highly recommend avoiding this command unless you have the equipment to do so. It requires the sensor to be at the ppm you are setting it to, e.g. 2000ppm. Roughly, it's difference between lowest and highest range points, for this sensor, it's the same value as range. From tiral and error, it's usually best sent last in the calibrations sequence.

Alarm: The analog output is located on the brown wire on the JST version. On the non-JST version it can be found on the far side, beside the Rx pin. It's unclear at the moment how to change the threshold and is not affected by Range. However, it is possible to attach an amplifier to the Analog Out pin and create an interrupt.

Analog Out: An additional feature of MH-Z19. The output in mV corresponds to ppm when using a range of 2000ppm. Alternatively, calculations can be made to adjust the value (See Examples).

Main Priorities:


  • Reduce memory usage

Additional Disclaimer


THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Authors


Myself, you can find my contact details below.

License


This project is licensed under the Lesser General Public License v3.0 License - see the LICENSE.md file for details

Acknowledgments


This library was originaly inspired by Strange-V's work! https://github.com/strange-v/MHZ19;

Feedback


This is one of my first pieces of code, so lots of room for imporvement, feel free to provide constructive feedback; [email protected]

If this library was particularly helpful, and you feel like funding a replacement sensor (brutalised from testing!) Donate

mh-z19's People

Contributors

arminjo avatar bitboxx avatar drawlerr avatar hixfield avatar mpparsley avatar per1234 avatar schumar avatar sfeli avatar wifwaf avatar yoihito avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mh-z19's Issues

How to calibrate the sensor properly?

Hi, thank you for this great library.

I've checked and run the calibration example, but it didn't help me.
I was outside and run sketch couple times without any changes in code (except rx/tx). But mh-z19 still returns me values around 720. Did I do it wrong?
I have another CO2 monitor, which shows 460-470 at the same spot, and it seems to be a fair number.

So I noticed that my mh-z19 has wrong delta around 200-300 ppm. Is there a way to make a safe shift for that delta?

ERROR 3 after powercycle - firmware download blocks init

Hi,

so i have an ATTiny1614 (16kB Flash, 2kB RAM) with megaTinyCore, a 4-digit serial display and the MHZ-19C. I'm using hardware serial to save memory.
When i flash the code everything works as expected but when i power cycle the board i get error 3 "Recieved data does not match the usual syntax expected".
Flash memory is at 31% and global variables consume 10%.

If it is a memory problem, why does it work right after flashing?

#include <Arduino.h>
#include "MHZ19.h"
#include <TM1637Display.h>

//Pins for 7-Segment
#define CLK 7
#define DIO 6

MHZ19 myMHZ19;                    // Constructor for CO2 Sensor
TM1637Display display(CLK, DIO);  // Constructor for 7-Segment

unsigned long getDataTimer = 0;
uint16_t errorCode=0;

void setup()
{
    display.setBrightness(0x05);
    Serial.begin(9600);                                     // Device to MH-Z19 should not be changed
    
    //mySerial.begin(BAUDRATE);                               // (Uno example) device to MH-Z19 serial start   
    myMHZ19.begin(Serial);                                // *Serial(Stream) refence must be passed to library begin(). 
    myMHZ19.printCommunication();    
     
    myMHZ19.autoCalibration(true);                              // Turn auto calibration ON (OFF autoCalibration(false))
    display.showNumberDec(millis(),false);
    delay(2000);
    display.showNumberDec(0,true);
}

void loop()
{   
    if (millis() - getDataTimer >= 2000)
    {
        int CO2; 

        /* note: getCO2() default is command "CO2 Unlimited". This returns the correct CO2 reading even 
        if below background CO2 levels or above range (useful to validate sensor). You can use the 
        usual documented command with getCO2(false) */

        CO2 = myMHZ19.getCO2();                             // Request CO2 (as ppm)
        if(myMHZ19.errorCode ==  RESULT_OK)
          display.showNumberDec(CO2,false);
        else{
          display.showNumberDec(myMHZ19.errorCode,true);
        }
        getDataTimer = millis();
    }
}

Disable ABC every day?

Hello,

This is just a quick question:

In the project Readme says "ABC must be disabled each day, however this is handled by the library."
Is this correct? So the MHZ19B re-enables the auto cal every 24h? Could you confirm it, please?

Many thanks.

MHZ19::read returns sometimes RESULT_MATCH forever

The library seems to get out of sync sometimes after 2-3 days running without any problems. If such an error occurs i always get the response RESULT_MATCH forever.
I tried to analyze the code of MHZ19::read and what i understand so far is that you wait until you received at least 9 bytes of data. But what happens if you get more than 9 bytes because of an error? It seems that you just read 9 bytes, also if 10 bytes would be available. The next time the read function is called, you would have again 10 and not 9 bytes in your receive buffer (1 old byte from the previous corrupt message and the 9 bytes from the new message). But now everything is out of sync because of the invalid byte in the receive buffer which is never deleted.
Does this make any sense and could this be the reason for my problems?

I added the following patch to give it a try but i dont have any results so far:

while (mySerial->available() < MHZ19_DATA_LEN)
{
...
}

/* try to resync data */
while (mySerial->available() > MHZ19_DATA_LEN && (unsigned char)mySerial->peek() != 0xFF) 
{
    mySerial->read(); 
}

/* response recieved, read buffer */
mySerial->readBytes(inBytes, MHZ19_DATA_LEN);
    
/* clear receive buffer */
while (mySerial->available())
{
    mySerial->read();
} 

get background CO2

Now that I finally experiment I have another question.

I did a manual calibration as you suggested in your examples. I left the device outside for 20-30 minutes and then I pulled the DH pin to ground for 7 seconds. The readings calibrated to 400 and then i let it run for another 10 minutes to see if it's stays there.

After that i placed the device inside a closed room to show the higher readings. It did willfully. But then i checked the getBackgroundCO2 commend and I noticed the following.

The getBackgroundCO2 was always printing the same as the CO2 command

Background CO2: 3067
ABC Status: OFF
CO2 (ppm): 3067
Temperature (C): 20

Background CO2: 3100
ABC Status: OFF
CO2 (ppm): 3100
Temperature (C): 20

If I got the documentation correctly the getBackgroundCO2 should have been a constant 400 after the calibration. Have you any idea what am i missing?

Storage Usage of this Library ..

Hello again 👍 ,

New Week, New Problem.. You know that I try to make an battery powered Device for my office.. So I would like to Use an Attiny.. But the Attiny 404 has 4kb of Space.. The Library with the BasicUsage won’t fit on that chip.
The attiny has a real serial connection and don’t need „SoftwareSerial“.. Only for understanding: 8kb Attiny has only 26% free Space for Code. This must be more.

How can I use this Libary without SoftwareSerial?

Error Code 3

Hello
I use esp32 UART to communication with MH-Z19 MH-Z19C

than, I tried the example ErrorCodes and I got message

Sent << DEC: 255 1 133 0 0 0 0 0 122
Received >> DEC: 66 77 9 129 8 200 3 52 1 ERROR Code: 3
Failed to receive CO2 value - Error
Response Code: 3
Sent << DEC: 255 1 133 0 0 0 0 0 122
Received >> DEC: 66 77 9 129 8 200 3 52 1 ERROR Code: 3
Failed to receive CO2 value - Error
Response Code: 3
Sent << DEC: 255 1 133 0 0 0 0 0 122
Received >> DEC: 66 77 9 130 8 198 3 51 1 ERROR Code: 3
Failed to receive CO2 value - Error
Response Code: 3
Sent << DEC: 255 1 133 0 0 0 0 0 122
Received >> DEC: 66 77 9 130 8 198 3 51 1 ERROR Code: 3
Failed to receive CO2 value - Error
Response Code: 3
Sent << DEC: 255 1 133 0 0 0 0 0 122
Received >> DEC: 66 77 9 130 8 199 3 50 1 ERROR Code: 3
Failed to receive CO2 value - Error
Response Code: 3
Sent << DEC: 255 1 133 0 0 0 0 0 122
Received >> DEC: 66 77 9 131 8 199 3 49 1 ERROR Code: 3
Failed to receive CO2 value - Error
Response Code: 3

Could you help me please?

Thank you @WifWaf

getCO2() sends wrong serial command?

According to the MH-Z19's manual, the command to get the co2 reading is 0x86.
Following the basic usage example in this repository, it seems that 0x85 is being sent instead.
Here's a screenshot from a logic analyzer showing Tasmota correctly polling for the reading:
Logic_eUTjYcvB8w
Here's your arduino library:
Logic_wRio3f2ICs

The code I'm using:

#include <MHZ19.h>
#include <SoftwareSerial.h>
#define RX_PIN 8
#define TX_PIN 9
#define BAUDRATE 9600

MHZ19 myMHZ19;
SoftwareSerial mhzSerial(RX_PIN, TX_PIN);

unsigned long getDataTimer = 0; 

void setup() {
  mhzSerial.begin(BAUDRATE);
  myMHZ19.begin(mhzSerial);
  myMHZ19.setRange(2000);
  myMHZ19.setSpan(2000);
  
  Serial.begin(115200);
}

void loop() {
    if (millis() - getDataTimer >= 2000)                    // Check if interval has elapsed (non-blocking delay() equivilant)
    {
        int CO2;                                            // Buffer for CO2
        CO2 = myMHZ19.getCO2();                             // Request CO2 (as ppm)
    
        Serial.print("CO2 (ppm): ");                      
        Serial.println(CO2);                          
    
        getDataTimer = millis();                            // Update interval
    }
}

Am I doing something wrong here?

Temperature values among different sensors

I built 4 devices, all with the same components including a CO2 sensor, all running the same arduino software. I put them side by side and they report wildy different temperature values (14, 24, 38, 45). Have you seen this problem? What should be this value?

BasicUsage fails on the Wemos D1 Mini

Using :

#define RX_PIN D5 // Rx pin which the MHZ19 Tx pin is attached to
#define TX_PIN D6 // Tx pin which the MHZ19 Rx pin is attached to
#define BAUDRATE 9600 // Native to the sensor (do not change)

in the basicusage sketch.

Other libraries are able to fetch the temperature and ppm, this library fails.
I hooked up an oscilloscope and can see that the device indeed replies (TX and RX are both active).

Output of the sketch:

!ERROR: Failed to verify connection(1) to sensor. Failed to stablise
!ERROR: Initial communication errorCode recieved
CO2 (ppm): 0
Temperature (C): -17
CO2 (ppm): 0
Temperature (C): -17
CO2 (ppm): 0
Temperature (C): -17
CO2 (ppm): 0
Temperature (C): -17
CO2 (ppm): 0
Temperature (C): -17
CO2 (ppm): 0
Temperature (C): -17
CO2 (ppm): 0
Temperature (C): -17

ErrorCode = 2 meaning timeout
I tried to increase timeout to 5000 but nothing changed...

Add MH-Z16 and below 400ppm measurements, set different range / sensititivies of sensors used.

So nice to see this fantastic library. I struggled a lot 3 years ago, with all those commands...
https://www.hackteria.org/wiki/CO2_Soil_Respiration_Chamber

From my own experiments i started to prefer the MH-Z16, as it can also send ppm values below 400. For some experiments in plant monitoring or microbiological fermentation process we can also eat up more CO2 than we release.

It's quite similar, the library could add it with minor changes.

Whaaddabout those different sensitivities 0-2000, 0-5000, 0-10'000 and even more. How can i set this up using the library?

FYI: be warned about fake banggood MH-Z19b sensors

I recently ordered 3x MH-Z19 sensors from banggood. Because I wanted to construct 3 supplementary IOT CO2 sensors (refer to my project https://github.com/hixfield/HixCO2TemperatureIRBlaster). However, the readings that they produce are highly unstable and cannot be trusted. I created small YouTube video to show my readings (on request of banggood itself):

https://youtu.be/5_QQe75-SZI

Also found this post about it: https://revspace.nl/MH-Z19B#Fake_MH-Z19B_.28black_PCB.29

Simplification proposal

In MHZ19.cpp, sections such as:

        #if defined (ESP32) && (MHZ19_ERRORS)
        ESP_LOGE(TAG_MHZ19, "message...");
        #elif MHZ19_ERRORS
        Serial.println("!ERROR: message...");
        #endif 

Could be simplified:

        #if MHZ19_ERRORS
        Serial.println("!ERROR: message...");
        #endif 

Thank you!

RAW measurement

Hi,

I'm I correct to assume that even if my sensors range is between 410 - 2000.

That the raw measurement that goes above 20000 is also correct? (The ppm count in the raw example)

Or is this gibberish data?

Incorrect PPM range with sensor

Hi, so I've started playing with this library, and I'm confused a little about range which .getCO2() returns.
My MH-Z19B has a sticker which states 0-5000ppm.
I've called getRange(), it returned 5000. But when I call getCO2 - I get a value between 0-10000ppm, which looks like 0-5000 stretched into 10000, for example I get something like 1100 in fresh air, which should be close to 400-500, and I get 10000 when do a couple of breaths near it for a minute.

Am I missing something? Thanks in advance.

I've ran RetrieveDeviceInfo.ino:

Firmware Version: 04.30
Range: 5000
Background CO2: 400
Temperature Cal: 40
ABC Status: OFF

library fails with CORE_DEBUG_LEVEL=3

Overview

The library fails when the debug level is increased, when you define CORE_DEBUG_LEVEL=3 for example, its necessary pass the TAG like this: '-D TAG_MHZ19="MHZ19"' on PlatformIO ini file for example.

.pio/libdeps/M5STICKCPLUS/MH-Z19/src/MHZ19.cpp: In member function 'void MHZ19::begin(Stream&)':
.pio/libdeps/M5STICKCPLUS/MH-Z19/src/MHZ19.cpp:37:18: error: 'TAG_MHZ19' was not declared in this scope
         ESP_LOGE(TAG_MHZ19, "Initial communication errorCode recieved");

Get / Set - Cycle

Hello WifWaf,
on https://revspace.nl/ there is a indicator how to change the cycle of MH-Z19b.
Default is 5 seconds which will also be responded by :
int MHZ19::getCycle()
{
/* check get Cycle length (5 Sek default) /
provisioning(GETCYCLE);
if (this->errorCode == RESULT_OK)
/
convert MH-Z19 memory value and return */
return (int)makeInt(this->storage.responses.STAT[2], this->storage.responses.STAT[3]);
else
return 1;
}

But I'm not fine with setting other values.
Did you have checked this register (126) already?

If you like to investigate - I have setup some lines in a fork-version.
Nice to get your ideas and have a nice time . You see I'm a longeterm follower.

Stefan

!Error: Timed out waiting for response

Hi,
I am trying to use your library. Due to every connection seems okey i am not getting and data from my MHZ-19 sensor.

I constantly get the following error;

CO2 (ppm): 0
!Error: Timed out waiting for response
Temperature (C): -17

Thank you.

request overlapping

hi, i'm receiving RESULT_ERR_MATCH once at startup when using this code:

void setup()
{
    Serial.begin(9600);
    mhz_serial.begin(MHZ_BAUDRATE);

    mhz.printCommunication(false, true);
    mhz.begin(mhz_serial);
    mhz.autoCalibration(false);
}

void loop()
{
    if (millis() - getDataTimer >= 5000)
    {
        int CO2 = mhz.getCO2(false, true);
        Serial.println(CO2); // <-- zero at first (mhz.errorCode == 3 RESULT_ERR_MATCH)

        getDataTimer = millis();
    }
}

debug log:

---
request:  0xFF 0x01 0x85 0x00 0x00 0x00 0x00 0x00 0x7A  
response: 0xFF 0x85 0x08 0xE5 0x03 0x9E 0x00 0x00 0xED  
---
request:  0xFF 0x01 0xA2 0x00 0x00 0x00 0x00 0x00 0x5D  
response: 0xFF 0xA2 0x08 0xE5 0x03 0x9E 0x00 0x00 0xD0  
---
request:  0xFF 0x01 0x79 0x00 0x00 0x00 0x00 0x00 0x86  
response: 0xFF 0x79 0x01 0x00 0x00 0x00 0x00 0x00 0x86  
---
request:  0xFF 0x01 0x79 0x00 0x00 0x00 0x00 0x00 0x86  
---
request:  0xFF 0x01 0x86 0x00 0x00 0x00 0x00 0x00 0x79  
response: 0xFF 0x79 0x01 0x00 0x00 0x00 0x00 0x00 0x86 ERROR Code: 3
0
---
request:  0xFF 0x01 0x86 0x00 0x00 0x00 0x00 0x00 0x79  
response: 0xFF 0x86 0x03 0x9F 0x44 0x00 0x00 0x00 0x94  
927
---

not sure why 0x79 (ABC turn off) sent twice.
but first 0x86 (CO2 limited) requested before response for second 0x79 is received, so first 0x86 gets failed.

simillar happens with examples/BasicUsage, where co2 and temperature requests overlapping, resulting in failed response for both. fixed by requesting only one at a time.

Reasoning behind sensor zero-calibration ?

Hi there,

I don't know if the question is about the library or about the sensor itself. I am using the method calibrate (); to calibrate the sensor but it does not have the behavior I expect, which is to determine the zero (400 ppm). Instead, other baselines appear. After calibrating, I print the sensor information and get results such as:

Outdoor:
imagen

Indoor:
imagen

Background CO2 seems to have been defined in the calibration process. Does that make sense to you? In that case, how can that Background CO2 be set with such a high value, if the calibration is done outdoors?

Thank you!

Note: By the way, outdoor temperatures were lower, at 7-9 °C.

Library incompatible with I2C LCD?

I've been using a different MHZ19 library but am having serious bugs with it so I gave yours a try, however, when I upload it the LCD doesn't work. Uploading the old sketch brings it back online. I can't understand how this would affect the screen, but I've changed nothing in my code but what's needed to make each library work.

I'm running a Leonardo, so using hardware serial, if that's relevant.

Edit: Actually it seems like everything stopped working, the relays and the logic controlling them as well.

Any help?

Failed communication via UART (ESP32)

Hi everyone,
I'm using ESP32 with MHZ19B co2 sensor. I've changed the BasicUsage sketch to use HardwareSerial 2. After wiring everything the result was:
co2: 0
temperature: -17
error

Cannot connect the sensor properly

I used an Arduino Micro and just used your example code and connected the sensor like this:

  • 5V (Arduino) to Vin (MH-Z19B)
  • GND to GND
  • Rx (Arduino) to Tx (MH-Z19B)
  • Tx (Arduino) to Rx (MH-z19B)

Unfortunately, I got this Error:
image

I changed the value of the rx_pin and tx_pin like this:
#define RX_PIN 10
#define TX_PIN 11

When I look at the Sensor, I can see the IR light turning on every 2 seconds or so. On the arduino, the tx light flashes on and of, but the rx light is permanentely of.

What can I do?

Serial communication - MH-Z19b + ESP-01S together or Arduino

Hi,

is possible to get these two modules working side by side over serial communication with Arduino UNO?

I get this error:
image

My part of the code:
`
#include <Wire.h>
#include <SoftwareSerial.h> // ESP-01S Wifi modul AT - serial komunikace
#include "Adafruit_BME280.h" // Bosch BME280 I2C (T+RH+P)
#include "MHZ19.h" // MH-Z19B (CO2)

#define MHZ19B_RX 10 // MH-Z19B - RX PIN (CO2 modul RX pin -> Arduino)
#define MHZ19B_TX 11 // MH-Z19B - TX PIN (CO2 modul TX pin -> Arduino)
#define ESP01S_RX 2 // ESP-01S - RX PIN (Wifi modul TX pin -> Arduino)
#define ESP01S_TX 3 // ESP-01S - RX PIN (Wifi modul RX pin -> Arduino)

int CO2ppm; // koncentrace CO2 (ppm)
unsigned long getDataTimer = 0; // MHZ19B timer

// ESP-01S Wifi modul - konfigurace zapojeni PINu - RX/TX
SoftwareSerial espSerial(ESP01S_RX,ESP01S_TX);

// MH-Z19B CO2 senzor - konfigurace zapojeni PINu - RX/TX (UART zapojeni)
MHZ19 myMHZ19; // knihovna
SoftwareSerial mhz19bSerial(MHZ19B_RX,MHZ19B_TX);

void setup()
{

// Arduino - komunikace
Serial.begin(9600); // Komunikace Arduino - 9600 baudrate

// Inicializace senzoru + modulu
// Bosch BME280 senzor (T+RH+P)
Serial.println("Inicializace...");
Serial.println("Detekce BME280 sensoru...");
if(!bme.begin(0x76)) // IC2 adresa pro komunikaci nastavena na 0x76
{
Serial.println("BME280 senzor nebyl detekovan. Zkontrolujte vase zapojení a/nebo IC2 adresu!");
while(1);
}
Serial.println("BME280 senzor uspesne nacten!");

  // MH-Z19B CO2 senzor
  mhz19bSerial.begin(9600); // Komunikace s CO2 modulem - 9600 baudrate
  myMHZ19.begin(mhz19bSerial); // Definovat seriovou komunikaci
  myMHZ19.autoCalibration(false); // Vypnout auto-kalibraci CO2


// ESP-01S - komunikace  
  espSerial.begin(115200); // Komunikace s Wifi modulem - 115200 baudrate
  espSerial.flush(); // Vymazat serial monitor
  espData("AT+RST", 1000, DEBUG); // Reset ESP-01S modulu
  espData("AT+CWMODE=1", 1000, DEBUG); // Nastavit rezim ESP-01S na "station mode"
  espData("AT+CWJAP=\""+ AP_SSID +"\",\""+ AP_PASSWORD +"\"", 1000, DEBUG); // Pripojit k Wifi siti
  delay(1000);

}

void readSensors(void)
{

// MH-Z19B - koncentrace CO2 (ppm)
if (millis() - getDataTimer >= 2000)
{
CO2ppm = myMHZ19.getCO2(); // Hodnota koncentrace CO2 (ppm)
getDataTimer = millis();
}
...

`

Consider changing the license

The current license is GPL, which means that you cannot use this library in a project without releasing all of that project's source code under GPL as well.

I don't know if using GPL is a fully thought out choice or not, but it severely restricts where the library can be used.

Please consider releasing changing the license to LGPL (allows linking inside of a program), or to MIT (even better, basically allows all use in a propriety program).

The other 2 libraries I've found for using MH-Z19B are MIT licensed, but one of them only supports PWM (no serial support) and the other one isn't available in Arduino IDE's library manager:
https://github.com/tobiasschuerg/MH-Z-CO2-Sensors
https://github.com/crisap94/MHZ19

Changing the license at this point should be fairly simple, but after you've accepted contributions from other people, they need to agree to the license change as well, as far as I've understood.

The readme says that this library is derived/inspired by another library, which is licensed under GPLv3, so the distinction between derived and inspired is probably important if the license would be changed.

First measurement is not correct

I have mhz-19b

first measurement is not accurate, it returns always about 450 ppm, but the second if is correct (tested and compared with my second commercial device).

I use delay 60 second before the first read, is there anything what can be done better? Thank you!

Wrong Temperature - wrong Co2?

Hi, I used your example script on my new (and first) MH-Z19B sensor. I have no experience with this type of Sensor, however i do not trust this temerature measurements:
CO2 (ppm): 1962 Temperature (C): 4
The Co2 could be possible due to an indoor room, but the temp is definitely off. And I guessing this makes the Co2 wrong too? Could this be script side oder is my sensor just broken?

Problem in "byte MHZ19::getCRC(byte inBytes[])"

File MHZ19.cpp
Lines 736 to746
The variable CRC, written in capital letters collides with a macro defined in CMSIS, resulting in a bunch of compiler errors.

Writing the variable crc in lower case letters solves the issue.

You are welcome
Michael

Error:
Arduino: 1.8.13 (Windows 7), Board: "Generic STM32F1 series, BluePill F103C8, Maple DFU Bootloader original, Enabled (generic 'Serial'), None, Low/Full Speed, Smallest (-Os default), Newlib Standard"

In file included from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\system/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h:131,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/stm32/stm32_def.h:28,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/stm32/clock.h:43,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/wiring_time.h:23,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/wiring.h:38,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/Arduino.h:36,

             from C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.h:14,

             from C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:11:

C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp: In member function 'byte MHZ19::getCRC(byte*)':

C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\system/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h:685:43: error: expected ')' before '*' token

685 | #define CRC ((CRC_TypeDef *)CRC_BASE)

  |                              ~            ^

C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:736:17: note: in expansion of macro 'CRC'

736 | byte x = 0, CRC = 0;

  |                 ^~~

C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\system/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h:685:43: error: expected ')' before '*' token

685 | #define CRC ((CRC_TypeDef *)CRC_BASE)

  |                             ~             ^

C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:736:17: note: in expansion of macro 'CRC'

736 | byte x = 0, CRC = 0;

  |                 ^~~

C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:740:25: error: lvalue required as left operand of assignment

740 | CRC += inBytes[x];

  |                         ^

C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:743:17: error: 'crc' was not declared in this scope

743 | CRC = 255 - crc;

  |                 ^~~

In file included from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\system/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h:131,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/stm32/stm32_def.h:28,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/stm32/clock.h:43,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/wiring_time.h:23,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/wiring.h:38,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/Arduino.h:36,

             from C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.h:14,

             from C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:11:

C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\system/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h:685:30: error: increment of read-only location '(CRC_TypeDef*)((1073741824 + 131072) + 12288)'

685 | #define CRC ((CRC_TypeDef *)CRC_BASE)

  |                             ~^~~~~~~~~~~~~~~~~~~~~~~~

C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:744:5: note: in expansion of macro 'CRC'

744 | CRC++;

  |     ^~~

C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:744:8: error: lvalue required as increment operand

744 | CRC++;

  |        ^~

In file included from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\system/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h:131,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/stm32/stm32_def.h:28,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/stm32/clock.h:43,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/wiring_time.h:23,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/wiring.h:38,

             from C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\cores\arduino/Arduino.h:36,

             from C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.h:14,

             from C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:11:

C:\Users\Michael\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\system/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h:685:30: error: invalid conversion from 'CRC_TypeDef*' to 'byte' {aka 'unsigned char'} [-fpermissive]

685 | #define CRC ((CRC_TypeDef *)CRC_BASE)

  |                             ~^~~~~~~~~~~~~~~~~~~~~~~~

  |                              |

  |                              CRC_TypeDef*

C:\Users\Michael\Documents\Arduino\libraries\MH-Z19\src\MHZ19.cpp:746:12: note: in expansion of macro 'CRC'

746 | return CRC;

  |            ^~~

exit status 1

Fehler beim Kompilieren für das Board Generic STM32F1 series.

High values after power reset

Hi! Thanks for the useful library!
I found a small problem: after a reboot on power, the sensor returns falsely large values, which breaks the display of CO2-level charts.
Here is a serial monitor dump after such reboot:

CO2 = 63882 ppm
CO2 = 7011 ppm
CO2 = 4013 ppm
CO2 = 1017 ppm
CO2 = 1016 ppm
CO2 = 1029 ppm
CO2 = 1042 ppm

It would be great to add a filter of values to the library if it's possible.

Kind regards, Max.

Readings way off

This is likely related to #36 but I did not want to hijack that thread.

I have a recent MH-Z19C (plug version). The C02 readings have been ok-ish from the beginning. I compare them to the readings I get out of a Sensirion SCD41 that sits next to it. The temperature was off by roughly +10°C.

However, after a few weeks the CO2 readings started declining gradually until they ended up far below 400ppm (120-300). The reported temperature was constantly around +-32°C.

To see whether this library may be at fault I tried two others for this sensor and got similar results. I concluded my sensor must have failed the test of time. However, after I scanned #36 I'm not so sure anymore.

Tonight I ran the sensor outside for half an hour. Here's what it reports now (inside again).

Device info

21:57:22.753 -> Firmware Version: 05.12
21:57:22.753 -> Range: 2000
21:57:22.787 -> Background CO2: 500
21:57:22.787 -> Temperature Cal: 50
21:57:22.823 -> ABC Status: ON

Basic usage plus background CO2

22:18:26.583 -> CO2 (ppm): 493
22:18:26.583 -> background CO2: 493
22:18:26.654 -> Temperature (C): 33
22:18:28.653 -> CO2 (ppm): 497
22:18:28.653 -> background CO2: 497
22:18:28.725 -> Temperature (C): 33
22:18:30.716 -> CO2 (ppm): 469
22:18:30.716 -> background CO2: 469
22:18:30.782 -> Temperature (C): 33
22:18:32.815 -> CO2 (ppm): 465
22:18:32.815 -> background CO2: 465
22:18:32.850 -> Temperature (C): 33
22:18:34.858 -> CO2 (ppm): 465
22:18:34.858 -> background CO2: 465
22:18:34.895 -> Temperature (C): 33
22:18:36.939 -> CO2 (ppm): 468
22:18:36.939 -> background CO2: 468
22:18:36.976 -> Temperature (C): 33
22:18:38.985 -> CO2 (ppm): 466
22:18:38.985 -> background CO2: 466
22:18:39.056 -> Temperature (C): 33
22:18:41.054 -> CO2 (ppm): 491
22:18:41.054 -> background CO2: 491
22:18:41.126 -> Temperature (C): 33
22:18:43.143 -> CO2 (ppm): 492
22:18:43.143 -> background CO2: 492
22:18:43.181 -> Temperature (C): 33
22:18:45.198 -> CO2 (ppm): 485
22:18:45.198 -> background CO2: 485
22:18:45.232 -> Temperature (C): 33
22:18:47.263 -> CO2 (ppm): 436
22:18:47.263 -> background CO2: 436
22:18:47.299 -> Temperature (C): 33
22:18:49.342 -> CO2 (ppm): 440
22:18:49.342 -> background CO2: 440
22:18:49.380 -> Temperature (C): 33
22:18:51.414 -> CO2 (ppm): 494
22:18:51.414 -> background CO2: 494
22:18:51.450 -> Temperature (C): 33
22:18:53.455 -> CO2 (ppm): 506
22:18:53.455 -> background CO2: 506
22:18:53.529 -> Temperature (C): 33

-> CO2 and background always the same
-> CO2 is off by ~500ppm compared to the SCD41 that I consider accurate
-> CO2 readings are highly volatile, jumping 10% in just a couple of seconds -> appears to be caused by the sensor calibrating
-> temperature is off by 10°C

Getting wrong temperature on MH-z19c

Hi,

I am usning MH-Z19c sensor on esp8266.

I am getting the same temperature value:

CO2: 672
Temperature: -40
Accuracy: 0
CO2: 675
Temperature: -40
Accuracy: 0
CO2: 682
Temperature: -40
Accuracy: 0
CO2: 684
Temperature: -40
Accuracy: 0
CO2: 689
Temperature: -40
Accuracy: 0
CO2: 691
Temperature: -40
Accuracy: 0
CO2: 693
Temperature: -40
Accuracy: 0

Please help me on this.

error compiling

Hi, thanks for the library, makes life so much easier setting up the device

I tried the basic sketch with both library files inside the same directory and tried to compile it on an arduino pro mini (ATMEGA328 so uno compatible) and im getting the following error

MHZ19.cpp: In member function ‘byte MHZ19::read(byte*, MHZ19::Command_Type)’:
MHZ19.cpp:594:48: error: invalid conversion from ‘byte* {aka unsigned char*}’ to ‘char*’ [-fpermissive]
     mySerial->readBytes(inBytes, MHZ19_DATA_LEN);
                                                ^
In file included from /usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.h:28:0,
                 from /usr/share/arduino/hardware/arduino/cores/arduino/Arduino.h:193,
                 from MHZ19.h:6,
                 from MHZ19.cpp:3:
/usr/share/arduino/hardware/arduino/cores/arduino/Stream.h:76:10: note:   initializing argument 1 of ‘size_t Stream::readBytes(char*, size_t)’
   size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
          ^

have i fucked up something obvious that i can't see?

ESP32C3 support.

Compiling for an esp32c3 board, I have some issues with platfomio, like this:

C:/Users/Usuario/.platformio/packages/framework-arduinoespressif32@src-01b2ee0664276ec022da2783d94579c3/tools/sdk/esp32c3/include/log/include/esp_log.h:351:38: note: in expansion of macro 'ESP_LOG_LEVEL_LOCAL'
#define ESP_LOGE( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, tag, format, ##VA_ARGS)
^~~~~~~~~~~~~~~~~~~
.pio/libdeps/ESP32C3/MH-Z19/src/MHZ19.cpp:51:9: note: in expansion of macro 'ESP_LOGE'
ESP_LOGE(TAG_MHZ19, "Invalid Range value (0 - 65000)");
^~~~~~~~
.pio/libdeps/ESP32C3/MH-Z19/src/MHZ19.cpp:51:18: error: 'TAG_MHZ19' was not declared in this scope
ESP_LOGE(TAG_MHZ19, "Invalid Range value (0 - 65000)");

receiving zeros after warmup

hi, sometimes (like 10% chance) i'm receiving zeros from getCO2 after following init process:

void init_mhz() {
  mhz_serial.begin(MHZ_BAUDRATE);

  mhz.begin(mhz_serial);
  mhz.setFilter(true, true);

  mhz.setRange(2000);
  mhz.autoCalibration(true);

  // warming up
  while (true) {
    int co2 = mhz.getCO2(false, true);

    if (mhz.errorCode == RESULT_FILTER) {
      log_ln("sensors: mhz: warming up...", true);
    } else if (mhz.errorCode != RESULT_OK) {
      log_ln("sensors: mhz: failed to read CO2 on warmup.", true);
    } else {
      // warmed up (zeros can slip here)
      break;
    }

    delay(CO2_WARMING_READ_PERIOD);
  }
}

i'm using mhz.errorCode instead of simplier co2 == 0 (as in example), because i want to distinguish normal warming (RESULT_FILTER) and failing on warmup (!RESULT_OK).

maybe this is because i'm using TEMPLIM instead of TEMPUNLIM (what's the difference btw? didn't found any info about that. using TEMPLIM because this one specified in manual).

probably co2 == 0 case should be added to other filtering cases.

v1.4.2

Question. Correct interpretation of sensor readings

I am using version 1.5.3

Hi.
I calibrated on a windowsill with an open window, after calibration I upload my sketch and invoke getBackgroundCO2(), it was 500, then I corrected something in the code, upload it again and the value of getBackgroundCO2() became equal to getCO2(), is this correct behavior? I had the idea to calibrate the sensor, and then measure the delta from the background level of CO2, i.e. getCO2() - getBackgroundCO2(). Also, what seemed strange to me, the sensor readings in a ventilated room range from 1500 to 1600 ppm, is this an overestimated value?

Always reading 5000ppm on ESP32.

I encountered a weird problem and while most likely not related to the library, I wanted to make sure. I use the MH-Z19B with an ESP32. I already tried with an Arduino and an ESP8266 and everything worked fine.

Additionally when I use the sensor with a "LOLIN32" everything works, too.

Now the problem is the board I would like to use "LOLIN D32" has no 5V pin and when I connect the sensor to the 3.3V pin, I always receive 5000ppm as response. I did some research and it seems as if the sensor is getting a brownout and restarts continuosly...
I tried to use an external 5V power source (I connected GND and 5V to Vin and GND and also tried to connect only 5V to Vin) but now I get an error on startup ([E][MHZ19.cpp:44] begin(): Initial communication errorCode recieved) and always receive 0ppm.

Sorry for opening this potential Non-Issue and thanks in advance.

I used these connections on ESP32 / External 5V source.
Vin -> 5V
GND -> GND
17 -> RX
16 -> TX

I used this code:

#include <Arduino.h>
#include "MHZ19.h"

MHZ19 myMHZ19;                                             

unsigned long getDataTimer = 0;                                                        

void setup()
{
    Serial.begin(9600);

    Serial2.begin(9600, SERIAL_8N1);
    myMHZ19.begin(Serial2);
    myMHZ19.autoCalibration();
}                                                         

void loop()
{
    if (millis() - getDataTimer >= 5000)
    {
        int CO2Unlim = myMHZ19.getCO2();
        Serial.print("CO2 (ppm): ");
        Serial.println(CO2Unlim);

        getDataTimer = millis();                                                      
    }                                                                               
}  

Is using this board not supported yet or am I doing something wrong?

Question about the Calibration

Hey,

thank your for your nice Library and your Documentation about it. I bought this Sensor and I want to use it only indoors and my Question is about the Calibration. I thought that I need to turn of the auto-calibration, right?

But how can I calibrate this Sensor to have stable Values for a long time?

Is it possible to use your Calibration code with an simple button? I mean : I pressed the button outside the Sensor calibrates itself and then its done. Or needs the Sensor a longer Calibration Time?

Could you please explain to me if I disable the Auto-Calibration disabled that also the temperature Compensation?

My last question is about the Power-Consumption:

  • Could I power Off the Sensor to save Energy?

Thank you very much for answering my Questions..

Trouble with HardwareSerial on nodemcu 12

Hello, thank for your library, it's very useful, especially Recovery and Calibrating part.
When i use SoftwareSerial, everything work great, but 3 hours later i don't receive any data from the sensor (i tested it several times). So i read, that using HardwareSerial on ESP gives more stability, and i tried to connect via HardwareSerial, but don't received any data. Maybe something wrong with my sketch, but i tried to minimum change it from original example sketch.
I just change strings

HardwareSerial mySerial(1);
to
HardwareSerial Serial2(2);

and also

mySerial.begin(BAUDRATE, SERIAL_8N1, RX_PIN, TX_PIN);
to
Serial2.begin(BAUDRATE, SERIAL_8N1);

Cause if i try to compile it with original code, i have error:

BasicUsage:21:56: error: invalid conversion from 'int' to 'SerialMode' [-fpermissive]
     mySerial.begin(BAUDRATE, SERIAL_8N1, RX_PIN, TX_PIN); // (ESP32 Example) device to MH-Z19 serial start   
                                                        ^
In file included from /Users/ac1d/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.2/cores/esp8266/Arduino.h:244:0,
                 from /var/folders/j2/rv6w5j790dq31zz952rgp0j00000gn/T/arduino_modified_sketch_904602/BasicUsage.ino:1:
/Users/ac1d/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.2/cores/esp8266/HardwareSerial.h:87:10: error:   initializing argument 3 of 'void HardwareSerial::begin(long unsigned int, SerialConfig, SerialMode, uint8_t)' [-fpermissive]
     void begin(unsigned long baud, SerialConfig config, SerialMode mode, uint8_t tx_pin)
          ^
exit status 1
invalid conversion from 'int' to 'SerialMode' [-fpermissive]

Connections:
MHZ19 TX -> GPIO13 (D7) (RXD2)
MHZ19 RX -> GPIO15 (D8) (TXD2)

#include <Arduino.h>
#include "MHZ19.h"                                        
//#include <SoftwareSerial.h>                                // Remove if using HardwareSerial or Arduino package without SoftwareSerial support
#include "HardwareSerial.h"

//#define RX_PIN 10                                          // Rx pin which the MHZ19 Tx pin is attached to
//#define TX_PIN 11                                          // Tx pin which the MHZ19 Rx pin is attached to
#define BAUDRATE 9600                                      // Device to MH-Z19 Serial baudrate (should not be changed)

MHZ19 myMHZ19;                                             // Constructor for library

//SoftwareSerial mySerial(RX_PIN, TX_PIN);                   // (Uno example) create device to MH-Z19 serial
HardwareSerial Serial2(2);                                // (ESP32 Example) create device to MH-Z19 serial

unsigned long getDataTimer = 0;

void setup()
{
    Serial.begin(9600);                                     // Device to serial monitor feedback
    //Serial.swap(); //GPIO15 (TX) and GPIO13 (RX)
    //Serial.flush(); //clear serial buffer
    //mySerial.begin(BAUDRATE);                               // (Uno example) device to MH-Z19 serial start   
    Serial2.begin(BAUDRATE, SERIAL_8N1);                    // (ESP32 Example) device to MH-Z19 serial start   
    
    
    myMHZ19.begin(Serial2);                                // *Serial(Stream) refence must be passed to library begin(). 
    
    myMHZ19.autoCalibration();                              // Turn auto calibration ON (OFF autoCalibration(false))
}

void loop()
{
    if (millis() - getDataTimer >= 2000)
    {
        int CO2; 

        /* note: getCO2() default is command "CO2 Unlimited". This returns the correct CO2 reading even 
        if below background CO2 levels or above range (useful to validate sensor). You can use the 
        usual documented command with getCO2(false) */

        CO2 = myMHZ19.getCO2();                             // Request CO2 (as ppm)
        
        Serial.print("CO2 (ppm): ");                      
        Serial.println(CO2);                                

        int8_t Temp;
        Temp = myMHZ19.getTemperature();                     // Request Temperature (as Celsius)
        Serial.print("Temperature (C): ");                  
        Serial.println(Temp);                               

        getDataTimer = millis();
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.