Why my mq-135 sensor keeps showing value 0 on serial monitor

hello I have some problem only with the mq135 sensor for detecting amonia (other parameters like ph and flow meter works with the code). amonia sensor keeps showing value 0 when I'm using the wifi and influxdb set up code. but when I try without wifi and influxdb setup code the amonia sensor works. it shows the value of the measurements

note: I'm using ESP32 board and the code below is for wifi and influxdb setup. I'm using grafana for monitoring.

here's the code:

#include <WiFi.h>
#include <InfluxDbClient.h>
#include <SPI.h>
#include <Wire.h>

#define SENSORFLOW  14     //SENSORFLOW1
#define SENSORFLOW1 26    //SENSORFLOW2
#define LED_BUILTIN 2     //SENSORFLOW
#define MQ_sensor 15      //SENSORAMONIA
#define RL 20             //SENSORAMONIA
#define m -0.243          //SENSORAMONIA
#define b 0.323           //SENSORAMONIA
#define Ro 4.01            //SENSORAMONIA


long currentMillis = 0;           //SENSORFLOW1
long previousMillis = 0;          //SENSORFLOW1
int interval = 1000;              //SENSORFLOW1
boolean ledState = LOW;           //SENSORFLOW1
float calibrationFactor = 4.5;    //SENSORFLOW1
volatile byte pulseCount;         //SENSORFLOW1
byte pulse1Sec = 0;               //SENSORFLOW1
float flowRate;                   //SENSORFLOW1
unsigned long flowMilliLitres;    //SENSORFLOW1
unsigned int totalMilliLitres;    //SENSORFLOW1
float flowLitres;                 //SENSORFLOW1
float totalLitres;                //SENSORFLOW1
 
void IRAM_ATTR pulseCounter()     //SENSORFLOW1
{                                 //SENSORFLOW1
  pulseCount++;                   //SENSORFLOW1
}                                 //SENSORFLOW1

long currentMillis1 = 0;           //SENSORFLOW2
long previousMillis1 = 0;          //SENSORFLOW2
int interval1 = 1000;              //SENSORFLOW2
boolean ledState1 = LOW;           //SENSORFLOW2
float calibrationFactor1 = 4.5;    //SENSORFLOW2
volatile byte pulseCount1;         //SENSORFLOW2
byte pulse1Sec1 = 0;               //SENSORFLOW2
float flowRate1;                   //SENSORFLOW2
unsigned long flowMilliLitres1;    //SENSORFLOW2
unsigned int totalMilliLitres1;    //SENSORFLOW2
float flowLitres1;                 //SENSORFLOW2
float totalLitres1;                //SENSORFLOW2
 
void IRAM_ATTR pulseCounter1()     //SENSORFLOW2
{                                 //SENSORFLOW2
  pulseCount1++;                   //SENSORFLOW2
}                                 //SENSORFLOW2

const int ph_Pin  = 34;            //SENSOR PH
float Po = 0;                     //SENSOR PH
float PH_step;                    //SENSOR PH
int nilai_analog_PH;              //SENSOR PH
double TeganganPh;                //SENSOR PH

float PH4 = 4.28;                 //untuk kalibrasi PH
float PH7 = 3.52;                //untuk kalibrasi PH

const int numReadings = 5;        //SENSORAMONIA
float readings[numReadings];      //SENSORAMONIA
int readIndex = 0;                //SENSORAMONIA
float total = 0;                  //SENSORAMONIA
float average = 0;                //SENSORAMONIA


// WiFi AP SSID
#define WIFI_SSID "Alip"
// WiFi password
#define WIFI_PASSWORD "alip1420"
// InfluxDB  server url. Don't use localhost, always server name or ip address.
// E.g. http://192.168.0.101:8086 (In InfluxDB 2 UI -> Load Data -> Client Libraries), 
#define INFLUXDB_URL "http://192.168.0.100:8086"
// InfluxDB 2 server or cloud API authentication token (Use: InfluxDB UI -> Load Data -> Tokens -> <select token>)
#define INFLUXDB_TOKEN "toked-id"
// InfluxDB 2 organization id (Use: InfluxDB UI -> Settings -> Profile -> <name under tile> )
#define INFLUXDB_ORG "org"
// InfluxDB 2 bucket name (Use: InfluxDB UI -> Load Data -> Buckets)
#define INFLUXDB_BUCKET "bucket"
// InfluxDB v1 database name 
#define INFLUXDB_DB_NAME "skripsi"

// InfluxDB client instance
//InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN);
// InfluxDB client instance for InfluxDB 1
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_DB_NAME);

// Data point
Point sensor("MONITORING IPAL");

