Mh-z19b being weird

I set up a device with various sensors that measure different air polluants and sends values through bluetooth to an android app. This is the code:

#include <math.h>
#include <Arduino.h>
#include "PMS.h"
#include "SparkFun_SGP30_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_SGP30
#include <Wire.h>
 
SGP30 mySensor; //create an object of the SGP30 class
// Define the serial port for MH-Z19B sensor (Serial2 on Arduino Mega)
#define MHZ19B_SERIAL Serial2

// Define the serial port for Bluetooth (Serial3 on Arduino Mega)
#define BLUETOOTH_SERIAL Serial3

// Define the baud rate for MH-Z19B sensor
#define MHZ19B_BAUDRATE 9600



// Define the command to read CO2 concentration
uint8_t MHZ19B_CMD_READ_CO2[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};

PMS pms(Serial1);
PMS::DATA data;


enum channel {
  CH_NH3, CH_RED, CH_OX
};
typedef enum channel channel_t;

// Enum for proper gas declaration
enum gas {
  CO, NO2, NH3, C3H8, C4H10, CH4, H2, C2H5OH
};
typedef enum gas gas_t;

#define NH3PIN A1
#define COPIN A0
#define OXPIN A2

uint16_t NH3baseR;
uint16_t REDbaseR;
uint16_t OXbaseR;

/**
   Requests the current resistance for a given channel
   from the sensor. The value is an ADC value between
   0 and 1024.

   @param channel
          The channel to read the base resistance from.
   @return The unsigned 16-bit base resistance
           of the selected channel.
*/

uint16_t getResistance(channel_t channel) {
      unsigned long rs = 0;
      int counter = 0;

  switch (channel) {
    case CH_NH3:
      for(int i = 0; i < 100; i++) {
        rs += analogRead(NH3PIN);
        counter++;
        delay(2);
      }
      return rs/counter;
    case CH_RED:
      for(int i = 0; i < 100; i++) {
        rs += analogRead(COPIN);
        counter++;
        delay(2);
      }
      return rs/counter;
    case CH_OX:      
      for(int i = 0; i < 100; i++) {
        rs += analogRead(OXPIN);
        counter++;
        delay(2);
      }
      return rs/counter;

  }

  return 0;
}

