Sensor Kualiti Udara SGP30 dengan Arduino & ESP32: Wiring, Baca TVOC dan eCO2

Cartoon of a dark-blue SGP30 sensor module with a silver metal-lid sensor, teal scent lines reaching it from a marker pen, spray bottle and coffee cup, with an open window on the right

Selepas header empat pin yang dibekalkan berasingan itu disolder, sensor kualiti udara GY-SGP30 boleh disambung ke Arduino Uno atau ESP32 dengan empat jumper sahaja β€” VIN, GND dan dua talian I2C ke A4/A5 atau GPIO21/22 β€” dan library Adafruit_SGP30 membaca TVOC dan eCO2 daripada alamat 0x58. Tetapi nombornya perlu ditafsir dengan betul: 15 saat pertama memang sengaja ditetapkan pada 400 ppm dan 0 ppb, 12 jam pertama ialah masa sensor belajar mengenali udara bersih, dan eCO2 bukanlah CO2 yang diukur secara langsung.

Apa sebenarnya yang diukur oleh SGP30 β€” dan adakah eCO2 itu CO2 sebenar?

SGP30 ialah sensor gas oksida logam (MOX): satu plat pemanas mikro (micro-hotplate) mengekalkan lapisan nipis oksida logam pada suhu yang sangat tinggi. Dalam udara bersih, oksigen melekat pada permukaan panas itu dan memerangkap elektron daripada lapisan tersebut, lalu rintangan elektriknya naik; gas penurun (reducing gas) seperti hidrogen, alkohol atau kebanyakan VOC bertindak balas dengan oksigen yang terperangkap itu, elektron mengalir kembali, dan rintangannya jatuh. Cip ini memerhati kesan tersebut pada dua saluran β€” isyarat hidrogen (H2) dan isyarat etanol β€” dan algoritma di dalam cip menukarnya kepada dua nombor yang anda baca melalui I2C: TVOC (jumlah sebatian organik meruap, 0–60,000 ppb) dan eCO2 (400–60,000 ppm), menurut datasheet Sensirion SGP30. Pemanas itu juga sebabnya sensor ini menarik kira-kira 48 mA semasa mengukur β€” lebih tinggi daripada hampir semua breakout I2C lain, tetapi masih tiada masalah jika dibekalkan daripada pin kuasa Uno atau ESP32.

Huruf “e” dalam eCO2 itu membawa maksud yang besar. Tiada apa-apa di dalam sensor ini yang mengukur karbon dioksida β€” CO2 sudah teroksida sepenuhnya, jadi ia tidak boleh bertindak balas dengan oksigen yang terperangkap, tidak membebaskan elektron dan langsung tidak mengubah rintangan lapisan itu. SGP30 menganggarkan nilai setara CO2 daripada saluran hidrogennya: nafas yang dihembus membawa hidrogen hasil pencernaan, dan bilik yang berpenghuni dipenuhi VOC, jadi dalam kehidupan harian di dalam bangunan, isyarat-isyarat itu biasanya naik dan turun seiring dengan CO2 sebenar. Ini menjadikan eCO2 jawapan yang baik kepada soalan “adakah orang dan aktiviti mereka sedang membebankan udara bilik ini?” β€” tetapi alat yang salah untuk mengesahkan kadar pengudaraan atau keselamatan CO2, kerana dalam situasi itu, korelasi tersebut ialah perkara yang sebenarnya perlu diuji. Untuk mengira molekul CO2 sebenar, anda perlukan sensor optik NDIR seperti SCD30 dalam binaan monitor kualiti udara ESP32 kami.

Jadi, baca kedua-dua output sebagai penunjuk trend, bukan ukuran makmal. Buka penutup marker kekal di sebelah sensor dan TVOC melonjak dalam beberapa saat; buka tingkap dan kedua-dua nombor menurun perlahan-lahan.

Komponen pilihan