void setup() {
 Serial.begin(9600); 
 for (int thisReading = 0; thisReading < numReadings; thisReading++) {   //SENSORAMONIA
  readings[thisReading] = 0;                                              //SENSORAMONIA
  }                                                                       //SENSORAMONIA
  for (int times = 1; times <=3; times++) {                               //SENSORAMONIA
  Serial.println ("  pre heating");                                     //SENSORAMONIA
  Serial.println(times);                                                //SENSORAMONIA
  Serial.println (" seconds");                                          //SENSORAMONIA
  delay(1000);                                                          //SENSORAMONIA
  }

   // Connect WiFi
  Serial.println("Connecting to WiFi");
  delay (1000);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("WiFi berhasil konek");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Set InfluxDB 1 authentication params
  //client.setConnectionParamsV1(INFLUXDB_URL, INFLUXDB_DB_NAME, INFLUXDB_USER, INFLUXDB_PASSWORD);

//****** Bagian  koneksi dari influxdb
  while (client.validateConnection() == false)
  {
    Serial.print("InfluxDB connection failed: ");
    Serial.println(client.getLastErrorMessage());
    delay(5000);
  }
     Serial.print("Connected to InfluxDB: ");
    Serial.println(client.getServerUrl());

  // Check server connection
  if (client.validateConnection()) {
    Serial.print("Connected to InfluxDB: ");
    Serial.println(client.getServerUrl());
  } else {
    Serial.print("InfluxDB connection failed: ");
    Serial.println(client.getLastErrorMessage());
  }
 
  pinMode (ph_Pin, INPUT);              //SENSOR PH
  pinMode(LED_BUILTIN, OUTPUT);         //SENSORFLOW1
  pinMode(SENSORFLOW, INPUT_PULLUP);    //SENSORFLOW1
  pinMode(SENSORFLOW1, INPUT_PULLUP);   //SENSORFLOW2
  pulseCount = 0;                       //SENSORFLOW1
  flowRate = 0.0;                       //SENSORFLOW1
  flowMilliLitres = 0;                  //SENSORFLOW1
  totalMilliLitres = 0;                 //SENSORFLOW1
  previousMillis = 0;                   //SENSORFLOW1
  attachInterrupt(digitalPinToInterrupt(SENSORFLOW), pulseCounter, FALLING);  //SENSORFLOW1
  pulseCount1 = 0;                       //SENSORFLOW2
  flowRate1 = 0.0;                       //SENSORFLOW2
  flowMilliLitres1 = 0;                  //SENSORFLOW2
  totalMilliLitres1 = 0;                 //SENSORFLOW2
  previousMillis1 = 0;                   //SENSORFLOW2
  attachInterrupt(digitalPinToInterrupt(SENSORFLOW1), pulseCounter1, FALLING);  //SENSORFLOW2
  
}

