Published on

Sensor Modular

Authors

πŸ§ͺ Modul 6 – Sensor Modular



Baik. Langsung teknis, ringkas, tidak berbelit.


🧭 Prolog Modul: Posisi dan Peran Modul 6

Modul 6 memperkenalkan sensor sebagai sumber data input dalam arsitektur firmware IoT modular. Setelah Modul 5 memastikan firmware mampu menangani event asinkron (interrupt) secara aman dan non-blocking, modul ini memperluas sistem dengan kemampuan membaca data lingkungan secara periodik dan terstruktur.

Pada titik ini, firmware tidak lagi hanya merespons event eksternal, tetapi juga secara aktif mengumpulkan data dari sensor. Sensor diperlakukan sebagai komponen OOP penuh, setara dengan LED dan tombol, dan wajib mengikuti kontrak ComponentBase (begin() dan update()).

Fokus Modul 6 adalah memastikan bahwa pembacaan sensor:

  • terenkapsulasi dalam class,
  • tidak mengganggu komponen lain,
  • dan dapat diintegrasikan tanpa menambah kompleksitas di firmware.ino.

Modul ini menjadi fondasi teknis bagi modul-modul berikutnya, karena seluruh automasi dan komunikasi IoT akan bergantung langsung pada data sensor yang dikelola dengan benar.


🧠 Konteks Pengetahuan: Relasi Antar Modul

πŸ”™ Prasyarat Konseptual

Modul 6 bergantung langsung pada fondasi yang sudah dibangun sebelumnya:

  • Modul 4 – ComponentBase Wajib memahami:

    • kontrak begin() dan update()
    • pengelolaan komponen melalui base class
    • pemisahan lifecycle komponen dari firmware.ino
  • Modul 5 – Interrupt dan Tombol Wajib memahami:

    • konsep event dan state
    • firmware non-blocking
    • pemrosesan terpisah antara trigger dan aksi
  • Modul 3 – Object dari JSON Digunakan untuk:

    • konfigurasi sensor secara runtime
    • pemisahan parameter sensor dari implementasi class

Tanpa pemahaman ini, sensor modular tidak dapat diintegrasikan secara konsisten.


πŸ”œ Digunakan Kembali di Modul Selanjutnya

Class sensor yang dibangun pada Modul 6 akan digunakan langsung pada:

  • Modul 7 – Actuator Modular Sensor menjadi sumber data pengambilan keputusan.

  • Modul 8 – MQTT Integration Data sensor menjadi payload komunikasi.

  • Modul 9 – Final Project Sensor berperan sebagai input utama sistem IoT.

Dengan kata lain, desain sensor di modul ini mengikat perilaku sistem ke depan.


🎯 Tujuan Modul (Learning Objectives)

Setelah menyelesaikan Modul 6, pembaca harus mampu secara praktis:

  • Menempatkan sensor sebagai komponen input dalam sistem IoT
  • Mendesain class sensor berbasis OOP yang terenkapsulasi
  • Melakukan pembacaan sensor secara periodik tanpa delay()
  • Menyimpan data sensor sebagai state internal yang konsisten
  • Mengekspos data sensor melalui antarmuka class yang jelas
  • Mengintegrasikan sensor ke sistem berbasis ComponentBase

Jika sensor masih dibaca langsung di loop(), modul dianggap gagal.


🧩 Masalah yang Diselesaikan Modul Ini

Masalah umum pada pembacaan sensor di firmware konvensional:

  • Logika pembacaan tersebar di loop()
  • Penggunaan delay() menghambat komponen lain
  • Penambahan sensor memaksa perubahan struktur kode
  • Tidak ada standar penyimpanan dan akses data sensor

Dampak langsung:

  • Firmware sulit diskalakan
  • Sulit diuji
  • Sulit diintegrasikan dengan sistem yang lebih besar

Modul 6 menyelesaikan masalah ini dengan:

  • Mengenkapsulasi seluruh logika sensor dalam class khusus
  • Menggunakan mekanisme waktu non-blocking
  • Menyatukan sensor ke arsitektur modular berbasis komponen

πŸ—οΈ Konsep Inti yang Diperkenalkan

Konsep Utama

Modul ini memperkenalkan pola teknis berikut:

  • Sensor sebagai komponen OOP Sensor diperlakukan sebagai unit logika mandiri.

  • Pembacaan sensor periodik Menggunakan waktu (millis()), bukan delay().

  • Manajemen state dan data sensor Data disimpan sebagai cache internal class.

  • Pemisahan pembacaan dan konsumsi data Sensor membaca data, komponen lain mengonsumsi data.

  • Integrasi dengan ComponentBase Sensor tunduk pada lifecycle sistem.


Konsep yang Tidak Dibahas di Modul Ini

Secara eksplisit di luar scope Modul 6:

  • Kalibrasi sensor lanjutan
  • Filtering dan smoothing data
  • Interrupt berbasis sensor
  • MQTT dan komunikasi jaringan

