wahyu-widodo-dev/ntc10k

1.0.0

Latest
uploaded 2 hours ago
Driver pembaca termistor NTC 10K dengan model Beta atau Steinhart-Hart, filter sampel, dan deteksi gangguan untuk ESP-IDF.

Readme

# Komponen NTC10K

Driver pembaca termistor NTC melalui komponen `adc_manager` dan ADC oneshot
ESP-IDF 5.3.0 atau lebih baru. Aplikasi membuat ADC manager satu kali dan dapat
memakainya bersama beberapa sensor NTC maupun sensor analog lain. Komponen ini
membaca satu kumpulan sampel, menyaring noise, menghitung tegangan node dan
resistansi NTC, lalu menghasilkan suhu dalam Celsius, Fahrenheit, dan Kelvin.
Driver mendukung model Beta dan Steinhart-Hart serta mendeteksi rangkaian
open/short dan suhu di luar rentang yang dikonfigurasi.

> **Penting:** NTC 10 kOhm hanya menjelaskan resistansi nominal, bukan kurva
> suhu lengkap. Nilai Beta dan koefisien Steinhart-Hart berbeda antar tipe
> termistor. Gunakan parameter datasheet atau hasil kalibrasi NTC yang tepat
> untuk memperoleh akurasi yang diharapkan.

## Fitur

- Menggunakan `adc_manager` untuk berbagi satu ADC Unit dengan sensor analog
  lain tanpa membuat ADC oneshot terpisah.
- Kalibrasi tegangan memakai `adc_cali_handle_t` yang disediakan aplikasi,
  atau estimasi nominal jika handle kalibrasi tidak disediakan.
- Model suhu Beta atau Steinhart-Hart dengan parameter yang dapat dikonfigurasi.
- Filter mean, median, atau trimmed mean untuk 1 sampai 64 sampel.
- Dukungan pembagi dengan NTC di sisi ground maupun sisi supply.
- Pembacaan snapshot berisi raw ADC, rentang sampel, tegangan, resistansi,
  suhu C/F/K, status kalibrasi, dan kode gangguan.
- Validasi konfigurasi, serialisasi pembacaan per handle, dan error ADC
  diteruskan ke aplikasi.

## Rangkaian pembagi tegangan

Gunakan resistor tetap yang diketahui presisinya dan sambungkan node tengah ke
channel ADC. Jangan biarkan tegangan pada pin ADC melampaui batas SoC.

### NTC ke ground (`NTC10K_TO_GROUND`)

```text
V_SUPPLY
   |
R_SERI
   |
   +------ ADC
   |
 NTC 10K
   |
  GND
```

Resistansi dihitung sebagai `R_NTC = R_SERI × V_ADC / (V_SUPPLY - V_ADC)`.

### NTC ke supply (`NTC10K_TO_SUPPLY`)

```text
V_SUPPLY
   |
 NTC 10K
   |
   +------ ADC
   |
R_SERI
   |
  GND
```

Resistansi dihitung sebagai `R_NTC = R_SERI × (V_SUPPLY - V_ADC) / V_ADC`.
Nilai `divider_supply_voltage_v` harus merupakan tegangan supply pembagi yang
sebenarnya, bukan tegangan maksimum ADC.

## ADC Unit, channel, dan GPIO

Tiga istilah ini menunjuk bagian yang berbeda:

- **ADC Unit** adalah perangkat ADC di dalam chip, misalnya `ADC_UNIT_1`.
  Buat sekali melalui `adc_manager_create()`.
- **GPIO** adalah nomor pin fisik yang disambungkan ke keluaran sensor, misalnya
  `GPIO_NUM_1`.
- **ADC channel** adalah jalur internal ADC yang terhubung ke suatu GPIO.
  Pemetaan GPIO ke channel berbeda antar model chip.

Pilih **ADC Unit sekali** saat membuat manager. Untuk setiap NTC, konfigurasi
hanya meminta **GPIO**. Manager memetakan GPIO ke channel dan memeriksa bahwa
GPIO tersebut memang berada pada Unit yang dikelolanya. Tidak perlu
menuliskan `ADC_UNIT_1` lagi di konfigurasi sensor.

