Belajar Elektro

Random post

Belajar Elektro

Powered By Blogger

This is default featured slide 1 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

This is default featured slide 2 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

This is default featured slide 3 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

This is default featured slide 4 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

This is default featured slide 5 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

Wednesday, 17 September 2025

DTMF Longe range Controller 2 CH

 











DTMF Kode :

const int dtmfPins[4] = {2, 3, 4, 5};

const int stdPin = 6;

const int relay1 = 8;

const int relay2 = 9;

const int buzzer = 7;

 

unsigned long debounceDelay = 300;

 

int lastTone = -1;

unsigned long lastValidTime = 0;

 

enum DTMFState { IDLE, READ_1, READ_2, READ_3 };

DTMFState dtmfState = IDLE;

 

int t1 = -1, t2 = -1, t3 = -1;

 

unsigned long dtmfTimestamp = 0;

const unsigned long dtmfInterval = 40; // waktu antar baca DTMF

 

// Status nada startup

bool isPlayingStartup = false;

int startupStep = 0;

unsigned long startupStepStart = 0;

 

const int startupFreqs[] = {1000, 1200, 1500};

const unsigned long startupDurations[] = {150, 150, 300};

const unsigned long startupIntervals[] = {200, 200, 400};

const int startupStepsCount = 3;

 

// Struktur queue nada buzzer

#define BUZZER_QUEUE_SIZE 5

struct BuzzerNote {

  unsigned int freq;

  unsigned long duration;

};

BuzzerNote buzzerQueue[BUZZER_QUEUE_SIZE];

int buzzerHead = 0;

int buzzerTail = 0;

 

unsigned long buzzerStartTime = 0;

bool buzzerPlaying = false;

 

void setup() {

  Serial.begin(9600);

 

  for (int i = 0; i < 4; i++) pinMode(dtmfPins[i], INPUT);

  pinMode(stdPin, INPUT);

  pinMode(relay1, OUTPUT);

  pinMode(relay2, OUTPUT);

  pinMode(buzzer, OUTPUT);

 

  digitalWrite(relay1, HIGH);

  digitalWrite(relay2, HIGH);

 

  playStartupTune();

}

 

void loop() {

  handleBuzzer();

  handleDTMF();

}

 

void handleDTMF() {

  unsigned long now = millis();

 

  // Jangan baca DTMF saat nada startup diputar

  if (isPlayingStartup) return;

 

  switch (dtmfState) {

    case IDLE:

      if (digitalRead(stdPin) == HIGH) {

        dtmfTimestamp = now;

        dtmfState = READ_1;

      }

      break;

    case READ_1:

      if (now - dtmfTimestamp >= dtmfInterval) {

        t1 = readDTMF();

        dtmfTimestamp = now;

        dtmfState = READ_2;

      }

      break;

    case READ_2:

      if (now - dtmfTimestamp >= dtmfInterval) {

        t2 = readDTMF();

        dtmfTimestamp = now;

        dtmfState = READ_3;

      }

      break;

    case READ_3:

      if (now - dtmfTimestamp >= dtmfInterval) {

        t3 = readDTMF();

        dtmfState = IDLE;

        if (t1 == t2 && t2 == t3 && t1 != -1) {

          if ((t1 != lastTone) || (now - lastValidTime > debounceDelay)) {

            lastTone = t1;

            lastValidTime = now;

            handleTone(t1);

          }

        }

      }

      break;

  }

}

 

int readDTMF() {

  int val = 0;

  for (int i = 0; i < 4; i++) {

    val |= (digitalRead(dtmfPins[i]) << i);

  }

  return val;

}

 

void handleTone(int tone) {

  Serial.print("DTMF Valid: ");

  Serial.println(tone);

 

  switch (tone) {

    case 1:

      setRelay(relay1, true);

      playBuzzerNote(1000, 150);

      break;

    case 2:

      setRelay(relay2, true);

      playBuzzerNote(1000, 150);

      break;

    case 3:

      setRelay(relay1, false);

      playBuzzerNote(600, 300);

      break;

    case 4:

      setRelay(relay2, false);

      playBuzzerNote(600, 300);

      break;

    default:

      Serial.println("DTMF tidak dikenali");

      break;

  }

}

 

void setRelay(int relayPin, bool on) {

  digitalWrite(relayPin, on ? LOW : HIGH);

  Serial.print("Relay ");

  Serial.print(relayPin);

  Serial.print(on ? " ON\n" : " OFF\n");

}

 

// --- Buzzer handling ---

 

void playStartupTune() {

  isPlayingStartup = true;

  startupStep = 0;

  startupStepStart = millis();

  playBuzzerNote(startupFreqs[startupStep], startupDurations[startupStep]);

}

 

void handleBuzzer() {

  unsigned long now = millis();

 

  // Tangani nada startup

  if (isPlayingStartup) {

    if (!buzzerPlaying && (now - startupStepStart >= startupIntervals[startupStep])) {

      startupStep++;

      if (startupStep >= startupStepsCount) {

        isPlayingStartup = false;

        noTone(buzzer);

        return;

      }

      playBuzzerNote(startupFreqs[startupStep], startupDurations[startupStep]);

      startupStepStart = now;

    }

    return; // Prioritas nada startup

  }

 

  // Jika buzzer sedang main nada, cek durasi

  if (buzzerPlaying) {

    if (now - buzzerStartTime >= buzzerQueue[buzzerHead].duration) {

      noTone(buzzer);

      buzzerPlaying = false;

      buzzerHead = (buzzerHead + 1) % BUZZER_QUEUE_SIZE;

    } else {

      return; // masih main nada

    }

  }

 

  // Jika tidak main nada, cek antrian nada berikutnya

  if (buzzerHead != buzzerTail) {

    BuzzerNote note = buzzerQueue[buzzerHead];

    tone(buzzer, note.freq);

    buzzerPlaying = true;

    buzzerStartTime = now;

  }

}

 

void playBuzzerNote(unsigned int freq, unsigned long dur) {

  int nextTail = (buzzerTail + 1) % BUZZER_QUEUE_SIZE;

  if (nextTail == buzzerHead) {

    // Queue penuh, nada baru diabaikan supaya tidak nge-block

    Serial.println("Buzzer queue penuh, nada diabaikan");

    return;

  }

  buzzerQueue[buzzerTail].freq = freq;

  buzzerQueue[buzzerTail].duration = dur;

  buzzerTail = nextTail;

}