void calibrateMICS() {
  // Continuously measure the resistance,
  // storing the last N measurements in a circular buffer.
  // Calculate the floating average of the last seconds.
  // If the current measurement is close to the average stop.

  // Seconds to keep stable for successful calibration
  // (Keeps smaller than 64 to prevent overflows)
  uint8_t seconds = 10;
  // Allowed delta for the average from the current value
  uint8_t delta = 2;

  // Circular buffer for the measurements
  uint16_t bufferNH3[seconds];
  uint16_t bufferRED[seconds];
  uint16_t bufferOX[seconds];
  // Pointers for the next element in the buffer
  uint8_t pntrNH3 = 0;
  uint8_t pntrRED = 0;
  uint8_t pntrOX = 0;
  // Current floating sum in the buffer
  uint16_t fltSumNH3 = 0;
  uint16_t fltSumRED = 0;
  uint16_t fltSumOX = 0;

  // Current measurements;
  uint16_t curNH3;
  uint16_t curRED;
  uint16_t curOX;

  // Flag to see if the channels are stable
  bool NH3stable = false;
  bool REDstable = false;
  bool OXstable = false;

  // Initialize buffer
  for (int i = 0; i < seconds; ++i) {
    bufferNH3[i] = 0;
    bufferRED[i] = 0;
    bufferOX[i] = 0;
  }

  do {
    // Wait a second
    delay(1000);
    Serial.print(".");
    // Read new resistances
    unsigned long rs = 0;
    delay(50);
    for (int i = 0; i < 3; i++) {
    delay(1);
    rs += analogRead(NH3PIN);
    }
    curNH3 = rs/3;
    rs = 0;
    delay(50);
    for (int i = 0; i < 3; i++) {
    delay(1);
    rs += analogRead(COPIN);
    }
    curRED = rs/3;
    rs = 0;
    delay(50);
    for (int i = 0; i < 3; i++) {
    delay(1);
    rs += analogRead(OXPIN);
    }
    curOX = rs/3;

    // Update floating sum by subtracting value
    // about to be overwritten and adding the new value.
    fltSumNH3 = fltSumNH3 + curNH3 - bufferNH3[pntrNH3];
    fltSumRED = fltSumRED + curRED - bufferRED[pntrRED];
    fltSumOX = fltSumOX + curOX - bufferOX[pntrOX];

    // Store new measurement in buffer
    bufferNH3[pntrNH3] = curNH3;
    bufferRED[pntrRED] = curRED;
    bufferOX[pntrOX] = curOX;

    // Determine new state of flags
    NH3stable = abs(fltSumNH3 / seconds - curNH3) < delta;
    REDstable = abs(fltSumRED / seconds - curRED) < delta;
    OXstable = abs(fltSumOX / seconds - curOX) < delta;

    // Advance buffer pointer
    pntrNH3 = (pntrNH3 + 1) % seconds ;
    pntrRED = (pntrRED + 1) % seconds;
    pntrOX = (pntrOX + 1) % seconds;

    //Mikä kestää?
    if(!NH3stable) {
      Serial.print("(NH3:");
      Serial.print(abs(fltSumNH3 / seconds - curNH3));
      Serial.println(")");
    }
    if(!REDstable) {
      Serial.print("(RED:");
      Serial.print(abs(fltSumRED / seconds - curRED));
      Serial.println(")");
    }
    if(!OXstable) {
      Serial.print("(OX:");
      Serial.print(abs(fltSumOX / seconds - curOX));
      Serial.println(")");
    }

  } while (!NH3stable || !REDstable || !OXstable);

  NH3baseR = fltSumNH3 / seconds;
  REDbaseR = fltSumRED / seconds;
  OXbaseR = fltSumOX / seconds;

  // Store new base resistance values in EEPROM
}

uint16_t getBaseResistance(channel_t channel) {
  /* if (1 == __version) {
     // Version 1 can query every channel independently
     // Reply is 4 bytes long with relevant data in second and third byte
     switch (channel) {
       case CH_NH3:
         return getRuntimeData(CMD_V1_GET_R0_NH3, 4, 1);
       case CH_RED:
         return getRuntimeData(CMD_V1_GET_R0_RED, 4, 1);
       case CH_OX:
         return getRuntimeData(CMD_V1_GET_R0_OX, 4, 1);
     }
    }
    if (2 == __version) {
     // Version 2 uses the same command every time, but different offsets*/
     switch (channel) {
       case CH_NH3:
         return NH3baseR;
       case CH_RED:
         return REDbaseR;
       case CH_OX:
         return OXbaseR;
     }
  //  }
  
  return 0;
}


/**
   Calculates the current resistance ratio for the given channel.

   @param channel
          The channel to request resistance values from.
   @return The floating-point resistance ratio for the given channel.
*/
float getCurrentRatio(channel_t channel) {
  float baseResistance = (float) getBaseResistance(channel);
  float resistance = (float) getResistance(channel);

  return resistance / baseResistance * (1023.0 - baseResistance) / (1023.0 - resistance);
  

  return -1.0;
}

