ESP32 and MQ-135 working together, BUT NOT working with other sensors

/*************************************************************
ESP32 + MQ-135 + DHT22
 *************************************************************/

/* Fill-in information from Blynk Device Info here */
#define BLYNK_TEMPLATE_ID           ""
#define BLYNK_TEMPLATE_NAME         ""
#define BLYNK_AUTH_TOKEN            ""

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial


#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

// DHT22
#include "DHT.h"
#define DHTPIN 4     // Pin-ul digital conectat la DHT22
const int mq135Pin = 0;
#define DHTTYPE DHT22
#define REPORTING_PERIOD_MS 1000

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "";
char pass[] = "";

BlynkTimer timer;

// Initializare DHT22
DHT dht(DHTPIN, DHTTYPE);
// Variabila delays
uint32_t tsLastReport = 0;



// This function is called every time the Virtual Pin 0 state changes
BLYNK_WRITE(V0)
{
  // Set incoming value from pin V0 to a variable
  int value = param.asInt();

  // Update state
  Blynk.virtualWrite(V1, value);
}

// This function is called every time the device is connected to the Blynk.Cloud
BLYNK_CONNECTED()
{
  // Change Web Link Button message to "Congratulations!"
  Blynk.setProperty(V3, "offImageUrl", "https://static-image.nyc3.cdn.digitaloceanspaces.com/general/fte/congratulations.png");
  Blynk.setProperty(V3, "onImageUrl",  "https://static-image.nyc3.cdn.digitaloceanspaces.com/general/fte/congratulations_pressed.png");
  Blynk.setProperty(V3, "url", "https://docs.blynk.io/en/getting-started/what-do-i-need-to-blynk/how-quickstart-device-was-made");
}

// This function sends Arduino's uptime every second to Virtual Pin 2.
void myTimerEvent()
{
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V2, millis() / 1000);
  if (millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    if (isnan(h) || isnan(t)) {
      Serial.println(F("Failed to read from DHT sensor!"));
      return;
    }
    // Compute heat index in Celsius (isFahreheit = false)
    float hic = dht.computeHeatIndex(t, h, false);
    Blynk.virtualWrite(V4, h);
    Blynk.virtualWrite(V5, t);
    Blynk.virtualWrite(V6, hic);
    int sensorValue = analogRead(mq135Pin); // Pin 0 used 
    Serial.println(sensorValue); // Reading ONLY value of 0
    tsLastReport = millis();
  }
}

void setup()
{
  // Debug console
  Serial.begin(115200);

  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
  // You can also specify server:
  //Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
  //Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);

  // Setup a function to be called every second
  timer.setInterval(1000L, myTimerEvent);
  dht.begin();
}

void loop()
{
  Blynk.run();
  timer.run();

  // You can inject your own code or combine it with other sketches.
  // Check other examples on how to communicate with Blynk. Remember
  // to avoid delay() function!
}

This is working!

// Define the analog pin connected to the MQ-135 sensor
const int mq135Pin = 0;
uint32_t tsLastReport = 0;

#define REPORTING_PERIOD_MS 1000
void setup() {
  // Start the serial communication
  Serial.begin(115200);
}

void loop() {
if (millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    int sensorValue = analogRead(mq135Pin);
    Serial.println(sensorValue);
    tsLastReport = millis();
  }
}

