first commit

This commit is contained in:
kicap
2026-01-30 12:35:40 +08:00
commit 5c8342d836
9 changed files with 960 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

37
include/README Normal file
View File

@ -0,0 +1,37 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the convention is to give header files names that end with `.h'.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into the executable file.
The source code of each library should be placed in a separate directory
("lib/your_library_name/[Code]").
For example, see the structure of the following example libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Example contents of `src/main.c` using Foo and Bar:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
The PlatformIO Library Dependency Finder will find automatically dependent
libraries by scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

20
platformio.ini Normal file
View File

@ -0,0 +1,20 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
lib_deps =
miguel5612/MQUnifiedsensor@^3.0.5
adafruit/Adafruit SSD1306@^2.5.16
adafruit/Adafruit GFX Library@^1.12.4
vshymanskyy/TinyGSM@^0.12.0
monitor_speed = 115200

421
src/main.cpp Normal file
View File

@ -0,0 +1,421 @@
#include <Arduino.h>
// =====================================================
// ESP32 + MQ-135 + MQ-7 + OLED SSD1306 (0.96" 128x64)
// Bahasa Indonesia | Stabil | Client-ready
// =====================================================
#define TINY_GSM_MODEM_SIM800
#define TINY_GSM_RX_BUFFER 650
#include <Wire.h>
#include <TinyGsmClient.h>
#include <MQUnifiedsensor.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// ================== SERIAL ==================
#define SerialMon Serial
// ================== SIM800L =================
#define MODEM_RX 16 // ESP32 GPIO16 ← SIM800L TX
#define MODEM_TX 17 // ESP32 GPIO17 → SIM800L RX (via resistor)
HardwareSerial SerialAT(2);
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
// APN Indonesia (change if needed)
const char apn[] = "internet";
const char user[] = "";
const char pass[] = "";
// Server
const char server[] = "k-dummy.my.id";
const int port = 8080;
// ================= OLED CONFIG =================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ================= MQ CONFIG ===================
#define BOARD "ESP-32"
#define VOLTAGE 3.3
#define ADC_BITS 12
#define PIN_MQ135 34
#define PIN_MQ7 35
#define RATIO_CLEAN_MQ135 3.6
#define RATIO_CLEAN_MQ7 27.5
MQUnifiedsensor MQ135(BOARD, VOLTAGE, ADC_BITS, PIN_MQ135, "MQ-135");
MQUnifiedsensor MQ7(BOARD, VOLTAGE, ADC_BITS, PIN_MQ7, "MQ-7");
// ================== HELPER ==================
void oledStatus(const String &msg)
{
display.clearDisplay();
display.setCursor(0, 0);
display.println("STATUS GSM:");
display.println(msg);
display.display();
}
// ================= HELPER ======================
float readAverage(MQUnifiedsensor &sensor, int samples = 5)
{
float sum = 0;
for (int i = 0; i < samples; i++)
{
sensor.update();
sum += sensor.readSensor();
delay(50);
}
return sum / samples;
}
// =====================================================
void setup()
{
Serial.begin(115200);
delay(500);
// ================= OLED INIT =================
Wire.begin(21, 22);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR))
{
Serial.println("❌ OLED tidak ditemukan!");
while (true)
delay(1000);
}
// SIM800L UART
SerialMon.println("[GSM] Init UART...");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("GSM INIT ...");
display.display();
SerialAT.begin(9600, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(3000);
SerialMon.println("[GSM] Restart modem...");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("GSM RESTART modem...");
display.display();
if (!modem.restart())
{
SerialMon.println("[ERROR] Modem restart failed!");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("GSM RESTART FAILED...");
display.display();
delay(1000);
while (1)
;
}
SerialMon.println("[GSM] Waiting for network...");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("GSM WAIT NETWORK...");
display.display();
delay(2000);
if (!modem.waitForNetwork())
{
SerialMon.println("[ERROR] No network!");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("GSM NO NETWORK...");
display.display();
delay(1000);
while (1)
;
}
SerialMon.println("[GSM] Network OK");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("GSM NETWORK OK...");
display.display();
delay(2000);
SerialMon.println("[GSM] Connecting GPRS...");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("GSM CONNECTING GPRS...");
display.display();
delay(2000);
if (!modem.gprsConnect(apn, user, pass))
{
SerialMon.println("[ERROR] GPRS failed!");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("");
display.display();
delay(1000);
while (1)
;
}
SerialMon.println("[GSM] GPRS CONNECTED");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("GSM GPRS CONNECTED...");
display.display();
delay(2000);
// MQ init
SerialMon.println("[MQ] Init MQ135 & MQ7");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Monitoring Udara");
display.println("ESP32 + MQ");
display.println("Kalibrasi...");
display.display();
delay(2000);
// ================= KALIBRASI =================
Serial.println("Mulai kalibrasi sensor...");
Serial.println("Pastikan udara bersih (±1-2 menit)");
// MQ135
MQ135.setRegressionMethod(1);
MQ135.init();
float r0_135 = 0;
for (int i = 0; i < 10; i++)
{
MQ135.update();
r0_135 += MQ135.calibrate(RATIO_CLEAN_MQ135);
delay(600);
}
r0_135 /= 10;
MQ135.setR0(r0_135);
// MQ7
MQ7.setRegressionMethod(1);
MQ7.init();
float r0_7 = 0;
for (int i = 0; i < 10; i++)
{
MQ7.update();
r0_7 += MQ7.calibrate(RATIO_CLEAN_MQ7);
delay(600);
}
r0_7 /= 10;
MQ7.setR0(r0_7);
if (r0_135 <= 0 || r0_7 <= 0)
{
Serial.println("❌ Kalibrasi gagal!");
display.clearDisplay();
display.setCursor(0, 0);
display.println("ERROR KALIBRASI");
display.display();
while (true)
delay(1000);
}
Serial.println("Kalibrasi selesai!");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Kalibrasi OK");
display.println("Mulai Monitor");
display.display();
delay(2000);
}
// =====================================================
void loop()
{
// =============== MQ135 =================
MQ135.setA(110.47);
MQ135.setB(-2.862);
float co2 = readAverage(MQ135);
if (co2 < 0)
co2 = 0;
MQ135.setA(605.18);
MQ135.setB(-3.937);
float benzene = readAverage(MQ135);
if (benzene < 0)
benzene = 0;
// =============== MQ7 ===================
MQ7.setA(99.042);
MQ7.setB(-1.518);
float co = readAverage(MQ7);
if (co < 0)
co = 0;
// ========== AIR QUALITY ESTIMATION =====
int aq = 100;
if (co2 > 700)
aq -= map(co2, 700, 2000, 0, 50);
if (co2 > 2000)
aq -= map(co2, 2000, 5000, 50, 80);
if (co > 10)
aq -= map(co, 10, 50, 0, 30);
if (co > 50)
aq -= 30;
if (benzene > 5)
aq -= map(benzene, 5, 50, 0, 40);
aq = constrain(aq, 0, 100);
String status;
if (aq >= 90)
status = "Sangat Baik";
else if (aq >= 70)
status = "Baik";
else if (aq >= 50)
status = "Sedang";
else if (aq >= 30)
status = "Buruk";
else
status = "Sangat Buruk";
// =============== OLED DISPLAY ==========
display.clearDisplay();
display.setCursor(0, 0);
display.print("CO2: ");
display.print(co2, 0);
display.println(" ppm");
display.print("CO : ");
display.print(co, 1);
display.println(" ppm");
display.print("BZ : ");
display.print(benzene, 1);
display.println(" ppm");
display.print("AQ : ");
display.print(aq);
display.print("% ");
display.println(status);
display.display();
// =============== SERIAL =================
Serial.println("===== STATUS UDARA =====");
Serial.print("CO2 : ");
Serial.print(co2);
Serial.println(" ppm");
Serial.print("CO : ");
Serial.print(co);
Serial.println(" ppm");
Serial.print("BZ : ");
Serial.print(benzene);
Serial.println(" ppm");
Serial.print("AQ : ");
Serial.print(aq);
Serial.print("% ");
Serial.println(status);
Serial.println("========================\n");
delay(5000);
if (client.connect(server, port))
{
String url = "/api/update?";
url += "co2=" + String(co2);
url += "&co=" + String(co);
url += "&bz=" + String(benzene);
url += "&aq=" + String(aq);
SerialMon.print("[HTTP] GET ");
SerialMon.println(url);
// Send request
client.print(String("GET ") + url + " HTTP/1.1\r\n");
client.print("Host: k-dummy.my.id\r\n");
client.print("Connection: close\r\n\r\n");
oledStatus("MENUNGGU RESP");
// -------------------------------
// READ RESPONSE
// -------------------------------
String response = "";
unsigned long timeout = millis();
while (client.connected() && millis() - timeout < 8000)
{
while (client.available())
{
char c = client.read();
response += c;
timeout = millis(); // reset timeout when data arrives
}
}
client.stop();
SerialMon.println("----- HTTP RESPONSE -----");
SerialMon.println(response);
SerialMon.println("-------------------------");
// -------------------------------
// EXTRACT JSON BODY
// -------------------------------
int jsonStart = response.indexOf('{');
if (jsonStart >= 0)
{
String json = response.substring(jsonStart);
SerialMon.print("[JSON] ");
SerialMon.println(json);
oledStatus("RESP OK");
}
else
{
SerialMon.println("[ERROR] No JSON found!");
oledStatus("RESP ERROR");
}
}
else
{
SerialMon.println("[ERROR] Server connection failed!");
oledStatus("GAGAL KIRIM");
}
client.stop();
SerialMon.println("===== LOOP END =====");
delay(10000);
}

182
src/main.cpp.bck-no-edit Normal file
View File

@ -0,0 +1,182 @@
#include <Arduino.h>
// =====================================================
// ESP32 + MQ-135 + MQ-7 + OLED SSD1306 (0.96" 128x64)
// Bahasa Indonesia | Stabil | Client-ready
// =====================================================
#include <Wire.h>
#include <MQUnifiedsensor.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// ================= OLED CONFIG =================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ================= MQ CONFIG ===================
#define BOARD "ESP-32"
#define VOLTAGE 3.3
#define ADC_BITS 12
#define PIN_MQ135 34
#define PIN_MQ7 35
#define RATIO_CLEAN_MQ135 3.6
#define RATIO_CLEAN_MQ7 27.5
MQUnifiedsensor MQ135(BOARD, VOLTAGE, ADC_BITS, PIN_MQ135, "MQ-135");
MQUnifiedsensor MQ7(BOARD, VOLTAGE, ADC_BITS, PIN_MQ7, "MQ-7");
// ================= HELPER ======================
float readAverage(MQUnifiedsensor &sensor, int samples = 5) {
float sum = 0;
for (int i = 0; i < samples; i++) {
sensor.update();
sum += sensor.readSensor();
delay(50);
}
return sum / samples;
}
// =====================================================
void setup() {
Serial.begin(115200);
delay(500);
// ================= OLED INIT =================
Wire.begin(21, 22);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("❌ OLED tidak ditemukan!");
while (true) delay(1000);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Monitoring Udara");
display.println("ESP32 + MQ");
display.println("Kalibrasi...");
display.display();
// ================= KALIBRASI =================
Serial.println("Mulai kalibrasi sensor...");
Serial.println("Pastikan udara bersih (±1-2 menit)");
// MQ135
MQ135.setRegressionMethod(1);
MQ135.init();
float r0_135 = 0;
for (int i = 0; i < 10; i++) {
MQ135.update();
r0_135 += MQ135.calibrate(RATIO_CLEAN_MQ135);
delay(600);
}
r0_135 /= 10;
MQ135.setR0(r0_135);
// MQ7
MQ7.setRegressionMethod(1);
MQ7.init();
float r0_7 = 0;
for (int i = 0; i < 10; i++) {
MQ7.update();
r0_7 += MQ7.calibrate(RATIO_CLEAN_MQ7);
delay(600);
}
r0_7 /= 10;
MQ7.setR0(r0_7);
if (r0_135 <= 0 || r0_7 <= 0) {
Serial.println("❌ Kalibrasi gagal!");
display.clearDisplay();
display.setCursor(0, 0);
display.println("ERROR KALIBRASI");
display.display();
while (true) delay(1000);
}
Serial.println("Kalibrasi selesai!");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Kalibrasi OK");
display.println("Mulai Monitor");
display.display();
delay(2000);
}
// =====================================================
void loop() {
// =============== MQ135 =================
MQ135.setA(110.47); MQ135.setB(-2.862);
float co2 = readAverage(MQ135);
if (co2 < 0) co2 = 0;
MQ135.setA(605.18); MQ135.setB(-3.937);
float benzene = readAverage(MQ135);
if (benzene < 0) benzene = 0;
// =============== MQ7 ===================
MQ7.setA(99.042); MQ7.setB(-1.518);
float co = readAverage(MQ7);
if (co < 0) co = 0;
// ========== AIR QUALITY ESTIMATION =====
int aq = 100;
if (co2 > 700) aq -= map(co2, 700, 2000, 0, 50);
if (co2 > 2000) aq -= map(co2, 2000, 5000, 50, 80);
if (co > 10) aq -= map(co, 10, 50, 0, 30);
if (co > 50) aq -= 30;
if (benzene > 5) aq -= map(benzene, 5, 50, 0, 40);
aq = constrain(aq, 0, 100);
String status;
if (aq >= 90) status = "Sangat Baik";
else if (aq >= 70) status = "Baik";
else if (aq >= 50) status = "Sedang";
else if (aq >= 30) status = "Buruk";
else status = "Sangat Buruk";
// =============== OLED DISPLAY ==========
display.clearDisplay();
display.setCursor(0, 0);
display.print("CO2: ");
display.print(co2, 0);
display.println(" ppm");
display.print("CO : ");
display.print(co, 1);
display.println(" ppm");
display.print("BZ : ");
display.print(benzene, 1);
display.println(" ppm");
display.print("AQ : ");
display.print(aq);
display.print("% ");
display.println(status);
display.display();
// =============== SERIAL =================
Serial.println("===== STATUS UDARA =====");
Serial.print("CO2 : "); Serial.print(co2); Serial.println(" ppm");
Serial.print("CO : "); Serial.print(co); Serial.println(" ppm");
Serial.print("BZ : "); Serial.print(benzene); Serial.println(" ppm");
Serial.print("AQ : "); Serial.print(aq); Serial.print("% "); Serial.println(status);
Serial.println("========================\n");
delay(5000);
}

228
src/main.cpp.gprs-ok Normal file
View File

@ -0,0 +1,228 @@
/*********************************************************
* ESP32 + MQ135 + MQ7 + OLED SSD1306 + SIM800L
* GSM HTTP GET → http://k-dummy.my.id:8080/
* Bahasa Indonesia | Client-ready
*********************************************************/
// ================== TINYGSM (MUST BE FIRST) ==================
#define TINY_GSM_MODEM_SIM800
#define TINY_GSM_RX_BUFFER 650
#include <Arduino.h>
#include <Wire.h>
#include <TinyGsmClient.h>
#include <MQUnifiedsensor.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// ================== SERIAL ==================
#define SerialMon Serial
// ================== SIM800L =================
#define MODEM_RX 16 // ESP32 GPIO16 ← SIM800L TX
#define MODEM_TX 17 // ESP32 GPIO17 → SIM800L RX (via resistor)
HardwareSerial SerialAT(2);
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
// APN Indonesia (change if needed)
const char apn[] = "internet";
const char user[] = "";
const char pass[] = "";
// Server
const char server[] = "k-dummy.my.id";
const int port = 8080;
// ================== OLED ====================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// ================== MQ SENSOR ===============
#define BOARD "ESP-32"
#define VOLTAGE 3.3
#define ADC_BITS 12
#define PIN_MQ135 34
#define PIN_MQ7 35
#define RATIO_CLEAN_MQ135 3.6
#define RATIO_CLEAN_MQ7 27.5
MQUnifiedsensor MQ135(BOARD, VOLTAGE, ADC_BITS, PIN_MQ135, "MQ-135");
MQUnifiedsensor MQ7(BOARD, VOLTAGE, ADC_BITS, PIN_MQ7, "MQ-7");
// ================== HELPER ==================
void oledStatus(const String &msg)
{
display.clearDisplay();
display.setCursor(0, 0);
display.println("STATUS GSM:");
display.println(msg);
display.display();
}
float readAverage(MQUnifiedsensor &s)
{
float sum = 0;
for (int i = 0; i < 5; i++)
{
s.update();
sum += s.readSensor();
delay(50);
}
return sum / 5;
}
void logSerial(const String &msg)
{
SerialMon.println(msg);
}
// =============================================================
void setup()
{
SerialMon.begin(115200);
delay(1000);
SerialMon.println("=================================");
SerialMon.println(" ESP32 + MQ + SIM800L START ");
SerialMon.println("=================================");
// OLED
Wire.begin(21, 22);
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
oledStatus("Init GSM...");
logSerial("[OLED] Init GSM...");
// SIM800L UART
SerialMon.println("[GSM] Init UART...");
SerialAT.begin(9600, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(3000);
SerialMon.println("[GSM] Restart modem...");
if (!modem.restart())
{
SerialMon.println("[ERROR] Modem restart failed!");
oledStatus("MODEM FAIL");
while (1);
}
SerialMon.println("[GSM] Waiting for network...");
oledStatus("Cari jaringan...");
if (!modem.waitForNetwork())
{
SerialMon.println("[ERROR] No network!");
oledStatus("NO SIGNAL");
while (1);
}
SerialMon.println("[GSM] Network OK");
SerialMon.println("[GSM] Connecting GPRS...");
oledStatus("GPRS connect...");
if (!modem.gprsConnect(apn, user, pass))
{
SerialMon.println("[ERROR] GPRS failed!");
oledStatus("GPRS FAIL");
while (1);
}
SerialMon.println("[GSM] GPRS CONNECTED");
oledStatus("GSM READY");
delay(1500);
// MQ init
SerialMon.println("[MQ] Init MQ135 & MQ7");
MQ135.setRegressionMethod(1);
MQ135.init();
MQ135.setR0(10);
MQ7.setRegressionMethod(1);
MQ7.init();
MQ7.setR0(10);
SerialMon.println("[SYSTEM] Setup complete!");
}
// =============================================================
void loop()
{
SerialMon.println("\n===== LOOP START =====");
// MQ135 → CO2
MQ135.setA(110.47);
MQ135.setB(-2.862);
float co2 = readAverage(MQ135);
if (co2 < 0) co2 = 0;
// MQ135 → Benzene
MQ135.setA(605.18);
MQ135.setB(-3.937);
float bz = readAverage(MQ135);
if (bz < 0) bz = 0;
// MQ7 → CO
MQ7.setA(99.042);
MQ7.setB(-1.518);
float co = readAverage(MQ7);
if (co < 0) co = 0;
int aq = constrain(100 - (co2 / 50) - (co * 2) - (bz * 3), 0, 100);
// ===== SERIAL SENSOR LOG =====
SerialMon.println("[SENSOR]");
SerialMon.print("CO2 : "); SerialMon.print(co2); SerialMon.println(" ppm");
SerialMon.print("CO : "); SerialMon.print(co); SerialMon.println(" ppm");
SerialMon.print("BZ : "); SerialMon.print(bz); SerialMon.println(" ppm");
SerialMon.print("AQ : "); SerialMon.print(aq); SerialMon.println(" %");
// OLED
display.clearDisplay();
display.setCursor(0, 0);
display.printf("CO2: %.0f ppm\n", co2);
display.printf("CO : %.1f ppm\n", co);
display.printf("BZ : %.1f ppm\n", bz);
display.printf("AQ : %d%%\n", aq);
display.display();
// ===== SEND TO SERVER =====
SerialMon.println("[HTTP] Sending data...");
oledStatus("Kirim data...");
if (client.connect(server, port))
{
String url = "/api/update?";
url += "CO2=" + String(co2);
url += "&CO=" + String(co);
url += "&BZ=" + String(bz);
url += "&AQ=" + String(aq);
SerialMon.print("[HTTP] GET ");
SerialMon.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n");
client.print("Host: k-dummy.my.id\r\n");
client.print("Connection: close\r\n\r\n");
SerialMon.println("[HTTP] Data sent!");
oledStatus("TERKIRIM");
}
else
{
SerialMon.println("[ERROR] Server connection failed!");
oledStatus("GAGAL KIRIM");
}
client.stop();
SerialMon.println("===== LOOP END =====");
delay(15000);
}

11
test/README Normal file
View File

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html