ItemPriceQty
NodeMCU ESP32 Wi-Fi + Bluetooth Development Board CH340/CP2012 - For IOT Project - ESP-32 (CH340)NodeMCU ESP32 Wi-Fi + Bluetooth Development Board CH340/CP2012 - For IOT Project - ESP-32 (CH340)E32CH34RM29.90
Data Cable Type-A Type-C MicroUSB Type-B 0.5m 1m 30cm 0.3m 100cm Data Transfer Upload Code - TYPE-A TO TYPE-C CABLE (1.0M)Data Cable Type-A Type-C MicroUSB Type-B 0.5m 1m 30cm 0.3m 100cm Data Transfer Upload Code - TYPE-A TO TYPE-C CABLE (1.0M)ATCC100RM5.90
Soldering Service for Circuit Boards & Electronics - 5 Pins Soldering ServiceSoldering Service for Circuit Boards & Electronics - 5 Pins Soldering ServiceSOLSE05RM0.80
DHT 11 DHT 22 Temperature and Humidity Sensor DHT22 High Sensitivity Sensor DHT11 For Aduino IOT - DHT22 SENSORDHT 11 DHT 22 Temperature and Humidity Sensor DHT22 High Sensitivity Sensor DHT11 For Aduino IOT - DHT22 SENSORDHT22HTRM14.95
0.96β€˜ OLED Display Module Blue White Screen I2C IIC Serial 128X64 LCD Display Board - 0.96' OLED BLUE0.96β€˜ OLED Display Module Blue White Screen I2C IIC Serial 128X64 LCD Display Board - 0.96' OLED BLUE096OLBLRM15.80Kehabisan stok

Lebih suka dashboard WiFi? ESP32 boleh menggantikan Uno β€” port USB-C-nya memerlukan kabel data, bukan kabel cas sahaja. Tiada soldering iron? Servis solder 5 pin menyiapkan empat sambungan header SGP30 sebelum ia dihantar. DHT22 membekalkan nilai untuk pampasan kelembapan yang diterangkan di bawah, dan OLED memaparkan bacaan tanpa perlu laptop.

Bagaimana nak sambung GY-SGP30 ke Arduino Uno atau ESP32?

Modul GY-SGP30 sampai dengan header empat pinnya sebagai jalur yang berasingan β€” lubang bersalut bertanda VIN, GND, SCL dan SDA di bahagian belakang masih kosong, jadi langkah pertama ialah empat sambungan solder. Panduan solder header pin kami menerangkannya langkah demi langkah dengan segulung timah solder; kalau tak mahu solder sendiri, tandakan servis solder dalam baris pilihan dan header akan sampai dalam keadaan sudah disolder.

Selepas header dipasang, binaan ini hanya perlukan empat wayar. Cucuk modul pada breadboard dan sambungkan jumper dupont male-to-male yang fleksibel ke Uno β€” kata kuncinya ialah fleksibel, kerana wayar tegar berbentuk U daripada kit jumper breadboard hanya menjambatkan lubang di dalam breadboard dan tidak sampai ke header female Uno. Dengan header yang sudah disolder, anda juga boleh terus tanpa breadboard: wayar male-to-female menyambungkan modul terus ke Uno. ESP32 juga memerlukan wayar jenis ini, kerana pinnya jenis male: hujung male dicucuk ke breadboard di sebelah modul, hujung female ke pin ESP32.

Pin GY-SGP30 Arduino Uno ESP32 (DevKit 30 pin)
VIN 5V 3V3
GND GND GND
SCL A5 (atau pin SCL berhampiran bucu USB) GPIO22
SDA A4 (atau pin SDA di sebelahnya) GPIO21

Kedua-dua voltan bekalan itu betul, dan inilah sebabnya: cip Sensirion itu sendiri berjalan pada rel kelas 1.8V β€” 1.62–1.98V, dengan maksimum mutlak 2.16V β€” jadi breakout ini membawa regulatornya sendiri untuk menghasilkan rel tersebut daripada apa sahaja voltan yang masuk ke VIN, serta level-shifting pada SDA dan SCL supaya cip yang hanya menerima 1.8V itu boleh berkomunikasi dengan logik 5V atau 3.3V. Seni bina ini sama seperti yang didokumenkan oleh Adafruit dan SparkFun untuk board SGP30 mereka, dan sebab itulah VIN menerima apa sahaja dari 2V hingga 5V. Ini juga bermakna VIN menentukan aras logik: perintang pull-up SDA dan SCL berada di sebelah VIN pada level shifter (satu-satunya bekalan pada modul yang melebihi 1.8V), jadi pin I2C board anda akan menerima voltan yang sama seperti yang membekalkan VIN. Satu perangkap pada ESP32: guna 3V3, bukan pin berlabel VIN pada DevKit itu sendiri β€” pin itu membawa 5V daripada USB, yang akan meletakkan 5V pada pin ESP32 yang tidak tahan 5V (Adafruit mendokumenkan pull-up 10k yang sama ke Vin pada board SGP30-nya).