Fokus modul ini murni pada struktur dan pola sensor modular.


πŸ› οΈ Desain Teknis & Arsitektur

Pada level arsitektur, sensor diperlakukan sebagai:

  • Komponen pasif yang menghasilkan data
  • Memiliki lifecycle standar (begin(), update())
  • Menyimpan hasil pembacaan sebagai state internal

Tanggung jawab class sensor:

  • Menentukan interval pembacaan
  • Mengakses hardware sensor
  • Memperbarui cache data internal
  • Menyediakan method akses data (getter)

Peran firmware.ino:

  • Tidak membaca sensor
  • Tidak mengatur timing sensor
  • Hanya mengelola lifecycle komponen

Dengan desain ini, sensor dapat ditambah, diganti, atau dikonfigurasi ulang tanpa mengubah struktur firmware utama.


πŸ§ͺ Implementasi Bertahap (High-Level)

0️⃣ Struktur Folder (WAJIB seperti ini)

firmware/
β”œβ”€β”€ ComponentBase.h
β”œβ”€β”€ LedController.h
β”œβ”€β”€ LedController.cpp
β”œβ”€β”€ DhtSensor.h
β”œβ”€β”€ DhtSensor.cpp
└── firmware.ino

ComponentBase dan LedController dipakai ulang dari Modul 4–5 Tidak ada refactor ke modul sebelumnya.


1️⃣ Menentukan Tanggung Jawab Class Sensor

Class sensor HANYA bertanggung jawab atas:

  • Inisialisasi hardware sensor
  • Penjadwalan pembacaan periodik
  • Pembacaan data dari sensor
  • Penyimpanan data terakhir (cache)
  • Penyediaan data via getter

Class sensor TIDAK:

  • Mengontrol actuator
  • Menulis ke Serial (kecuali debug opsional)
  • Mengatur logic aplikasi
  • Menggunakan delay()

2️⃣ Mendesain Class Sensor Turunan dari ComponentBase

DhtSensor.h

#ifndef DHT_SENSOR_H
#define DHT_SENSOR_H

#include <Arduino.h>
#include "ComponentBase.h"
#include <DHT.h>

class DhtSensor : public ComponentBase {
  public:
    DhtSensor(uint8_t pin, uint8_t type, uint32_t intervalMs);

    void begin() override;
    void update() override;

    // Public API (getter)
    float getTemperature() const;
    float getHumidity() const;
    bool isValid() const;

  private:
    uint8_t _pin;
    uint8_t _type;
    uint32_t _intervalMs;

    DHT _dht;

    // Timing
    uint32_t _lastReadMs = 0;

    // Cached data
    float _temperature = NAN;
    float _humidity = NAN;
    bool _valid = false;

    void readSensor();
};

#endif

3️⃣ Menentukan Interval Pembacaan Non-Blocking

  • Menggunakan millis()
  • Tidak ada delay()
  • Interval disimpan sebagai parameter constructor
  • Sensor tidak dibaca setiap loop

Interval dicek di update().


4️⃣ Membaca Data Sensor (DHT)

DhtSensor.cpp

#include "DhtSensor.h"

DhtSensor::DhtSensor(uint8_t pin, uint8_t type, uint32_t intervalMs)
: _pin(pin),
  _type(type),
  _intervalMs(intervalMs),
  _dht(pin, type) {}

void DhtSensor::begin() {
  _dht.begin();
  _lastReadMs = 0;
}

void DhtSensor::update() {
  uint32_t now = millis();
  if (now - _lastReadMs >= _intervalMs) {
    _lastReadMs = now;
    readSensor();
  }
}

void DhtSensor::readSensor() {
  float h = _dht.readHumidity();
  float t = _dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    _valid = false;
    return;
  }

  _humidity = h;
  _temperature = t;
  _valid = true;
}

5️⃣ Menyimpan Hasil Pembacaan dalam State Internal

State yang disimpan:

float _temperature;
float _humidity;
bool  _valid;

Aturan:

  • Data hanya ditulis oleh sensor
  • Data dibaca oleh pihak lain
  • Tidak ada race condition (single-thread loop)

6️⃣ Mengekspos Data Sensor melalui Method Publik

Getter WAJIB const:

float DhtSensor::getTemperature() const {
  return _temperature;
}

float DhtSensor::getHumidity() const {
  return _humidity;
}

bool DhtSensor::isValid() const {
  return _valid;
}

Tidak ada setter. Sensor adalah source of truth.


7️⃣ Integrasi ke firmware.ino

firmware.ino (FINAL – UTUH)

#include <Arduino.h>
#include "ComponentBase.h"
#include "LedController.h"
#include "DhtSensor.h"

// ===== Konfigurasi =====
#define LED_PIN   2
#define DHT_PIN   4
#define DHT_TYPE  DHT22

