why is the ACS712 30A reading always 0 in this code?
Hasil rata-rata offset: 2.25
Max Value: 2908, Min Value: 2658, Vpp: 0.20
Voltage after Offset: -0.56
Arus Fan (AmpsRMS): 0.00
Suhu: 0.00F, Arus Fan: 0.00
#include <Arduino.h>
#include <driver/twai.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Konfigurasi OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
// Pin CAN Bus ESP32
#define CAN_TX_PIN 5
#define CAN_RX_PIN 4
// Pin LED dan Buzzer
#define LED_MERAH 13
#define BUZZER_PIN 12
// Pin ACS712 Global
#define ACS712_PIN 35 // Pin analog untuk sensor ACS712
#define MV_PER_AMP 66 // Sesuaikan untuk ACS712 30A (66mV/A)
// Batas suhu kritis
#define BATAS_SUHU_KRITIS 100.0
// Offset global untuk sensor ACS712
float sensorOffset = 2.5; // Nilai default offset (tegangan tengah sensor ACS712)
// Objek OLED
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Variabel Global
float engineTemperature = 0.0;
float fanCurrent = 0.0;
float lastEngineTemp = 0.0;
float lastFanCurrent = 0.0;
// Fungsi kalibrasi ACS712
float kalibrasiACS712() {
float total = 0;
for (int i = 0; i < 100; i++) {
total += analogRead(ACS712_PIN) * 3.3 / 4096.0;
delay(10); // Tunggu antara pembacaan
}
return total / 100; // Rata-rata tegangan
}
// Fungsi filter sederhana (Exponential Moving Average)
float filterNilai(float nilaiBaru, float nilaiLama, float alpha) {
return (alpha * nilaiBaru) + ((1 - alpha) * nilaiLama);
}
// Fungsi setup pin output
void setupPinOutput() {
pinMode(LED_MERAH, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
}
// Fungsi setup CAN bus
void setupCANBus() {
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(
(gpio_num_t)CAN_TX_PIN,
(gpio_num_t)CAN_RX_PIN,
TWAI_MODE_NORMAL
);
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
Serial.println("CAN Bus Driver Installed");
twai_start();
}
}
// Fungsi untuk mengukur tegangan puncak-puncak (Vpp)
float getVPP() {
int maxValue = 0;
int minValue = 4096;
uint32_t start_time = millis();
while ((millis() - start_time) < 1000) {
int readValue = analogRead(ACS712_PIN);
if (readValue > maxValue) {
maxValue = readValue;
}
if (readValue < minValue) {
minValue = readValue;
}
}
if (maxValue == minValue) {
Serial.println("Kesalahan pembacaan Vpp: maxValue == minValue");
return 0;
}
float Vpp = ((maxValue - minValue) * 3.3) / 4096.0;
// Debug: Print nilai maksimum, minimum, dan Vpp
Serial.print("Max Value: ");
Serial.print(maxValue);
Serial.print(", Min Value: ");
Serial.print(minValue);
Serial.print(", Vpp: ");
Serial.println(Vpp);
return Vpp; // Vpp
}
// Fungsi untuk membaca tegangan offset ACS712
float bacaOffsetACS712() {
float total = 0.0;
// Loop untuk membaca beberapa sampel
for (int i = 0; i < 100; i++) {
float teganganSaatIni = analogRead(ACS712_PIN) * 3.3 / 4096.0;
total += teganganSaatIni;
// Debugging untuk memantau setiap pembacaan
Serial.print("Sample ke-");
Serial.print(i + 1);
Serial.print(": Tegangan = ");
Serial.println(teganganSaatIni);
delay(10); // Tunggu antara pembacaan
}
float rataRata = total / 100.0;
// Debugging hasil rata-rata
Serial.print("Hasil rata-rata offset: ");
Serial.println(rataRata);
return rataRata; // Rata-rata offset
}
// Fungsi untuk membaca arus kipas menggunakan ACS712
bool bacaArusFan() {
static unsigned long lastCurrentReadTime = 0;
// Baca arus setiap 500ms
if (millis() - lastCurrentReadTime >= 500) {
// Baca tegangan offset terbaru
sensorOffset = bacaOffsetACS712();
float Voltage = getVPP(); // Ambil Vpp
Voltage -= sensorOffset; // Kompensasi offset
// Filter tegangan untuk meredam noise
static float voltageFiltered = 0;
voltageFiltered = filterNilai(Voltage, voltageFiltered, 0.1);
Voltage = voltageFiltered;
// Debug: Print nilai tegangan setelah kompensasi offset
Serial.print("Voltage after Offset: ");
Serial.println(Voltage);
// Abaikan noise kecil
if (Voltage < 0.01) {
fanCurrent = 0.0;
} else {
// Konversi Vpp ke RMS
float VRMS = (Voltage / 2.0) * 0.707;
float AmpsRMS = (VRMS * 1000) / MV_PER_AMP;
fanCurrent = fabs(AmpsRMS);
// Debug: Print nilai VRMS dan AmpsRMS
Serial.print("VRMS: ");
Serial.print(VRMS);
Serial.print(", AmpsRMS: ");
Serial.println(AmpsRMS);
}
Serial.print("Arus Fan (AmpsRMS): ");
Serial.println(fanCurrent);
lastCurrentReadTime = millis();
return true;
}
return false;
}
// Fungsi untuk membaca suhu mesin dari CAN bus
bool bacaSuhuECT() {
static unsigned long lastTempReadTime = 0;
// Baca suhu setiap 500ms
if (millis() - lastTempReadTime >= 500) {
twai_message_t message;
uint32_t targetID = 0x7E0;
if (twai_receive(&message, pdMS_TO_TICKS(100)) == ESP_OK) {
if (message.identifier == targetID) {
engineTemperature = ((message.data[2] - 40.0) * 1.8) + 32.0;
lastTempReadTime = millis();
return true;
}
}
}
return false;
}
// Fungsi kontrol peringatan
void kontrolPeringatan() {
if (engineTemperature > BATAS_SUHU_KRITIS) {
digitalWrite(LED_MERAH, HIGH);
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
static bool buzzerState = false;
if (currentMillis - previousMillis >= 500) {
previousMillis = currentMillis;
buzzerState = !buzzerState;
digitalWrite(BUZZER_PIN, buzzerState);
}
} else {
digitalWrite(LED_MERAH, LOW);
digitalWrite(BUZZER_PIN, LOW);
}
}
// Fungsi untuk menampilkan data di OLED
void tampilkanDisplay() {
display.clearDisplay();
display.setTextColor(WHITE);
// Tampilkan suhu mesin
display.setCursor(0, 0);
display.setTextSize(1);
display.print("Suhu Mesin: ");
display.print(engineTemperature, 1);
display.print(" F");
// Tampilkan arus kipas
display.setCursor(0, 16);
display.print("Arus Fan: ");
display.print(fanCurrent, 2);
display.print(" A");
// Tampilkan peringatan jika suhu kritis
if (engineTemperature > BATAS_SUHU_KRITIS) {
display.setCursor(90, 16);
display.print("KRITIS!");
}
display.display();
}
void setup() {
analogReadResolution(12); // Resolusi ADC 12-bit
analogSetPinAttenuation(ACS712_PIN, ADC_0db); // Input 0-3.3V
Serial.begin(115200);
setupPinOutput();
Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("Gagal inisialisasi OLED"));
for (;;);
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.display();
setupCANBus();
// Kalibrasi nilai offset dari ACS712
sensorOffset = kalibrasiACS712();
Serial.print("Offset Sensor setelah Kalibrasi: ");
Serial.println(sensorOffset);
}
void loop() {
bool tempRead = bacaSuhuECT();
bool currentRead = bacaArusFan();
if (tempRead || currentRead) {
Serial.print("Suhu: ");
Serial.print(engineTemperature);
Serial.print("F, Arus Fan: ");
Serial.println(fanCurrent);
tampilkanDisplay();
kontrolPeringatan();
}
delay(50); // Delay minimal untuk memberikan waktu proses
}