/**
   Measures the gas concentration in ppm for the specified gas.

   @param gas
          The gas to calculate the concentration for.
   @return The current concentration of the gas
           in parts per million (ppm).
*/
float measureMICS(gas_t gas) {
  float ratio;
  float c = 0;

  switch (gas) {
    case CO:
      ratio = getCurrentRatio(CH_RED);
      c = pow(ratio, -1.179) * 4.385;
      break;
    case NO2:
      ratio = getCurrentRatio(CH_OX);
      c = pow(ratio, 1.007) / 6.855;
      break;
    case NH3:
      ratio = getCurrentRatio(CH_NH3);
      c = pow(ratio, -1.67) / 1.47;
      break;
    case C3H8:
      ratio = getCurrentRatio(CH_NH3);
      c = pow(ratio, -2.518) * 570.164;
      break;
    case C4H10:
      ratio = getCurrentRatio(CH_NH3);
      c = pow(ratio, -2.138) * 398.107;
      break;
    case CH4:
      ratio = getCurrentRatio(CH_RED);
      c = pow(ratio, -4.363) * 630.957;
      break;
    case H2:
      ratio = getCurrentRatio(CH_RED);
      c = pow(ratio, -1.8) * 0.73;
      break;
    case C2H5OH:
      ratio = getCurrentRatio(CH_RED);
      c = pow(ratio, -1.552) * 1.622;
      break;
  }

  return isnan(c) ? -1 : c;
}




void setup() {
  // Initialize Serial Monitor for debugging
  BLUETOOTH_SERIAL.begin(9600);
  Serial.begin(9600);
  Serial1.begin(9600); // For PMS5003
  MHZ19B_SERIAL.begin(MHZ19B_BAUDRATE);
  
  // Wait for the sensor to warm up
  delay(2000);

  Serial.println("MICS-6814 Sensor Test v0.1");
  Serial.print("Calibrating Sensor");
  calibrateMICS();
  Serial.println("OK!");

  Wire.begin();
  //Initialize sensor
  if (mySensor.begin() == false) 
{
    Serial.println("No SGP30 Detected. Check connections.");
    while (1);
  }
  //Initializes sensor for air quality readings
  //measureAirQuality should be called in one second increments after a call to initAirQuality
  mySensor.initAirQuality();



}