Library dan sketch mana yang memberi bacaan TVOC dan eCO2 pertama?

Driver Arduino yang standard untuk SGP30 ialah library Adafruit_SGP30: dalam IDE, buka Tools β†’ Manage Libraries, cari “Adafruit SGP30” dan install bersama helper Adafruit BusIO yang turut diminta. Sketch yang sama berjalan tanpa sebarang perubahan pada ESP32 β€” Wire secara lalai menggunakan GPIO21/22 di sana β€” cuma pilih board yang betul, dan upload ke ESP32 melalui kabel USB-C yang menyokong data.

#include <Wire.h>
#include "Adafruit_SGP30.h"

Adafruit_SGP30 sgp;
unsigned long lastBaselineReport = 0;

void setup() {
  Serial.begin(115200);
  while (!Serial) { delay(10); }

  if (!sgp.begin()) {
    Serial.println("SGP30 not found - check VIN, GND, SCL, SDA and the header joints");
    while (1) { delay(10); }
  }
  Serial.print("SGP30 found, serial #");
  Serial.print(sgp.serialnumber[0], HEX);
  Serial.print(sgp.serialnumber[1], HEX);
  Serial.println(sgp.serialnumber[2], HEX);

  // Ada baseline yang disimpan kurang seminggu lalu? Pulihkan di sini dengan
  // DUA nombor ANDA daripada baris BASELINE di bawah, dan langkau tempoh 12 jam:
  // sgp.setIAQBaseline(0x8E68, 0x8F41);
}

void loop() {
  if (!sgp.IAQmeasure()) {
    Serial.println("Measurement failed");
    delay(1000);
    return;
  }
  Serial.print("eCO2: ");
  Serial.print(sgp.eCO2);
  Serial.print(" ppm   TVOC: ");
  Serial.print(sgp.TVOC);
  Serial.println(" ppb");

  // Sekali seminit, cetak pasangan baseline supaya anda boleh mencatatnya
  if (millis() - lastBaselineReport > 60000UL) {
    lastBaselineReport = millis();
    uint16_t eco2_base, tvoc_base;
    if (sgp.getIAQBaseline(&eco2_base, &tvoc_base)) {
      Serial.print("BASELINE eCO2: 0x");
      Serial.print(eco2_base, HEX);
      Serial.print("   TVOC: 0x");
      Serial.println(tvoc_base, HEX);
    }
  }

  delay(1000);  // algoritma baseline mengharapkan satu bacaan setiap saat
}

Buka Serial Monitor pada 115200 baud. Baris nombor siri itu ialah bukti wiring anda betul β€” ia hanya dicetak jika Uno menemui sesuatu yang menjawab pada alamat I2C 0x58. Kemudian bacaan muncul, satu setiap saat: tepat 400 ppm dan 0 ppb, untuk kira-kira lima belas bacaan. Itu bukan kerosakan. Selepas arahan init, SGP30 mengambil masa 15 saat untuk memanaskan lapisannya dan menjadi stabil, dan menurut datasheet ia memang memulangkan nilai minimum tetap itu sehingga sedia. Selepas itu barulah nombornya hidup β€” hembus nafas ke arah sensor dan lihat kedua-duanya melonjak.

Kenapa nombornya berlegar sekitar 400 dan 0 β€” dan apa itu baseline?

Output SGP30 memang bersifat relatif mengikut reka bentuknya. Rintangan lapisan MOX berubah mengikut suhu, kelembapan dan usia, jadi bacaan rintangan mutlak tidak bermakna apa-apa dengan sendirinya. Sebaliknya, cip ini menjalankan algoritma pampasan baseline dinamik: ia sentiasa menjejak udara paling bersih yang pernah ditemuinya, menetapkannya sebagai rujukan β€” 400 ppm eCO2, 0 ppb TVOC, iaitu nilai paling rendah bagi setiap skala β€” dan melaporkan yang lain sebagai kenaikan di atas rujukan itu.