Satu ADC Unit dapat membaca banyak channel secara bergantian. Buat satu manager,
daftarkan GPIO yang berbeda untuk sensor-sensor, lalu berikan handle manager
yang sama ke setiap `ntc10k_create()`. Sensor analog lain juga dapat
dikonfigurasi dan dibaca melalui manager tersebut.

Contoh proyek dengan lima input analog pada **ESP32-S3**:

| Sensor | ADC Unit | GPIO yang disambungkan |
|---|---|---|
| NTC 1 | `ADC_UNIT_1` | `GPIO_NUM_1` |
| NTC 2 | `ADC_UNIT_1` | `GPIO_NUM_2` |
| NTC 3 | `ADC_UNIT_1` | `GPIO_NUM_3` |
| Sensor analog 1 | `ADC_UNIT_1` | `GPIO_NUM_4` |
| Sensor analog 2 | `ADC_UNIT_1` | `GPIO_NUM_5` |

Tabel tersebut contoh khusus ESP32-S3. Pada chip/board lain, GPIO yang bisa
dipakai sebagai ADC dapat berbeda. Periksa pinout board. Untuk NTC, GPIO
dipetakan otomatis ke channel oleh `adc_manager`.

Contoh berikut memakai **ESP32-S3** dengan tiga NTC di GPIO 1, 2, dan 3.
Pada board lain, pilih GPIO ADC sesuai datasheet/pemetaan pin chip. Program ini
membuat ADC manager satu kali dan membagikannya ke semua NTC:

```c
#include <inttypes.h>

#include "adc_manager.h"
#include "esp_check.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "ntc10k.h"

static const char *TAG = "ntc_example";

void app_main(void)
{
    adc_manager_handle_t adc = NULL;
    ESP_ERROR_CHECK(adc_manager_create(ADC_UNIT_1, &adc));

    ntc10k_config_t config_1 = ntc10k_get_default_config(GPIO_NUM_1);
    ntc10k_config_t config_2 = ntc10k_get_default_config(GPIO_NUM_2);
    ntc10k_config_t config_3 = ntc10k_get_default_config(GPIO_NUM_3);
    ntc10k_handle_t ntc_1 = NULL;
    ntc10k_handle_t ntc_2 = NULL;
    ntc10k_handle_t ntc_3 = NULL;
    ESP_ERROR_CHECK(ntc10k_create(adc, &config_1, &ntc_1));
    ESP_ERROR_CHECK(ntc10k_create(adc, &config_2, &ntc_2));
    ESP_ERROR_CHECK(ntc10k_create(adc, &config_3, &ntc_3));

    // Opsional: daftarkan sensor analog biasa pada GPIO 4.
    ESP_ERROR_CHECK(adc_manager_configure_channel(adc,
                                                  GPIO_NUM_4,
                                                  ADC_ATTEN_DB_12,
                                                  ADC_BITWIDTH_12));

    while (true) {
        ntc10k_reading_t reading_1;
        ntc10k_reading_t reading_2;
        ntc10k_reading_t reading_3;
        int analog_raw = 0;
        esp_err_t err_1 = ntc10k_read(ntc_1, &reading_1);
        esp_err_t err_2 = ntc10k_read(ntc_2, &reading_2);
        esp_err_t err_3 = ntc10k_read(ntc_3, &reading_3);
        esp_err_t analog_err = adc_manager_read_raw(adc, GPIO_NUM_4, &analog_raw);

        if (err_1 == ESP_OK && err_2 == ESP_OK && err_3 == ESP_OK) {
            ESP_LOGI(TAG,
                     "NTC1=%.2f C, NTC2=%.2f C, NTC3=%.2f C",
                     (double)reading_1.temperature_c,
                     (double)reading_2.temperature_c,
                     (double)reading_3.temperature_c);
        } else {
            ESP_LOGW(TAG, "Setidaknya satu pembacaan NTC tidak valid");
        }
        if (analog_err == ESP_OK) {
            ESP_LOGI(TAG, "Sensor analog GPIO4 raw=%d", analog_raw);
        } else {
            ESP_LOGW(TAG, "Pembacaan sensor analog gagal: %s",
                     esp_err_to_name(analog_err));
        }
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}
```