// ===== Komponen =====
LedController led(LED_PIN, false);
DhtSensor dht(DHT_PIN, DHT_TYPE, 2000); // baca tiap 2 detik

ComponentBase* components[] = {
  &led,
  &dht
};

const size_t COMPONENT_COUNT =
  sizeof(components) / sizeof(components[0]);

void setup() {
  Serial.begin(115200);
  delay(200);

  for (size_t i = 0; i < COMPONENT_COUNT; i++) {
    components[i]->begin();
  }

  Serial.println("Modul 6: Sensor Modular (DHT)");
}

void loop() {
  for (size_t i = 0; i < COMPONENT_COUNT; i++) {
    components[i]->update();
  }

  // Konsumsi data sensor (contoh observasi)
  if (dht.isValid()) {
    Serial.print("Temp: ");
    Serial.print(dht.getTemperature());
    Serial.print(" C | Hum: ");
    Serial.print(dht.getHumidity());
    Serial.println(" %");
  }
}

βœ… Checklist Validasi (WAJIB LULUS)

Checklist ini digunakan sebagai kriteria kelulusan teknis Modul 6. Jika satu poin gagal, implementasi tidak dianggap benar secara arsitektural.

  1. Sensor terbaca periodik

    • Output Serial Monitor muncul setiap Β± interval yang ditentukan (mis. 2000 ms)
    • Interval dikendalikan oleh logika waktu (millis()), bukan delay()
  2. Firmware tetap responsif

    • Tidak ada pemanggilan delay() di class sensor
    • Komponen lain (LED, tombol) tetap berfungsi normal saat sensor aktif
  3. firmware.ino bersih

    • Tidak ada pemanggilan API sensor (readTemperature(), readHumidity(), dsb.)
    • Tidak ada logika pembacaan atau timing sensor
  4. Sensor modular

    • Mengganti:

      • DHT β†’ PIR β†’ sensor analog
    • Tidak memerlukan perubahan:

      • firmware.ino
      • struktur ComponentBase
      • loop utama firmware
  5. ComponentBase tetap utuh

    • Sensor diperlakukan sama seperti komponen lain
    • Sensor diinisialisasi via begin()
    • Sensor dijalankan via update()

Catatan keras (WAJIB DIPATUHI)

Setelah Modul 6:

  • Tidak boleh membaca sensor di loop()
  • Tidak boleh menggunakan delay() untuk pembacaan sensor
  • Sensor bukan logic
  • Sensor hanya data source

Pelanggaran terhadap poin ini berarti arsitektur rusak.


🧾 Validasi dan Pengujian

Modul 6 dinyatakan lulus apabila seluruh kondisi berikut terpenuhi:

  • Data sensor terbaca secara periodik dan konsisten

  • Firmware tetap responsif terhadap:

    • interrupt tombol
    • komponen lain
  • Tidak ada blocking behavior akibat pembacaan sensor

  • Serial Monitor menampilkan data yang stabil (tidak acak karena race)

  • Penambahan atau penggantian sensor:

    • tidak mengubah komponen lain
    • tidak mengubah struktur firmware

Validasi ini memastikan sensor telah terintegrasi sebagai komponen sistem, bukan sebagai potongan kode ad-hoc.


πŸ” Refleksi dan Keterkaitan ke Modul Lain

Kondisi firmware setelah Modul 6:

  • Sistem memiliki sumber data lingkungan
  • Sensor berjalan periodik dan non-blocking
  • Data sensor tersedia untuk dikonsumsi komponen lain

Batasan saat ini:

  • Data sensor belum memicu aksi

Keterbatasan ini disengaja dan akan diselesaikan pada:

πŸ‘‰ Modul 7 – Actuator Modular

Di modul tersebut:

  • Data sensor dan event akan digunakan untuk mengendalikan aksi nyata
  • Logika keputusan mulai diperkenalkan
  • Sensor β†’ Actuator β†’ Sistem

🧭 Navigasi Modul

  • ⬅️ Modul sebelumnya – Modul 5: Interrupt dan Tombol Event asinkron dan input real-time.

  • ➑️ Modul selanjutnya – Modul 7: Actuator Modular Aksi berbasis data sensor dan event.


πŸ“Œ Penutup Analitis

Modul 6 mengubah firmware dari sistem yang reaktif menjadi sistem yang observasional. Dengan sensor modular, firmware mulai memahami kondisi lingkunganβ€”sebuah prasyarat mutlak untuk membangun sistem IoT yang cerdas dan adaptif.


Catatan Penyusunan Artikel ini disusun sebagai materi edukasi dan referensi umum berdasarkan berbagai sumber pustaka, praktik lapangan, serta bantuan alat penulisan. Pembaca disarankan untuk melakukan verifikasi lanjutan dan penyesuaian sesuai dengan kondisi serta kebutuhan masing-masing sistem.