Search code examples
iotesp32

How to read multiple sensor and send the data to ThingSpeak?


I have a problem with my code. When I test it without ThingSpeak library, my sensor values (especially for analogRead on fireLevel dan gasLevel) are there (not 0). But when I use ThingSpeak library for send the data, the fireLevel dan gasLevel show 0 for the values. Any solutions for my code, thanks I'm still learning The sensor that I used:

  1. DHT11
  2. KY-026
  3. MQ-135

and for the NodeMCU I used ESP32 type

#include <WiFi.h>
#include "ThingSpeak.h"
#include <SPI.h>
#include <Wire.h>
#include <DHT.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

const char* ssid = "SECRET_SSID";
const char* password = "SECRET_PASSWORD";

WiFiClient client;

unsigned long channelNum = X;
const char* APIKey = "SECRET_KEY";

#define AIRQ_SENSOR 2 // ESP32 pin GIP2 connected to mq135 sensor
#define DHT_SENSOR_PIN  13 // ESP32 pin GIOP13 connected to DHT11 sensor
#define DHT_SENSOR_TYPE DHT11
#define FIRE_SENSOR_ANALOG 14 // ESP32 pin GIP14 connected to Fire sensor
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
DHT dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
float humi, tempC, gasLevel, fireLevel;
String quality = "";

const uint8_t bitmap19[] = {0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x40, 0x00, 0x7f, 0x60, 0x00, 0xff, 0xe0, 0x00, 0xff, 0xf0, 0x06, 0xff, 0xf0, 0x07, 0xff, 0xf8, 0x07, 0xff, 0xf8, 0x0f, 0xf7, 0xf8, 0x0f, 0xe7, 0xf8, 0x1f, 0xe3, 0xfc, 0x1f, 0xc1, 0xfc, 0x3f, 0x80, 0xfc, 0x3f, 0x80, 0xf8, 0x1f, 0x00, 0xf8, 0x1f, 0x00, 0xf0, 0x0f, 0x00, 0xe0, 0x07, 0x80, 0xc0, 0x01, 0x81, 0x00};

void setup() {
  Serial.begin(9600);
  dht_sensor.begin(); // initialize the DHT sensor
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  
  display.setTextSize(2);
  display.setCursor(50, 0);
  display.println("Air");
  display.setTextSize(1);
  display.setCursor(23, 20);
  display.println("Quality Monitor");
  display.display();
  delay(1200);
  display.clearDisplay();

  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);
}

void fireSensor() {
  fireLevel = analogRead(FIRE_SENSOR_ANALOG);
  Serial.println("fire level: " + String(fireLevel));
  if(fireLevel < 2000) {
    display.drawBitmap(90, 35, bitmap19, 24, 24, 1);
  }
  else {
    display.clearDisplay();
  }
}

void temphSensor() {
  // read humidity
  humi  = dht_sensor.readHumidity();
  // read temperature in Celsius
  tempC = dht_sensor.readTemperature();

  // check whether the reading is successful or not
  if ( isnan(tempC) || isnan(humi)) {
    Serial.println("Failed to read from DHT sensor!");
  } else {
    display.setTextColor(WHITE);
    display.setTextSize(1);
    display.setCursor(0, 35);
    display.println("Tmp:");
    display.setCursor(30, 35);
    display.println(tempC);
    display.setCursor(64, 35);
    display.println("C");
    display.setCursor(0, 50);
    display.println("RH:");
    display.setCursor(30, 50);
    display.println(humi);
    display.setCursor(64, 50);
    display.println("%");
  }
}

void airqSensor() {
  gasLevel = analogRead(AIRQ_SENSOR);

  Serial.println("gas Level: " + String(gasLevel));
  if(gasLevel < 500) {
    quality = "Good";
  }
  else if(gasLevel < 750) {
    // avg 750
    quality = "Moderate";
  }
  else if(gasLevel < 1500) {
    // avg 1500
    quality = "Unhealty";
  }
  else {
    // 2000 >
    quality = "Hazardous";
  }

  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(30, 5);
  display.println("Air Quality");
  display.setCursor(35, 20);
  display.println(quality);
}

void writeThingSpeak() {
  ThingSpeak.setField(1, tempC);
  ThingSpeak.setField(2, humi);
  ThingSpeak.setField(3, gasLevel);
  ThingSpeak.setField(4, fireLevel);

  int x = ThingSpeak.writeFields(channelNum, APIKey);

  if(x == 200) {
    Serial.println("Channel update successful.");
  }
  else {
    Serial.println("Problem updating channel. HTTP error code " + String(x));
  }
  delay(15000);
}

void loop() {
  display.clearDisplay();

  if(WiFi.status() != WL_CONNECTED){
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    while(WiFi.status() != WL_CONNECTED){
      WiFi.begin(ssid, password);  // Connect to WPA/WPA2 network. Change this line if using open or WEP network
      Serial.print(".");
      delay(5000);     
    } 
    Serial.println("\nConnected.");
  }

  fireSensor();
  airqSensor();
  temphSensor();
  display.display();
  writeThingSpeak();
}

Solution

  • After further search I found a solution about my question. The problem is I used ADC2 for my sensor (ex: MQ-135 and KY-026) which is used to read an analog. In this case I put my sensor on GPIO2 and GPIO4, which is among the ADC2.

    List of ADC2s are: GPIO pins 0, 2, 4, 12, 13, 14, 15, 25, 26 and 27. So, instead use ADC2 that originally if you used a WiFi connection on your ESP32, just use ADC1.

    List of ADC1s are: GPIO pins 32, 33, 34, 35, 36, 37, 38 and 39.

    When I changed my AO pins for both of my sensors (MQ-135 and KY-026) to GPIO34 and 35 it worked!

    reference: esp32 pinout reference