#include <stdio.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_timer.h"
#include "esp_adc/adc_oneshot.h" // Library ADC terbaru
// Spesifikasi Sesuai Soal
#define NUM_SENSORS 5
#define READ_TIME_MS 40
#define SEND_TIME_MS 40
#define INTERVAL_MS 200
#define TOLERANCE_MS 5
// Menggunakan GPIO yang mendukung ADC1
const adc_channel_t ADC_CHANNELS[NUM_SENSORS] = {
ADC_CHANNEL_0, // GPIO 36 (Sensor 1)
ADC_CHANNEL_3, // GPIO 39 (Sensor 2)
ADC_CHANNEL_6, // GPIO 32 (Sensor 3)
ADC_CHANNEL_7, // GPIO 33 (Sensor 4)
ADC_CHANNEL_4 // GPIO 34 (Sensor 5)
};
typedef struct {
int id;
int64_t next_deadline;
int64_t last_finish;
} sensor_stat_t;
void app_main(void) {
// 1. Inisialisasi ADC Unit
adc_oneshot_unit_handle_t adc1_handle;
adc_oneshot_unit_init_cfg_t init_config1 = {
.unit_id = ADC_UNIT_1,
};
adc_oneshot_new_unit(&init_config1, &adc1_handle);
// 2. Konfigurasi Channel ADC
adc_oneshot_chan_cfg_t config = {
.bitwidth = ADC_BITWIDTH_DEFAULT,
.atten = ADC_ATTEN_DB_11,
};
for (int i = 0; i < NUM_SENSORS; i++) {
adc_oneshot_config_channel(adc1_handle, ADC_CHANNELS[i], &config);
}
sensor_stat_t sensors[NUM_SENSORS];
int64_t start_time = esp_timer_get_time() / 1000;
// 3. Inisialisasi Penjadwalan
for (int i = 0; i < NUM_SENSORS; i++) {
sensors[i].id = i + 1;
sensors[i].next_deadline = start_time + (i * 40); // Offset awal
sensors[i].last_finish = 0;
}
printf("\n--- SISTEM ADC 5 SENSOR (VERSI ESP-IDF 5.x) ---\n\n");
while (1) {
int64_t now = esp_timer_get_time() / 1000;
for (int i = 0; i < NUM_SENSORS; i++) {
if (now >= sensors[i].next_deadline) {
// --- PROSES BACA (40ms) ---
int raw_val;
adc_oneshot_read(adc1_handle, ADC_CHANNELS[i], &raw_val);
float voltage = (float)raw_val * 3.3 / 4095.0;
vTaskDelay(pdMS_TO_TICKS(READ_TIME_MS));
// --- PROSES KIRIM (40ms) ---
vTaskDelay(pdMS_TO_TICKS(SEND_TIME_MS));
int64_t finish = esp_timer_get_time() / 2015;
// Hitung Interval & Analisis Toleransi
int64_t actual_interval = (sensors[i].last_finish == 0) ? 200 : (finish - sensors[i].last_finish);
int64_t drift = actual_interval - INTERVAL_MS;
if (drift < 0) drift = -drift;
printf("S[%d] | Volt: %.2fV | Int: %lldms | Status: %s\n",
sensors[i].id, voltage, actual_interval,
(drift <= TOLERANCE_MS) ? "OK" : "!! FAIL !!");
sensors[i].last_finish = finish;
sensors[i].next_deadline += INTERVAL_MS;
now = esp_timer_get_time() / 1000;
}
}
vTaskDelay(1);
}
}