Pada contoh, `ntc10k_create()` mendaftarkan GPIO 1, 2, dan 3 ke manager.
Manager mencari channel yang sesuai; pengguna tidak perlu menebak atau mengisi
`ADC_CHANNEL_n`. Log inisialisasi manager menampilkan Unit, channel, dan GPIO.

`GPIO_NUM_4` pada kode adalah contoh **sensor analog tambahan**, bukan salah
satu NTC. GPIO itu didaftarkan dengan `adc_manager_configure_channel()`, lalu
nilainya dibaca dengan `adc_manager_read_raw()` di dalam loop. Sambungkan
keluaran sensor analog tersebut ke GPIO 4 jika memakai bagian contoh ini.

Jika proyek hanya memakai tiga NTC, hapus baris `adc_manager_configure_channel()`
untuk GPIO 4, deklarasi dan pembacaan `analog_raw`/`analog_err`, serta blok log
sensor analog GPIO 4. Tiga NTC tetap bekerja karena `ntc10k_create()` sudah
mendaftarkan GPIO NTC masing-masing ke manager.

Untuk setiap sensor analog tambahan, panggil `adc_manager_configure_channel()`
sekali per GPIO, lalu gunakan `adc_manager_read_raw()` untuk membaca nilai raw.
Untuk pemakaian lima input, pilih lima GPIO yang memang dipetakan sebagai pin
ADC oleh chip Anda. Tegangan pada setiap input harus berada dalam batas ADC
chip.

Kalibrasi tegangan bersifat opsional. Tanpa calibration handle, tegangan
dihitung sebagai perkiraan dari nilai raw. Untuk akurasi lebih baik, aplikasi
dapat membuat ADC calibration handle yang cocok dengan ADC Unit dan attenuation
channel, lalu mengisinya di konfigurasi tiap NTC. Manager memiliki ADC Unit;
aplikasi tetap memiliki dan mengelola calibration handle.

## Konfigurasi

Panggil `ntc10k_get_default_config(GPIO_NUM_x)` untuk memilih pin fisik, lalu
ubah parameter lain sesuai rangkaian dan datasheet termistor. ADC Unit sudah
dipilih saat membuat manager dan tidak perlu diulang di konfigurasi NTC:

| Field | Default | Keterangan |
|---|---:|---|
| `gpio_num` | Dipilih saat membuat config | Pin ADC fisik; channel dipetakan otomatis sesuai target |
| `attenuation` | `ADC_ATTEN_DB_12` | Attenuation channel; enum yang tersedia bergantung target |
| `bitwidth` | `ADC_BITWIDTH_12` | Lebar ADC yang didukung target |
| `adc_max_raw` | 4095 | Kode raw maksimum untuk lebar ADC yang dikonfigurasi |
| `calibration` | `NULL` | Calibration handle aplikasi, atau `NULL` untuk estimasi |
| `divider_supply_voltage_v` | 3.3 V | Tegangan supply aktual pada rangkaian pembagi |
| `adc_full_scale_voltage_v` | 3.3 V | Estimasi tegangan saat raw mencapai `adc_max_raw` jika tanpa kalibrasi |
| `series_resistance_ohms` | 10000 Ohm | Nilai resistor tetap pada pembagi |
| `ntc_position` | `NTC10K_TO_GROUND` | Posisi NTC pada pembagi |
| `model` | `NTC10K_MODEL_BETA` | Model konversi suhu |
| `nominal_resistance_ohms` | 10000 Ohm | `R0` model Beta |
| `nominal_temperature_c` | 25 C | `T0` model Beta |
| `beta_k` | 3950 K | Nilai Beta sesuai datasheet |
| `steinhart_a/b/c` | 0 | Isi dengan koefisien datasheet saat memakai model Steinhart-Hart |
| `minimum_temperature_c` / `maximum_temperature_c` | -40..125 C | Rentang validasi aplikasi |
| `sample_count` | 9 | Banyak sampel, 1..64 |
| `sample_interval_ms` | 0 ms | Jeda antar pembacaan ADC |
| `rail_margin_raw` | 2 | Zona kode ADC yang dianggap mendekati short/open |
| `filter` | `NTC10K_FILTER_MEDIAN` | Mean, median, atau trimmed mean |