Rujukan itu ialah udara sebenar, bukan tekaan. Menurut FAQ sensor gas Sensirion, algoritma ini berpaut pada hidrogen yang sentiasa ada dalam udara luar yang bersih, iaitu latar belakang stabil sekitar setengah bahagian per sejuta (ppm), jadi sensor ini memerlukan kira-kira 10 minit udara yang benar-benar bersih setiap satu atau dua minggu. Bilik aircon tertutup yang tidak pernah dibuka tingkapnya tidak pernah memberi sensor peluang melihat rujukan itu: udara pengap yang biasa di bilik itu akan dipelajari sebagai bersih, dan bacaan seterusnya akan keluar terlalu rendah.

Rujukan itu juga sengaja bergerak perlahan, supaya satu jam yang berbau tidak boleh menjadi kebiasaan baharu; sebab itulah rujukan yang boleh dipercayai mengambil masa kira-kira 12 jam beroperasi dengan kuasa hidup. Buka tingkap selama sepuluh minit semasa larian pertama itu, dan anggap nombor mutlak hari pertama sebagai sementara. Sensor ini hanya mengukur apabila diminta, dan algoritmanya mengharapkan permintaan itu sekali setiap saat, jadi delay(1000) dalam sketch itu memainkan peranan penting.

Matikan kuasa dan rujukan yang sudah dipelajari itu hilang β€” melainkan anda menyimpannya. getIAQBaseline() membaca keadaan algoritma sebagai dua word 16-bit, dan sketch mencetak pasangan itu sekali seminit. Buka Serial Monitor sekali sahaja dan biarkan ia terbuka, dengan laptop tidak masuk mod tidur: membuka Serial Monitor akan memulakan semula Uno, restart itu menjalankan semula begin(), dan ini menetapkan semula baseline SGP30, jadi kiraan 12 jam bermula dari awal. Selepas 12 jam pertama, catat satu pasangan; mulai saat itu, buang tanda komen pada baris setIAQBaseline() dan isi dengan nombor anda sendiri, dan sensor akan bersambung dalam keadaan terkalibrasi, bukannya belajar semula dari kosong. Ada dua peraturan yang datang bersamanya, menurut panduan SGP30 Adafruit: kemas kini pasangan yang disimpan secara berkala (pemasangan kekal menyimpannya ke EEPROM atau flash setiap jam), dan anggap baseline yang disimpan sudah luput apabila sensor dimatikan lebih daripada kira-kira seminggu β€” tujuh hari ialah had maksimum yang dinyatakan β€” lalu biarkan ia belajar semula.

Kartun modul SGP30 biru gelap di bawah lengkung garis masa berwarna teal dari matahari ke bulan, dengan garis beralun yang semakin mendatar menunjukkan baseline sedang terbentuk
Setengah hari pertama ialah masa SGP30 mempelajari rujukannya: bacaan turun naik, kemudian stabil apabila baseline terbentuk.

Bagaimana nak elakkan kelembapan Malaysia daripada memesongkan bacaan?

Wap air turut terlibat dalam kimia permukaan yang sama pada lapisan panas SGP30 seperti gas, jadi kelembapan mengubah isyarat mentah sama seperti gas. Cip ini boleh membuat pampasan untuknya di dalam cip, tetapi hanya selepas anda menghantar nilai kelembapan: datasheet menyatakan bahawa setiap kali kuasa dihidupkan atau berlaku soft reset, pampasan kelembapan dimatikan sehingga satu nilai diterima. Udara dalam rumah di Malaysia pada 30Β°C dan 75% RH mengandungi kira-kira 23 g/mΒ³ β€” hampir dua kali ganda 11.8 g/mΒ³ dalam contoh pengiraan datasheet itu sendiri pada 25Β°C, 50% RH β€” dan nilainya berubah setiap kali hujan turun dan setiap kali aircon hidup dan mati. Tanpa pembetulan, perubahan itu tercetak sebagai perubahan kualiti udara yang palsu. Satu had tegas yang perlu diingat: datasheet menyatakan sensor ini tidak boleh sekali-kali terdedah kepada udara yang memeluwap (melebihi 90% RH), jadi jauhkan ia dari bilik air dan tempat lain yang mengalami pemeluwapan.