(There's no point in sending it to Blynk if there is no value)

First code serial output:

Second code serial output:

Also the range of values change for every pin taken. As of now, with the 1st code which is displaying 0 values and 2nd working code, the voltage between literal PIN0 and GND is the same ~2.7V. I have to mention that I connected 1KOhm resistor between AO of MQ-135 and PIN0 (such that it takes no damage, because these ESP32 pins operate at 3.3V - that's what I remember I read.)

I also mention that I've disconnected my LCD which could be a power drainer.

Any advices?

Well apparently it doesn't work with Blynk. So it works with Blynk.begin() deleted. Does the ESP32 draw too much power for WiFi capabalities? Interestingly enough it works with DHT22.

if you suspect a power-supply-issue did you measure how much current your sensor is drawing?

Some USB-wires have really really thin copperwires which might lead to a significant voltage-drop.
I had differencies in the charge-current for smartphones between 0,3A with a bad cable and 1,2A with a very good cable.

The ESP's are known for short but high current-spikes. A big capacitor (2200 µF) at nearest possible position to Vin and GND and another one nearest to 3.3V and GND can help.

The onboard voltage-regulator has a limited current.
I would add serial printing starting right at

void setup() {
  Serial.begin();
  Serial.println("setup-Start");

to see if the "not working happends at void setup() or somehwhere below

best regards Stefan

1 Like

Hello, I have been working on this and found the problem. In the initial post the mq135Pin was connected to the 0 PIN of the ESP32. After some research I've found code that worked where the Pin was 32. I don't know exactly why it's behaving like this.

This is the code that works with an ESP32, MQ-135, DHT22, a fan module (INB,INA,VCC,GND), a piezoBuzzer module (high trigger) and Blynk.

#define BLYNK_TEMPLATE_ID           "TMPLxxxxx"
#define BLYNK_TEMPLATE_NAME         "Quickstart Template"
#define BLYNK_AUTH_TOKEN            "Q-xxxx"

#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

#include <DHT.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

int lcdColumns = 16;
int lcdRows = 2;

byte degree_symbol[8] =
{
  0b00111,
  0b00101,
  0b00111,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

char auth[] = BLYNK_AUTH_TOKEN;

char ssid[] = "xxxx";  // type your wifi name
char pass[] = "xxxx";  // type your wifi password

BlynkTimer timer;

#define REPORT_TIME 1000
int mq135Pin = 32;
int sensorThreshold = 100;
const int buzzerPin = 14;  // Pin 14 as the buzzer output
uint32_t tsLastReport = 0;

#define DHTPIN 4 //Connect Out pin to D2 in NODE MCU
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

int A1A = 12;
int A1B = 13;

void sendSensor()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit


  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  int analogSensor = analogRead(mq135Pin);
  Blynk.virtualWrite(V7, analogSensor);
  Serial.print("mq135Pin Value: ");
  Serial.println(analogSensor);
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V4, h);
  Blynk.virtualWrite(V5, t);
  float hic = dht.computeHeatIndex(t, h, false);
  Blynk.virtualWrite(V6, hic);

  Serial.print("Temperature : ");
  Serial.print(t);
  Serial.print("    Humidity : ");
  Serial.println(h);


}
void setup()
{
  pinMode(A1A, OUTPUT);
  pinMode(A1B, OUTPUT);

  pinMode(buzzerPin, OUTPUT);
  Serial.begin(115200);

  //pinMode(mq135Pin, INPUT);
  Blynk.begin(auth, ssid, pass);
  dht.begin();
  timer.setInterval(7000L, sendSensor);
  lcd.init();
  // turn on LCD backlight
  lcd.backlight();


  //  lcd.backlight();
  // lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("Monitorizare");
  lcd.setCursor(3, 1);
  lcd.print("Calitate Aer");
  delay(2000);
  lcd.clear();

  byte smiley[8] = {
    B00000,
    B10001,
    B00000,
    B00000,
    B10001,
    B01110,
    B00000,
  };

  byte sadFace[8] = {
    B00000,
    B10001,
    B00000,
    B00000,
    B01110,
    B10001,
    B00000,
  };

  // Load custom characters into LCD memory
  lcd.createChar(0, smiley);
  lcd.createChar(1, sadFace);
}

void loop()
{
  Blynk.run();
  timer.run();

  float h = dht.readHumidity();
  float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
  int analogSensor = analogRead(mq135Pin);

  if (t > 25)
  {

    digitalWrite(buzzerPin, HIGH);
    digitalWrite(A1A, HIGH);
    digitalWrite(A1B, LOW);

  } else if (t <= 25)
  {
    digitalWrite(buzzerPin, LOW);
    digitalWrite(A1A, LOW);
    digitalWrite(A1B, LOW);
  }

  float hic = dht.computeHeatIndex(t, h, false);


  // set cursor to first column, first row
  lcd.setCursor(0, 0);
  lcd.print(F("Temp: "));
  lcd.print(t);
  lcd.print((char)223);
  lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print(F("Hum: "));
  lcd.print(h);
  lcd.print(F("% "));
  lcd.write(0);
  delay(4000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("Index C: "));
  lcd.print(hic);
  lcd.print((char)223);
  lcd.print("C");
  delay(4000);
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print(F("Air Q: "));
  lcd.print(analogSensor);
  lcd.print(" ppm");
  delay(4000);
  lcd.clear();
}

I haven't come to the final behaviour of the system which requires just some more conditions put in the code that takes into account the mq135 value for some triggering events. I know it is recommended to avoid delays in the code, but this way I have my parameters uploaded onto cloud with no problem as of now. Maybe I will use something like

uint32_t tsLastReport = 0; // global var
// and in loop()
if(tsLastreport - millis() > REPORTING_TIME)
{
//output readings or calculate them or IDK
 tsLastReport = millis();
}

Thanks for your answer Stefan.

Good luck, everyone!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.