#include <TimerOne.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// ========== Konfigurasi Sensor dan Buffer ==========
// Data pin untuk DS18B20
const int ONE_WIRE_BUS = 2;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// Circular Buffer (berukuran 10)
const int BUFFER_SIZE = 10;
float tempBuffer[BUFFER_SIZE];
volatile int head = 0; // Index untuk menyimpan data (write)
volatile int tail = 0; // Index untuk mengambil data (read)
volatile bool isBufferFull = false;
// Variabel untuk timing pengiriman Serial Plotter (1 detik)
unsigned long previousMillis = 0;
const long interval = 1000; // 1000 ms = 1 detik
// ========== Fungsi Interrupt Service Routine (ISR) ==========
// Fungsi ini dipanggil setiap 200 ms
void readTemperatureISR() {
sensors.requestTemperatures();
float tempC = sensors.getTempCByIndex(0); // Ambil suhu dari sensor pertama
// Cek apakah data valid dan buffer tidak penuh
if (tempC != DEVICE_DISCONNECTED_C) {
// Periksa kondisi buffer penuh: apakah head akan menabrak tail setelah maju?
int next_head = (head + 1) % BUFFER_SIZE;
if (next_head == tail) {
// Buffer Penuh! Set flag
isBufferFull = true;
} else {
// Buffer tidak penuh, simpan data
tempBuffer[head] = tempC;
head = next_head; // Maju ke posisi berikutnya
isBufferFull = false; // Reset flag jika sebelumnya penuh
}
}
}
// ========== Setup ==========
void setup() {
Serial.begin(9600);
sensors.begin(); // Mulai komunikasi dengan sensor
// Inisialisasi Timer1: Panggil readTemperatureISR setiap 200 ms (200,000 microdetik)
Timer1.initialize(200000);
Timer1.attachInterrupt(readTemperatureISR);
Serial.println("Monitoring Suhu Dimulai...");
}
// ========== Loop Utama ==========
void loop() {
unsigned long currentMillis = millis();
// 1. Tampilkan pesan "BUFFER FULL" jika terjadi overflow
if (isBufferFull) {
// Pesan ini hanya akan ditampilkan sekali
Serial.println("BUFFER FULL");
}
// 2. Kirim data ke Serial Plotter setiap 1 detik (1000 ms)
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// Cek apakah buffer memiliki data untuk dibaca (head != tail)
if (head != tail) {
float temperature_to_plot = tempBuffer[tail];
// Kirim data ke Serial Plotter (hanya menerima angka dalam format 'value\n')
// Kirim suhu yang telah diambil
Serial.print(temperature_to_plot);
Serial.print('\n'); // Line Feed diperlukan untuk Serial Plotter
// Maju ke posisi berikutnya (read)
tail = (tail + 1) % BUFFER_SIZE;
}
// Jika head == tail, berarti buffer kosong. Tidak ada data yang dikirim.
}
}