Troubles with MH-Z19 Co2 meter reading always stays at 5000 ppm

Hello All

Was just testing the MH-Z19 module and am having some issues.

Using UART to connect to esp8266

#define CO2_TX D6
#define CO2_RX D7`

also powered using 3V and Ground.
Got it setup fine and connected to blynk server…it says -1 for a minute then around 420 ppm which is probably about right but after about 5 minutes it just goes to 5000 ppm and stays there.

its a 5000 ppm sensor so Im not sure if this is a code/calculation error or faulty sensor or what…

here is the sketch im using

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <Wire.h>
#include <SoftwareSerial.h>;


// MH-Z19:
// power - 3v
// D6 - TX sensor, D7 - RX sensor
#define CO2_TX D6
#define CO2_RX D7

SoftwareSerial co2Serial(CO2_TX, CO2_RX);

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = “redacted”;  // Put your Auth Token here. (see Step 3 above)

SimpleTimer timer;

void setup()
{
  Serial.begin(9600); // See the connection status in Serial Monitor
   Blynk.begin(auth, “xx”, “xx”); //insert here your SSID and password
 
  // Setup a function to be called every second
  timer.setInterval(10000L, sendUptime);

  co2Serial.begin(9600);
  co2Serial.flush();
}

int readCO2()
{
  byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
  char response[9];

  co2Serial.write(cmd, 9); //request PPM CO2
  co2Serial.readBytes(response, 9);

  byte crc = 0;
  for (int i = 1; i < 8; i++)
  {
    crc += response[i];
  }
  crc = 255 - crc;
  crc++;

  if (response[8] != crc)
  {
    Serial.println("Wrong crc from co2 sensor!");
    return -1;
  }
  if (response[0] != 0xFF)
  {
    Serial.println("Wrong starting byte from co2 sensor!");
    return -1;
  }
  if (response[1] != 0x86)
  {
    Serial.println("Wrong command from co2 sensor!");
    return -1;
  }

  int responseHigh = (int) response[2];
  int responseLow = (int) response[3];
  int ppm = (256 * responseHigh) + responseLow;
  return ppm;
}

void sendUptime()
{
int co2_ppm = readCO2();
  Blynk.virtualWrite(3, co2_ppm); // virtual pin 
}
void loop()
{
  Blynk.run();
  timer.run();
}

any ideas?

Thanks!

Where are you getting the 3.3v from? Hopefully NOT the ESP 3.3v pin as even at the sensors draw of <18mA the ESP is unlikely to have the current capacity to run the sensor properly.

If you get this working i will be happy to see it ! I was trying the same thing but with a different sensor. But i was never sure i had the right formula so i just kinda dropped that project for the moment.

Hi Gunner…
Yea im using the 8266 for the 3v right now.
hmm… interesting.
i read in a spec sheet that the sensor has Average current < 18 mA

any thoughts?

You didn’t mention the exact type of ESP dev board you have, or it’s power source. <18mA isn’t a lot, however your ESPs onboard regulator may already be under enough load?

Instead of tapping off the 3.3v pin, you could find an external source or a separate regulator from whatever source already powers the ESP.

Power may NOT be the issue, but worth looking into anyhow.

Also… have you tested it with an example sketch (non Blynk) and does it behave any better?

Hi Gunnar its an ESP8266 devboard (ESP12E).

TBH i havnt tried external power supply or other sketches or PWM (just UART)
Will try new power source first.

My coding skills are kindergarten level and the existing sketches i found online were proprietary to other ecosystems and libraries that created new issues and took me away from trying to solve this .

I tried to read the serial monitor to see if i can see anything but got nothing but gobblygook characters.

I tried searching for calibration of this sensor and found

https://revspace.nl/MHZ19#command_0x99_.28range.29

'Setting the measurement range
The following command sequences can be used to configure the measurement range of the sensor:

1000 ppm range: 0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x03, 0xE8, 0x7B
2000 ppm range: 0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x8F
3000 ppm range: 0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x0B, 0xB8, 0xA3
5000 ppm range: 0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x13, 0x88, 0xCB’

The sketch im using uses this

‘byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
char response[9];’

Itried switching to ‘5000 ppm range: 0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x13, 0x88, 0xCB’ but wouldnt compile.

I found this page… looks like some basic code at the end, without any strange libraries.

Try it and compare readings and longevity… then look at blynkifying it.

Thank you …will give it a go and report back.

@Gunner so i tried that script but couldnt "read " any data…
the serial output was not outputting…tried hooking up I2c OLED but fell in a rabbit hole.

So i went back to your original suggestion or more juice.
Its working better now…
Im giving the sensor 5v and UART 3,3v and its outputting PPM now.

The problem is the PPM meter says 910 ppm in my work room… lol
which according to google
800 PPM = Headache, nausea, and dizziness after 45 minutes; collapse and unconsciousness after 1 hour of exposure. Death within 2-3 hours.
1000 PPM =Loss of consciousness after 1 hour of exposure.

note sure if it needs a calibration or if im really going to die in the next few hours but either way im gonna celebrate with a cold :beer: and let lord cthulhu decide my fate.

Thank you for your help!

2 Likes

I think you miss a zero from those high reference ppm numbers that cause losing consciousness.

Generally, anything below 1000ppm is considered acceptable indoor air quality. Most sensors give you a green light (good air quality) for <800 ppm.

So, your 910 ppm is still acceptable.

I’ve been using MH-Z14 for half a year now and wired up the new MH-Z19B just last night. It looks like MH-Z19B doesn’t quite remember the previous zero calibration after power down/up sequence. The measured indoors readings were fine soon after zero calibrating. But after over night power down/up sequence the reported CO2 levels are clearly too high (1400-1700ppm). I’m setting the Auto Calibration OFF in Teensy LC setup and read the values via UART. My MH-Z14 doesn’t have the same problem as the zero calibration config is consistent even after power down/up. I’ll try to comment out the Auto Calibration OFF next if it makes any difference. I have just one MH-Z19B unit. So it may be just faulty device too.

Please create a new current topic with any Blynk related issues, thank you.