void readPM() {
  const int timeOut = 2000;
  if (pms.readUntil(data, timeOut)) {
    Serial.print("PM 1.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_1_0);

    BLUETOOTH_SERIAL.print(data.PM_AE_UG_1_0);
    BLUETOOTH_SERIAL.print("ug/m3");
    BLUETOOTH_SERIAL.print(",");

    Serial.print("PM 2.5 (ug/m3): ");
    Serial.println(data.PM_AE_UG_2_5);

    BLUETOOTH_SERIAL.print(data.PM_AE_UG_2_5);
    BLUETOOTH_SERIAL.print("ug/m3");
    BLUETOOTH_SERIAL.print(",");

    Serial.print("PM 10.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_10_0);

    BLUETOOTH_SERIAL.print(data.PM_AE_UG_10_0);
    BLUETOOTH_SERIAL.print("ug/m3");
    BLUETOOTH_SERIAL.print(",");
  } else {
    Serial.println("Failed to read PM data");
  }
}



void readCO2() {
  // Send command to MH-Z19B sensor to read CO2 concentration
  MHZ19B_SERIAL.write(MHZ19B_CMD_READ_CO2, sizeof(MHZ19B_CMD_READ_CO2));
  
  // Read response from the sensor
  uint8_t response[9];
  MHZ19B_SERIAL.readBytes(response, 9);
  
  // Check if response is valid
  if (response[0] == 0xFF && response[1] == 0x86) {
    // Calculate CO2 concentration (high byte * 256 + low byte)
    int co2 = response[2] * 256 + response[3];
    
    // Print CO2 concentration to Serial Monitor
    Serial.print("CO2 Level: ");
    Serial.print(co2);
    Serial.println(" ppm");

    BLUETOOTH_SERIAL.print(co2);
    BLUETOOTH_SERIAL.print("ppm");
    BLUETOOTH_SERIAL.print(",");
  } else {
    // Print error if response is invalid
    Serial.println("Error: Invalid response from sensor");
  }
}

void readtvoc(){
  
  mySensor.measureAirQuality();
  Serial.print(mySensor.TVOC);
  Serial.println(" ppb");
  BLUETOOTH_SERIAL.print(mySensor.TVOC);
  BLUETOOTH_SERIAL.print(" ppb");
  BLUETOOTH_SERIAL.print(",");

}


void readmics(){

  Serial.print("NH3: ");
  Serial.print(getResistance(CH_NH3));
  Serial.print("/");
  Serial.print(getBaseResistance(CH_NH3));
  Serial.print(" = ");
  Serial.print(getCurrentRatio(CH_NH3));
  Serial.print(" => ");  
  Serial.print(measureMICS(NH3));
  Serial.println("ppm");
  BLUETOOTH_SERIAL.print(measureMICS(NH3));
  BLUETOOTH_SERIAL.print("ppm");
  BLUETOOTH_SERIAL.print(",");

  delay(50);

  Serial.print("CO: ");
  Serial.print(getResistance(CH_RED));
  Serial.print("/");
  Serial.print(getBaseResistance(CH_RED));
  Serial.print(" = ");
  Serial.print(getCurrentRatio(CH_RED));
  Serial.print(" => ");  
  Serial.print(measureMICS(CO));
  Serial.println("ppm");
  BLUETOOTH_SERIAL.print(measureMICS(CO));
  BLUETOOTH_SERIAL.print("ppm");
  BLUETOOTH_SERIAL.print(",");

  delay(50);

  Serial.print("NO2: ");
  Serial.print(getResistance(CH_OX));
  Serial.print("/");
  Serial.print(getBaseResistance(CH_OX));
  Serial.print(" = ");
  Serial.print(getCurrentRatio(CH_OX));
  Serial.print(" => ");  
  Serial.print(measureMICS(NO2));
  Serial.println("ppm");
  BLUETOOTH_SERIAL.print(measureMICS(NO2));
  BLUETOOTH_SERIAL.print("ppm");
  BLUETOOTH_SERIAL.print(";");
  

  delay(50);


  delay(1000);
}


void loop() {
  
  readPM();
  readCO2();
  readtvoc();
  readmics();
  delay(2000);
    
}

Everything works, with one exception. Someimes the mhz19b co2 sensor won t show any data. Basically if i unplug the rx or tx of the sensor from arduino mega and put it back, it works, but it seems like it has a delay whenever i exhale on it or something. This problem ocurred when i tried to add another sensor. After that , the co2 didn t show any data and i had to undo everything until today. What could have happened? I power up externally my sensors + arduino using 9v@1A power supply which goes through a dc-dc buck convertert to get 5V.

Draw a block diagram of the power arrangement.

Are you giving 5 volts directly from the regulator to the sensors?

Which Arduino board are you using and how is 5 vo,ts connected to it?

a7

Don't unplug, or plug, any wire when the power is one. Some circuits are destroyd that way.

The 9V of my power supply goes through my dc-dc buck converter and outputs a 5V. The 5V now goes in parallel to all my sensors ( which are modules, not raw sensors so they have resistors, capacitors on the modules). Since the "problem" is only on this sensor, not all of them, i have bo idea why the sensor is "gambling". Also it has a delay whenever i do.

The board is an Arduino mega. I power it up through the 5V pin and it has common ground with my sensors. Whenever I upload code on my Arduino, i remove the wires from 5v and gnd.

licenta.pdf (130.2 KB)
There are a few components on my schematic and some of the sensors connection won t match the code and irl connections.

And the sensor won t require any voltage divider for the high logic of rx. The datasheet says it s compatible with both 3.3 and 5V logic.
image

I'm currently using some sensors and one of them seems like showing values but randomly, there is no continuity, and only after i unplug rx/tx of it and plug it back to arduino mega. This is the code:

#include <math.h>
#include <Arduino.h>
#include "PMS.h"
#include "SparkFun_SGP30_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_SGP30
#include <Wire.h>
 
SGP30 mySensor; //create an object of the SGP30 class
// Define the serial port for MH-Z19B sensor (Serial2 on Arduino Mega)
#define MHZ19B_SERIAL Serial2

// Define the serial port for Bluetooth (Serial3 on Arduino Mega)
#define BLUETOOTH_SERIAL Serial3

// Define the baud rate for MH-Z19B sensor
#define MHZ19B_BAUDRATE 9600



// Define the command to read CO2 concentration
uint8_t MHZ19B_CMD_READ_CO2[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};

PMS pms(Serial1);
PMS::DATA data;


enum channel {
  CH_NH3, CH_RED, CH_OX
};
typedef enum channel channel_t;

// Enum for proper gas declaration
enum gas {
  CO, NO2, NH3, C3H8, C4H10, CH4, H2, C2H5OH
};
typedef enum gas gas_t;

#define NH3PIN A1
#define COPIN A0
#define OXPIN A2

uint16_t NH3baseR;
uint16_t REDbaseR;
uint16_t OXbaseR;

/**
   Requests the current resistance for a given channel
   from the sensor. The value is an ADC value between
   0 and 1024.

   @param channel
          The channel to read the base resistance from.
   @return The unsigned 16-bit base resistance
           of the selected channel.
*/

uint16_t getResistance(channel_t channel) {
      unsigned long rs = 0;
      int counter = 0;

  switch (channel) {
    case CH_NH3:
      for(int i = 0; i < 100; i++) {
        rs += analogRead(NH3PIN);
        counter++;
        delay(2);
      }
      return rs/counter;
    case CH_RED:
      for(int i = 0; i < 100; i++) {
        rs += analogRead(COPIN);
        counter++;
        delay(2);
      }
      return rs/counter;
    case CH_OX:      
      for(int i = 0; i < 100; i++) {
        rs += analogRead(OXPIN);
        counter++;
        delay(2);
      }
      return rs/counter;

  }

  return 0;
}

void calibrateMICS() {
  // Continuously measure the resistance,
  // storing the last N measurements in a circular buffer.
  // Calculate the floating average of the last seconds.
  // If the current measurement is close to the average stop.

  // Seconds to keep stable for successful calibration
  // (Keeps smaller than 64 to prevent overflows)
  uint8_t seconds = 10;
  // Allowed delta for the average from the current value
  uint8_t delta = 2;

  // Circular buffer for the measurements
  uint16_t bufferNH3[seconds];
  uint16_t bufferRED[seconds];
  uint16_t bufferOX[seconds];
  // Pointers for the next element in the buffer
  uint8_t pntrNH3 = 0;
  uint8_t pntrRED = 0;
  uint8_t pntrOX = 0;
  // Current floating sum in the buffer
  uint16_t fltSumNH3 = 0;
  uint16_t fltSumRED = 0;
  uint16_t fltSumOX = 0;

  // Current measurements;
  uint16_t curNH3;
  uint16_t curRED;
  uint16_t curOX;

  // Flag to see if the channels are stable
  bool NH3stable = false;
  bool REDstable = false;
  bool OXstable = false;

  // Initialize buffer
  for (int i = 0; i < seconds; ++i) {
    bufferNH3[i] = 0;
    bufferRED[i] = 0;
    bufferOX[i] = 0;
  }

  do {
    // Wait a second
    delay(1000);
    Serial.print(".");
    // Read new resistances
    unsigned long rs = 0;
    delay(50);
    for (int i = 0; i < 3; i++) {
    delay(1);
    rs += analogRead(NH3PIN);
    }
    curNH3 = rs/3;
    rs = 0;
    delay(50);
    for (int i = 0; i < 3; i++) {
    delay(1);
    rs += analogRead(COPIN);
    }
    curRED = rs/3;
    rs = 0;
    delay(50);
    for (int i = 0; i < 3; i++) {
    delay(1);
    rs += analogRead(OXPIN);
    }
    curOX = rs/3;

    // Update floating sum by subtracting value
    // about to be overwritten and adding the new value.
    fltSumNH3 = fltSumNH3 + curNH3 - bufferNH3[pntrNH3];
    fltSumRED = fltSumRED + curRED - bufferRED[pntrRED];
    fltSumOX = fltSumOX + curOX - bufferOX[pntrOX];

    // Store new measurement in buffer
    bufferNH3[pntrNH3] = curNH3;
    bufferRED[pntrRED] = curRED;
    bufferOX[pntrOX] = curOX;

    // Determine new state of flags
    NH3stable = abs(fltSumNH3 / seconds - curNH3) < delta;
    REDstable = abs(fltSumRED / seconds - curRED) < delta;
    OXstable = abs(fltSumOX / seconds - curOX) < delta;

    // Advance buffer pointer
    pntrNH3 = (pntrNH3 + 1) % seconds ;
    pntrRED = (pntrRED + 1) % seconds;
    pntrOX = (pntrOX + 1) % seconds;

    //Mikä kestää?
    if(!NH3stable) {
      Serial.print("(NH3:");
      Serial.print(abs(fltSumNH3 / seconds - curNH3));
      Serial.println(")");
    }
    if(!REDstable) {
      Serial.print("(RED:");
      Serial.print(abs(fltSumRED / seconds - curRED));
      Serial.println(")");
    }
    if(!OXstable) {
      Serial.print("(OX:");
      Serial.print(abs(fltSumOX / seconds - curOX));
      Serial.println(")");
    }

  } while (!NH3stable || !REDstable || !OXstable);

  NH3baseR = fltSumNH3 / seconds;
  REDbaseR = fltSumRED / seconds;
  OXbaseR = fltSumOX / seconds;

  // Store new base resistance values in EEPROM
}

uint16_t getBaseResistance(channel_t channel) {
  /* if (1 == __version) {
     // Version 1 can query every channel independently
     // Reply is 4 bytes long with relevant data in second and third byte
     switch (channel) {
       case CH_NH3:
         return getRuntimeData(CMD_V1_GET_R0_NH3, 4, 1);
       case CH_RED:
         return getRuntimeData(CMD_V1_GET_R0_RED, 4, 1);
       case CH_OX:
         return getRuntimeData(CMD_V1_GET_R0_OX, 4, 1);
     }
    }
    if (2 == __version) {
     // Version 2 uses the same command every time, but different offsets*/
     switch (channel) {
       case CH_NH3:
         return NH3baseR;
       case CH_RED:
         return REDbaseR;
       case CH_OX:
         return OXbaseR;
     }
  //  }
  
  return 0;
}


/**
   Calculates the current resistance ratio for the given channel.

   @param channel
          The channel to request resistance values from.
   @return The floating-point resistance ratio for the given channel.
*/
float getCurrentRatio(channel_t channel) {
  float baseResistance = (float) getBaseResistance(channel);
  float resistance = (float) getResistance(channel);

  return resistance / baseResistance * (1023.0 - baseResistance) / (1023.0 - resistance);
  

  return -1.0;
}

/**
   Measures the gas concentration in ppm for the specified gas.

   @param gas
          The gas to calculate the concentration for.
   @return The current concentration of the gas
           in parts per million (ppm).
*/
float measureMICS(gas_t gas) {
  float ratio;
  float c = 0;

  switch (gas) {
    case CO:
      ratio = getCurrentRatio(CH_RED);
      c = pow(ratio, -1.179) * 4.385;
      break;
    case NO2:
      ratio = getCurrentRatio(CH_OX);
      c = pow(ratio, 1.007) / 6.855;
      break;
    case NH3:
      ratio = getCurrentRatio(CH_NH3);
      c = pow(ratio, -1.67) / 1.47;
      break;
    case C3H8:
      ratio = getCurrentRatio(CH_NH3);
      c = pow(ratio, -2.518) * 570.164;
      break;
    case C4H10:
      ratio = getCurrentRatio(CH_NH3);
      c = pow(ratio, -2.138) * 398.107;
      break;
    case CH4:
      ratio = getCurrentRatio(CH_RED);
      c = pow(ratio, -4.363) * 630.957;
      break;
    case H2:
      ratio = getCurrentRatio(CH_RED);
      c = pow(ratio, -1.8) * 0.73;
      break;
    case C2H5OH:
      ratio = getCurrentRatio(CH_RED);
      c = pow(ratio, -1.552) * 1.622;
      break;
  }

  return isnan(c) ? -1 : c;
}




void setup() {
  // Initialize Serial Monitor for debugging
  BLUETOOTH_SERIAL.begin(9600);
  Serial.begin(9600);
  Serial1.begin(9600); // For PMS5003
  MHZ19B_SERIAL.begin(MHZ19B_BAUDRATE);
  
  // Wait for the sensor to warm up
  delay(2000);

  Serial.println("MICS-6814 Sensor Test v0.1");
  Serial.print("Calibrating Sensor");
  calibrateMICS();
  Serial.println("OK!");

  Wire.begin();
  //Initialize sensor
  if (mySensor.begin() == false) 
{
    Serial.println("No SGP30 Detected. Check connections.");
    while (1);
  }
  //Initializes sensor for air quality readings
  //measureAirQuality should be called in one second increments after a call to initAirQuality
  mySensor.initAirQuality();



}

void readPM() {
  const int timeOut = 2000;
  if (pms.readUntil(data, timeOut)) {
    Serial.print("PM 1.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_1_0);

    BLUETOOTH_SERIAL.print(data.PM_AE_UG_1_0);
    BLUETOOTH_SERIAL.print("ug/m3");
    BLUETOOTH_SERIAL.print(",");

    Serial.print("PM 2.5 (ug/m3): ");
    Serial.println(data.PM_AE_UG_2_5);

    BLUETOOTH_SERIAL.print(data.PM_AE_UG_2_5);
    BLUETOOTH_SERIAL.print("ug/m3");
    BLUETOOTH_SERIAL.print(",");

    Serial.print("PM 10.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_10_0);

    BLUETOOTH_SERIAL.print(data.PM_AE_UG_10_0);
    BLUETOOTH_SERIAL.print("ug/m3");
    BLUETOOTH_SERIAL.print(",");
  } else {
    Serial.println("Failed to read PM data");
  }
}



void readCO2() {
  // Send command to MH-Z19B sensor to read CO2 concentration
  MHZ19B_SERIAL.write(MHZ19B_CMD_READ_CO2, sizeof(MHZ19B_CMD_READ_CO2));
  
  // Read response from the sensor
  uint8_t response[9];
  MHZ19B_SERIAL.readBytes(response, 9);
  
  // Check if response is valid
  if (response[0] == 0xFF && response[1] == 0x86) {
    // Calculate CO2 concentration (high byte * 256 + low byte)
    int co2 = response[2] * 256 + response[3];
    
    // Print CO2 concentration to Serial Monitor
    Serial.print("CO2 Level: ");
    Serial.print(co2);
    Serial.println(" ppm");

    BLUETOOTH_SERIAL.print(co2);
    BLUETOOTH_SERIAL.print("ppm");
    BLUETOOTH_SERIAL.print(",");
  } else {
    // Print error if response is invalid
    Serial.println("Error: Invalid response from sensor");
  }
}

void readtvoc(){
  
  mySensor.measureAirQuality();
  Serial.print(mySensor.TVOC);
  Serial.println(" ppb");
  BLUETOOTH_SERIAL.print(mySensor.TVOC);
  BLUETOOTH_SERIAL.print(" ppb");
  BLUETOOTH_SERIAL.print(",");

}


void readmics(){

  Serial.print("NH3: ");
  Serial.print(getResistance(CH_NH3));
  Serial.print("/");
  Serial.print(getBaseResistance(CH_NH3));
  Serial.print(" = ");
  Serial.print(getCurrentRatio(CH_NH3));
  Serial.print(" => ");  
  Serial.print(measureMICS(NH3));
  Serial.println("ppm");
  BLUETOOTH_SERIAL.print(measureMICS(NH3));
  BLUETOOTH_SERIAL.print("ppm");
  BLUETOOTH_SERIAL.print(",");

  delay(50);

  Serial.print("CO: ");
  Serial.print(getResistance(CH_RED));
  Serial.print("/");
  Serial.print(getBaseResistance(CH_RED));
  Serial.print(" = ");
  Serial.print(getCurrentRatio(CH_RED));
  Serial.print(" => ");  
  Serial.print(measureMICS(CO));
  Serial.println("ppm");
  BLUETOOTH_SERIAL.print(measureMICS(CO));
  BLUETOOTH_SERIAL.print("ppm");
  BLUETOOTH_SERIAL.print(",");

  delay(50);

  Serial.print("NO2: ");
  Serial.print(getResistance(CH_OX));
  Serial.print("/");
  Serial.print(getBaseResistance(CH_OX));
  Serial.print(" = ");
  Serial.print(getCurrentRatio(CH_OX));
  Serial.print(" => ");  
  Serial.print(measureMICS(NO2));
  Serial.println("ppm");
  BLUETOOTH_SERIAL.print(measureMICS(NO2));
  BLUETOOTH_SERIAL.print("ppm");
  BLUETOOTH_SERIAL.print(";");
  

  delay(50);


  delay(1000);
}


void loop() {
  
  readPM();
  readCO2();
  readtvoc();
  readmics();
  delay(2000);
    
}

Sensors are powered externally using 9V@1A which goes through a dc-dc buck converter to 5V. Every sensor uses 5V. The arduino mega is as well powered like this. I have no idea what could have gone wrong.

Is this the same problem as in Mh-z19b being weird ? If not, what is the difference.

What sensors? Sensors or sensor modules? Which one is showing what problem that you think is random? When you were writing the code, did you intend for the sensors to display readings constantly or only when requested?
What does your circuit look like?

yes, the same. While the devices is working , i have to unplug the rx,tx of my sensor module in order to get its values on my android. The rest of my sensors are working.

Sensor modules: pms5003, sgp30, mics6814, mhz19b ( c02 ) and i want to use as well ms1100 and mq131, but only if i solve the mhz19b issue. There is another problem with mq131, when using this library, which won t work when combining all my sensor's codes, but will work only alone. When the compiler is on the MQ131.calibrate(); line, it just stops the flow and stays there forever, but if i use the sensor alone, i have no problems.

I want to show data every 2 seconds , delay(2000);

This is my circuit, but the pinout is different from my code and irl layout of my components:
licenta.pdf (130.2 KB)

In which case you are wasting peoples time. Person B is not aware of the other topic where person A already replied which wastes person B's time.

It's called cross-posting and is against the forum rules; please stick to one topic per problem.

I've merged your two topics.

It also shows the TTL interface level at 3.3V and your Serial on the Mega is 5V. Did you use a level shifter between the sensor and the Mega?

I'm gonna try to implement that, to see if that's the problem.

1 Like

I suggest you to make test code just for this sensor and see if it's working. Also note that this sensor is slow and it has 3min initial heating time. Is your 5V converter beefy enough to power your setup? Why you use two converters in series for 5V?

Hi, @orlafn_12213

@orlafn_12213 schematic

I would be putting some bypass capacitors around your circuit.

Can you please post some pictures of you project?
So we can see your component layout.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

This from a library for the device:

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

I hope that is no,part of your problem.

a7

I thought about that, but apparently the problem was the library of the mhz. Now it's printing the values and the co2 is increasing whenever i exhale on it. Now I have to implement the next next sensor, mq131, which is kinda annoying, since it has in the library a function, calibrate() , that stops the flow and it's kinda stuck on it when I'm using mq131 with other sensors.

No, it's not. The library was problematic. Now it's printing the values on my phone alongside my other sensor's values but I have to geek the delay. And it's responsive, since the value is increasing while i exhale close to the sensor.