Penyelesaiannya ialah memberitahu sensor nilai yang sebenar. DHT22 membekalkan suhu dan kelembapan relatif; sketch menukarnya kepada kelembapan mutlak dan menghantar hasilnya ke setHumidity(), yang menerima nilai dalam miligram per meter padu. Mutlak, bukan relatif, kerana lapisan panas itu bertindak balas terhadap jumlah molekul air yang tiba, bukan terhadap sejauh mana bilik itu hampir tepu: 75% RH pada 30Β°C membawa kira-kira 50% lebih banyak air berbanding 75% RH pada 22Β°C.

Cucuk pin board DHT22 ke breadboard dan pindahkan satu-satunya sambungan 5V (Uno) atau 3V3 (ESP32) serta GND board anda ke rel breadboard supaya kedua-dua sensor berkongsi bekalan yang sama. Kemudian sambungkan + DHT22 ke rel bekalan, βˆ’ ke GND, dan out ke D2, atau GPIO4 pada ESP32. Elakkan GPIO2 pada ESP32: ia pin boot, dan talian data DHT22 kekal HIGH ketika tidak aktif, yang boleh menyekat upload. Install DHT sensor library daripada Adafruit melalui Library Manager yang sama (terima helper Adafruit Unified Sensor yang turut diminta), kemudian tambah tiga bahagian ini pada sketch di atas:

// 1) Di bahagian atas, di bawah #include "Adafruit_SGP30.h":
#include "DHT.h"
#define DHTPIN 2        // pin data DHT22 (ESP32: guna 4, bukan 2 atau pin input sahaja 34-39)
DHT dht(DHTPIN, DHT22);

// Kelembapan mutlak dalam mg/m3 daripada suhu (C) dan kelembapan relatif (%)
uint32_t absoluteHumidity(float t, float rh) {
  float ah = 216.7f * ((rh / 100.0f) * 6.112f *
             expf((17.62f * t) / (243.12f + t)) / (273.15f + t));  // g/m3
  return (uint32_t)(1000.0f * ah);                                 // mg/m3
}

// 2) Dalam setup(), sejurus selepas Serial.begin(115200):
//      dht.begin();

// 3) Dalam loop(), sebagai baris pertama, sebelum sgp.IAQmeasure():
float t = dht.readTemperature();
float rh = dht.readHumidity();
if (!isnan(t) && !isnan(rh)) {
  sgp.setHumidity(absoluteHumidity(t, rh));
}

DHT11 boleh melakukan kerja yang sama dengan bajet lebih jimat, tetapi langkah bacaan kelembapannya lebih kasar β€” kelebihan dan kekurangannya diterangkan dalam DHT11 vs DHT22.

Kartun sensor kelembapan DHT22 putih pada breakout board hitam menghantar anak panah teal ke modul SGP30 biru gelap, dengan titisan air teal pucat terapung di atas kedua-duanya
DHT22 memberikan nilai kelembapan secara langsung kepada SGP30, supaya kelembapan tropika tidak lagi tercetak sebagai perubahan kualiti udara yang palsu.

Kesilapan biasa yang kami lihat

Menganggap sensor rosak kerana bacaannya tepat 400 dan 0. Untuk 15 saat pertama, nilai itu ialah output init yang memang ditetapkan, dan selepas itu ia sekadar bacaan udara bersih β€” nilai paling rendah bagi setiap skala. Semakan kesihatan yang sebenar ialah tindak balasnya: hembus nafas ke sensor atau buka penutup marker berdekatan. Jika nombornya melonjak, tiada apa yang rosak.

Menyambung VIN ke VIN. Pin VIN pada DevKit ESP32 membawa kira-kira 5V daripada USB; sambung modul di situ dan SDA serta SCL akan ditarik ke 5V pada pin GPIO yang tidak tahan 5V. Ikut jadual, bukan label: 5V pada Uno, 3V3 pada ESP32.

Menggunakan eCO2 untuk menilai pengudaraan. Sesebuah bilik boleh menunjukkan bacaan eCO2 yang nampak selamat sedangkan CO2 sebenar sedang naik: SGP30 menyimpulkan nombornya daripada isyarat hidrogen dan VOC, bukan dengan mengukur CO2, dan dalam bilik yang tidak pernah dibuka tingkapnya, baseline-nya mempelajari udara pengap itu sebagai 400. Memantau trend kehadiran orang: ya. Mengesahkan pengudaraan bilik darjah: itu kerja sensor NDIR.