Saat memilih `NTC10K_MODEL_STEINHART_HART`, komponen menggunakan:
`1/T = A + B ln(R) + C (ln(R))^3`, dengan suhu dalam Kelvin dan resistansi
dalam Ohm. Pastikan koefisien cocok dengan satuan resistansi tersebut.
Parameter Beta digunakan hanya untuk model Beta.

Untuk trimmed mean, paling sedikit diperlukan 3 sampel. Satu nilai terendah
dan tertinggi dibuang (lebih banyak untuk kumpulan sampel besar), lalu nilai
lainnya dirata-ratakan.

## Pembacaan dan penanganan error

Gunakan satu pemanggilan `ntc10k_read()` untuk mendapat snapshot konsisten;
jangan memanggil pembacaan terpisah untuk masing-masing unit suhu karena tiap
pembacaan akan mengambil sampel ADC baru.

- `ESP_OK`: hasil dan semua satuan suhu valid.
- `ESP_ERR_INVALID_RESPONSE`: raw di luar rentang, rangkaian open/short, model
  menghasilkan nilai tak valid, atau suhu di luar rentang konfigurasi. Pada
  gangguan rangkaian atau suhu, periksa `reading.fault`; beberapa field hasil
  dapat tetap memuat data diagnostik.
- Error ADC atau kalibrasi lain diteruskan. Jangan gunakan hasil jika error
  bukan `ESP_OK` atau gangguan teridentifikasi.

`NTC10K_FAULT_OPEN_CIRCUIT` dan `NTC10K_FAULT_SHORT_CIRCUIT` ditentukan dari
arah rangkaian dan kode dekat rail ADC. Gangguan resistif atau sambungan buruk
yang tidak mencapai rail dapat muncul sebagai suhu di luar rentang, bukan
selalu dapat dibedakan sebagai open/short.

## Akurasi dan keselamatan pengukuran

- Gunakan nilai `R0`, `T0`, Beta atau koefisien Steinhart-Hart, serta toleransi
  resistor yang sesuai dengan komponen nyata. "NTC10K" saja tidak menentukan
  semua parameter kurva.
- Kalibrasi tegangan supply pembagi dan ADC meningkatkan estimasi resistansi.
  Jika ADC calibration handle tidak tersedia, tandai hasil `voltage_calibrated`
  sebagai `false` dan perlakukan pembacaan sebagai estimasi.
- Perubahan supply, toleransi resistor, self-heating akibat arus pembagi,
  pemasangan sensor, kabel, dan thermal lag memengaruhi suhu yang terbaca.
  Pilih resistor pembagi dan arus agar self-heating termistor tetap rendah.
- Komponen tidak menerapkan filter waktu atau proteksi hardware eksternal;
  tentukan batas suhu/error aplikasi sesuai penggunaan akhir.

## Kepemilikan resource dan dependensi

`adc_manager` membuat dan menghapus ADC Unit, serta mengonfigurasi dan
menserialisasi pembacaan channel. Aplikasi harus menghentikan dan melepas semua
sensor sebelum memanggil `adc_manager_deinit()` atau menghapus calibration
handle.

Komponen didaftarkan melalui `CMakeLists.txt` dan `idf_component.yml`,
menggunakan dependency publik `adc_manager` dan `esp_adc`, dan dilisensikan di
bawah MIT. Terbitkan `adc_manager` lebih dahulu di ESP Component Registry
sebelum menerbitkan versi NTC10K yang bergantung padanya.

Links

Supports all targets

To add this component to your project, run:

idf.py add-dependency "wahyu-widodo-dev/ntc10k^1.0.0"

download archive

Stats

  • Archive size
    Archive size ~ 11.41 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

wahyu-widodo-dev/ntc10k version: 1.0.0
|