/* * Phase-Angle Control untuk pemicuan Triac. * Menggunakan interrupt. * LAMA_PEMICUAN diperlukan 1 mS untuk memastikan, * pemicuan terjadi dengan baik. * * Tidak ada fitur komunikasi serial. * * Tidak ada perlindungan untuk batas maksimal * sudut pemicuan. * */ #include // Konstanta const float DEFAULT_FREQUENCY = 50.0; // PLN frek dalam Hz (default: 50 Hz) const uint8_t DEFAULT_PHASE_ANGLE = 120; // Sudut pemicuan dalam degree const uint16_t LAMA_PEMICUAN = 1000; // Lamanya sinyal pemicu /* * Sudut minimal: 0 * Sudut maksimal: 150 */ // Pin definitions const int ZERO_CROSS_PIN = 2; // Pin ke ZCD const int TRIAC_CONTROL_PIN = 3; // Pin ke MOC3021 // Var untuk penghitungan pewaktuan volatile bool zeroCrossDetected = false; float frequency = DEFAULT_FREQUENCY; int phaseAngle = DEFAULT_PHASE_ANGLE; float halfCyclePeriodMs; // Half cycle period in milliseconds float delayMs; uint16_t delayMS_int = 0; void setup() { pinMode(ZERO_CROSS_PIN, INPUT); pinMode(TRIAC_CONTROL_PIN, OUTPUT); digitalWrite(TRIAC_CONTROL_PIN, LOW); // Calculate half-cycle period (ms) halfCyclePeriodMs = 1000.0 / (2 * frequency); // Calculate delay based on phase angle delayMs = (phaseAngle / 180.0) * halfCyclePeriodMs; // Konversi dari float ke uint16_t // delayMS_int= static_cast(delayMs * 1000); delayMS_int= static_cast(delayMs * 1000); Serial.begin(9600); Serial.println(" Phase-Angle Control (PAC) untuk Triac."); Serial.print(" Nilai sudut picu dalam derajat: "); Serial.println(DEFAULT_PHASE_ANGLE); Serial.print(" Nilai delay dalam micro seconds: "); Serial.println(delayMS_int); Serial.println(""); // Inisiasi bagian interrupt. attachInterrupt(digitalPinToInterrupt(ZERO_CROSS_PIN), zeroCrossISR, RISING); } void loop() { if (zeroCrossDetected) { zeroCrossDetected = false; // Waktu tunda berdasarkan nilai firing angle. delayMicroseconds(delayMS_int); // Dihitung berdasarkan nilai sudut. // Bagian pemicuan Triac digitalWrite(TRIAC_CONTROL_PIN, HIGH); delayMicroseconds(LAMA_PEMICUAN); // Waktu tunda pulsa pemicuan MOC3021, min 1000 uS digitalWrite(TRIAC_CONTROL_PIN, LOW); } } // Rutin interrupt void zeroCrossISR() { zeroCrossDetected = true; }