Menyambung OLED ikut kedudukan, bukan ikut label. Pada OLED 0.96 inci, pin header pertama ialah GND β€” bertentangan dengan banyak modul lain yang meletakkan VCC dahulu. Mencucuknya “sama macam sebelum ni” akan menukar kedudukan kuasa dan ground, dan ini boleh merosakkan paparan. OLED (0x3C) dan sensor ini (0x58) boleh berkongsi satu bas I2C tanpa masalah; wiring dan kod di bahagian paparan ada dalam panduan monitor DHT11 + OLED.

Kabel USB-C cas sahaja pada ESP32. Board itu hidup, lampunya berkelip, tetapi tidak pernah muncul sebagai port, kerana kabel itu secara fizikal memang tiada wayar data. Guna kabel yang dijual untuk data, dan jika port masih tidak muncul, ikut langkah dalam ESP32 tak dikesan.

Soalan Lazim

Adakah bacaan eCO2 SGP30 itu CO2 sebenar?

Tidak. SGP30 menganggarkan nilai setara CO2 daripada isyarat hidrogennya, berdasarkan fakta bahawa nafas dan aktiviti di dalam bangunan membebaskan hidrogen dan VOC lebih kurang seiring dengan CO2. Ia menjejak trend kehadiran orang dengan baik, tetapi tidak boleh mengesahkan pengudaraan atau keselamatan CO2 β€” itu memerlukan sensor NDIR seperti SCD30, yang mengukur molekul CO2 secara optik.

Berapa lama SGP30 ambil masa untuk memberi bacaan yang tepat?

Ada tiga skala masa: 15 saat output init tetap 400 ppm / 0 ppb, trend yang boleh digunakan dalam beberapa minit, dan kira-kira 12 jam beroperasi dengan kuasa hidup sebelum baseline di dalam cip menjadikan nombor mutlak itu bermakna. Simpan pasangan baseline selepas itu dan pulihkannya semasa permulaan β€” ia sah untuk kira-kira seminggu β€” dan sensor akan kembali dalam keadaan terkalibrasi, bukannya bermula semula. Beri ia kira-kira sepuluh minit udara segar setiap satu atau dua minggu supaya rujukan itu kekal jujur.

Bolehkah saya sambung dua sensor SGP30 pada satu Arduino?

Tidak pada bas yang sama: alamat I2C-nya tetap pada 0x58 tanpa jumper alamat, dan dua peranti yang berkongsi alamat akan bertembung. Jalankan sensor kedua melalui multiplexer I2C, atau pada bas I2C kedua ESP32 melalui Wire1, atau beri setiap sensor board-nya sendiri.

Bolehkah SGP30 mengesan jerebu, asap atau PM2.5?

Ia bertindak balas terhadap gas dalam asap, jadi asap boleh menaikkan bacaan TVOC-nya, tetapi ia tidak boleh mengukur jerebu atau PM2.5: jerebu dinilai berdasarkan zarah halus, dan sensor gas tidak boleh mengira zarah. Bacaan zarah memerlukan sensor PM2.5 optik seperti dalam binaan monitor jerebu kami; untuk projek penggera asap dan gas mudah terbakar, MQ-2 ialah pilihan biasa, sebagai binaan pembelajaran, dan tidak sekali-kali pengganti penggera asap yang diperakui. Bidang SGP30 ialah VOC: pelarut, semburan, bahan yang membebaskan gas (off-gassing), dan manusia.

Bolehkah SGP30 berjalan pada Arduino Uno 5V?

Modul GY-SGP30 boleh, kerana regulator pada board menurunkan VIN ke rel 1.62–1.98V cip Sensirion itu sendiri dan level-shifter-nya menterjemah SDA dan SCL. Bekalkan VIN apa sahaja dari 2V hingga 5V, dipadankan dengan voltan logik board anda kerana pull-up I2C modul ini dibekalkan daripada VIN: pin 5V Uno, atau pin 3V3 ESP32, dan jangan sesekali pin VIN 5V ESP32. Hanya cip SGP30 tanpa breakout yang benar-benar komponen 1.8V.

Kemas kini terakhir November 2026. Tersangkut? Chat dengan kami di WhatsApp.

Leave a Reply

Your email address will not be published. Required fields are marked *