void loop() {
   currentMillis = millis();                             //SENSORFLOW1
  if (currentMillis - previousMillis > interval)        //SENSORFLOW1
  {  
    pulse1Sec = pulseCount;                             //SENSORFLOW1
    pulseCount = 0;                                     //SENSORFLOW1
    flowRate = ((1000.0 / (millis() - previousMillis))* pulse1Sec) / calibrationFactor;  //SENSORFLOW1
    previousMillis = millis();                          //SENSORFLOW1
    flowMilliLitres = (flowRate / 60) * 10000;           //SENSORFLOW1
    flowLitres = (flowRate / 60);                       //SENSORFLOW1
    totalMilliLitres += flowMilliLitres;                //SENSORFLOW1
    totalLitres += flowLitres * 10;                          //SENSORFLOW1
    Serial.print("Flow rate: ");                        //SENSORFLOW1
    Serial.print(float(flowRate));                      //SENSORFLOW1
    Serial.print("L/min");                              //SENSORFLOW1
    Serial.print("\t");                                 //SENSORFLOW1
    Serial.print("Output Liquid Quantity: ");           //SENSORFLOW1
    Serial.print(totalMilliLitres);                     //SENSORFLOW1
    Serial.print("mL / ");                              //SENSORFLOW1
    Serial.print(totalLitres);                          //SENSORFLOW1
    Serial.println("L");                                //SENSORFLOW1
    delay(1000);
  }

  currentMillis1 = millis();                               //SENSORFLOW2
  if (currentMillis1 - previousMillis1 > interval1)        //SENSORFLOW2
  {  
    pulse1Sec1 = pulseCount1;                              //SENSORFLOW2
    pulseCount1 = 0;                                       //SENSORFLOW2
    flowRate1 = ((1000.0 / (millis() - previousMillis1))* pulse1Sec1) / calibrationFactor1;  //SENSORFLOW2
    previousMillis1 = millis();                            //SENSORFLOW2
    flowMilliLitres1 = (flowRate1 / 60) * 10000;            //SENSORFLOW2
    flowLitres1 = (flowRate1 / 60);                        //SENSORFLOW2
    totalMilliLitres1 += flowMilliLitres1;                 //SENSORFLOW2
    totalLitres1 += flowLitres1 * 10;                           //SENSORFLOW2
    
    Serial.print("Flow rate Out : ");                           //SENSORFLOW2
    Serial.print(float(flowRate1));                        //SENSORFLOW2
    Serial.print("L/min");                                 //SENSORFLOW2
    Serial.print("\t");                                    //SENSORFLOW2
    Serial.print("Output Liquid Quantity Out: ");              //SENSORFLOW2
    Serial.print(totalMilliLitres1);                       //SENSORFLOW2
    Serial.print("mL / ");                                 //SENSORFLOW2
    Serial.print(totalLitres1);                            //SENSORFLOW2
    Serial.println("L");                                   //SENSORFLOW2
    delay(1000);
  }
 
  nilai_analog_PH = analogRead(ph_Pin);         //SENSOR PH
  Serial.print("Nilai ADC Ph: ");               //SENSOR PH
  Serial.println(nilai_analog_PH);              //SENSOR PH
  TeganganPh = 5.0 / 4095.0 * nilai_analog_PH;  //SENSOR PH
  Serial.print("TeganganPh: ");                 //SENSOR PH
  Serial.println(TeganganPh, 3);                //SENSOR PH
  PH_step = (PH4 - PH7) / 3;                    //SENSOR PH
  Po = 7.00 + ((PH7 - TeganganPh) / PH_step);   //SENSOR PH
  Serial.print("Nilai PH cairan: ");            //SENSOR PH
  
  Serial.println(Po, 2);                        //SENSOR PH
  delay(1000);                                  //SENSOR PH


  float VRL;                                          //SENSORAMONIA
  float RS;                                           //SENSORAMONIA
  float ratio;                                        //SENSORAMONIA
  VRL = analogRead(MQ_sensor)*(5/4095.0);             //SENSORAMONIA
  RS =(5 /VRL-1)*10 ;                               //SENSORAMONIA
  ratio = RS/Ro;                                      //SENSORAMONIA
  float ppm = pow(10, ((log10(ratio)-b)/m));          //SENSORAMONIA
  total = total - readings[readIndex];                //SENSORAMONIA
  readings[readIndex] = ppm;                          //SENSORAMONIA
  total = total + readings[readIndex];                //SENSORAMONIA
  readIndex = readIndex + 1;                          //SENSORAMONIA
  if (readIndex >= numReadings) {                     //SENSORAMONIA
    readIndex = 0;                                    //SENSORAMONIA
  }
  average = total / numReadings;                      //SENSORAMONIA
  

  Serial.println("amonia");                          //SENSORAMONIA
  Serial.println(average);                            //SENSORAMONIA
  delay(1000);                                        //SENSORAMONIA
 
  // Store measured value into point
  
  sensor.addField("amonia", average);
  sensor.addField("input", totalLitres);
  sensor.addField("output", totalLitres1);
  sensor.addField("pH", Po,2);
  //client.writePoint(namatabel);
  // Print what are we exactly writing
  Serial.print("Writing: ");
  Serial.println(client.pointToLineProtocol(sensor));

   if (!client.writePoint(sensor)) {
    Serial.print("InfluxDB write failed: ");
    Serial.println(client.getLastErrorMessage());
  }
    delay(1000);

  delay(1000);
  }

Successful programmers start with the working code, and add one new feature at a time.

Make sure that the new feature, and the old code work properly, before adding a second feature.

1 Like

Hello! Thankyou for the answer :blush: but wdym about the new/second features? ( I'm not good in english I'm sorry if I kinda misunderstood sometimes :grin:)

Add one new "thing" at time to your working code, and make sure everything still works.

You decide what that "thing" is.

1 Like

I see! Thankyou for the explanation :relaxed:

No experience with the A/D of an ESP32, but this page says to avoid ADC2 pins when WiFi is used.
You use pin15 (ADC2) for the MQ135.
Also note that the MQ135 draws 150mA, and that could be too much to tap from the ESP's supply pins.

This line assumes a 5volt logic processor, which the ESP32 is not.
Leo..

Unless it has been corrected on the latest versions of the processor, the ESP32 ADC is so nonlinear as to be nearly useless.

For example: Fixing the non linear ADC of an ESP32

That might not be that relevant for an MQ135 sensor.
Assuming OP has a 'bare' sensor, and not a module...
Resistance variation of the sensor is limited, so it's not hard to get it's output in the middle of the A/D range of the ESP32 where the A/D is fairly linear.

As suggested, OP should first get the sensor working/calibrate without all the other/WiFi crap.
Leo..

That might not be that relevant for an MQ135 sensor.

OF COURSE it is relevant. This is complete nonsense:

  VRL = analogRead(MQ_sensor)*(5/4095.0);             //SENSORAMONIA
  RS =(5 /VRL-1)*10 ;                               //SENSORAMONIA
  ratio = RS/Ro;                                      //SENSORAMONIA

The ESP32 ADC won't work to measure the pH, either.

Hi,
Can you please post a schematic of your project?
Please do not use Fritzy, a hand drawn image will be fine.
Include ALL power supplies, component names and pin labels.

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

I said "not that relevant", assuming that you can force the sensor to output 0.5-2.5volt, avoiding the bad extremes of that A/D. An ADS1115 external A/D could be a much better solution.
Leo..

Hello! Thankyou soo much for the answer. I change the 15 gpio pins into 35 gpio pins and it works! Thankyou so much you're so helpfull!

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