산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

아두이노만으로 DTMF 디코더 구축하기 – 추가 IC 불필요

부품 및 소모품

아두이노 우노 (Arduino UNO) 1개
LED (범용) 10개
브레드보드 (범용) 1개
점퍼 와이어 (범용) 20개

앱 및 온라인 서비스

프로젝트 소개

학기 프로젝트 목록을 검토하던 중 CM8870 IC를 DTMF 디코더로 사용하는 DTMF 제어 자동차 프로젝트를 발견했습니다. 디코더 기능이 핵심인데, 외부 IC를 통합하기가 까다로워 이를 코드나 라이브러리로 대체할 방법을 찾던 중 게르첼 알고리즘(Goertzel algorithm) 기반의 Goertzel.h 라이브러리를 찾았습니다. 이 라이브러리는 특정 주파수가 톤에 존재하는지 펄스 수와 진폭 기여도를 계산해 판별합니다.

기본 예제 코드를 바탕으로, 전화 통화 중 상대방이 누른 번호에 해당하는 DTMF 주파수를 감지하고 디코딩하는 코드를 작성했습니다.

코드

아두이노 DTMF 디코더 코드

아두이노 IDE에서 코드를 컴파일하고 업로드하세요. 라이브러리(Goertzel)를 먼저 추가하는 것을 잊지 마세요.

/* DTMF 디코더 기본 구현: 아날로그 핀 A0에서 16개 DTMF 문자를 감지하고,
   DTMF 매트릭스의 상위/하위 톤을 확인해 해당 숫자를 디코딩합니다.
   숫자 0-9는 해당 디지털 핀(2~12)을 HIGH로 설정하고,
   특수 문자는 시리얼 모니터에 출력합니다.
   Kevin Banks의 게르첼 알고리즘 구현(https://www.embedded.com/design/embedded/4024443/The-Goertzel-Algorithm)을 기반으로 하며,
   위키피디아(https://en.wikipedia.org/wiki/Goertzel_algorithm)에도 상세 설명이 있습니다.
   게르첼 알고리즘은 FFT 대안으로 단일 주파수만 탐색하므로 오버헤드가 적고 빠릅니다.
   작성/수정: Mian Mohammad Shoaib (MMSHOAIB8452@GMAIL.COM) */

#include <Goertzel.h>

int sensorPin = A0;
const int N = 100;                  // 샘플 수 (민감도 조절 가능, 너무 크면 속도 저하)
const float threshold = 2000;       // 톤 진폭 임계값 (민감도 조절용)
const float sampling_freq = 8900;   // 샘플링 주파수 (아두이노 우노 16MHz 기준 최대 8900Hz)

float x_frequencies[4];  // 열(Column) 주파수
float y_frequencies[4];  // 행(Row) 주파수

void setup() {
  pinMode(13, OUTPUT);  // 톤 감지 표시용 LED
  for (int i = 2; i <= 12; i++) pinMode(i, OUTPUT);  // DTMF 출력 핀 (0-9)
  Serial.begin(9600);

  // DTMF 주파수 매트릭스 초기화
  x_frequencies[0] = 1209; x_frequencies[1] = 1336;
  x_frequencies[2] = 1477; x_frequencies[3] = 1633;
  y_frequencies[0] = 697;  y_frequencies[1] = 770;
  y_frequencies[2] = 852;  y_frequencies[3] = 941;
}

bool detect_tone(float freq) {
  Goertzel goertzel = Goertzel(freq, N, sampling_freq);
  goertzel.sample(sensorPin);
  float magnitude = goertzel.detect();

  if (magnitude > threshold) {
    digitalWrite(13, HIGH);
    delay(250);
    digitalWrite(13, LOW);
    Serial.println(freq);
    return true;
  }
  return false;
}

void print_number(int row, int column) {
  int number = 0;
  // 행/열 조합으로 키패드 번호 매핑
  if (row == 0) {
    if (column == 0) number = 1;
    else if (column == 1) number = 2;
    else if (column == 2) number = 3;
    else if (column == 3) number = 10;  // A
  } else if (row == 1) {
    if (column == 0) number = 4;
    else if (column == 1) number = 5;
    else if (column == 2) number = 6;
    else if (column == 3) number = 11;  // B
  } else if (row == 2) {
    if (column == 0) number = 7;
    else if (column == 1) number = 8;
    else if (column == 2) number = 9;
    else if (column == 3) number = 12;  // C
  } else if (row == 3) {
    if (column == 0) number = 14;  // *
    else if (column == 1) number = 0;
    else if (column == 2) number = 15;  // #
    else if (column == 3) number = 13;  // D
  }

  if (number < 10) {
    digitalWrite(number + 2, HIGH);
    Serial.print(number);
  } else if (number == 10) Serial.print('A');
  else if (number == 11) Serial.print('B');
  else if (number == 12) Serial.print('C');
  else if (number == 13) Serial.print('D');
  else if (number == 14) Serial.print('*');
  else if (number == 15) Serial.print('#');
  Serial.println();

  delay(800);
  for (int i = 2; i <= 12; i++) digitalWrite(i, LOW);
}

void loop() {
  int column = 0, row = 0, i = 0;

  // 열(Column) 주파수 탐지
  while (1) {
    if (detect_tone(x_frequencies[i])) { column = i; break; }
    i++; if (i == 4) i = 0;
  }

  // 행(Row) 주파수 탐지
  i = 0;
  while (1) {
    if (detect_tone(y_frequencies[i])) { row = i; break; }
    i++; if (i == 4) i = 0;
  }

  print_number(row, column);
}

회로도

디지털 핀 2~12에 LED 10개를 연결해 숫자 0~9 입력 시 해당 LED가 켜지도록 하고, 핀 13에는 펄스 감지용 LED를 연결합니다. 특수 문자(*, #, A-D)는 시리얼 모니터에 출력됩니다.

오디오 잭 또는 AUX 케이블의 입력은 1uF 커패시터를 직렬로 연결해 아날로그 핀 A0에 연결합니다. 이 커패시터는 저주파와 DC 오프셋을 필터링합니다.

아두이노만으로 DTMF 디코더 구축하기 – 추가 IC 불필요

제조공정

  1. 아두이노로 모니터 앰비라이트(Ambilight) 시스템 직접 만들기
  2. 아두이노로 초음파 부양 장치 만들기: 단계별 가이드
  3. SERENA: TFT LCD 터치스크린 탑재 아두이노 메가 2560 커스텀 알람 시스템
  4. 아두이노와 스마트폰으로 만드는 스마트 전압계 – 초간단 DIY 프로젝트
  5. 아두이노와 MAX30100으로 만드는 실시간 IoT 심박수 모니터
  6. 레이저 모듈로 구현하는 모스 부호 통신 – 아두이노 양방향 프로젝트
  7. 아두이노 우노 와이파이 웹 서버: 브라우저로 LED 제어하기
  8. 스마트 주차 카운터: 아두이노, 프로세싱, PHP로 실시간 차량 추적
  9. 아두이노로 크롬 공룡 게임 자동화하기 – LDR과 파이썬으로 장애물 감지
  10. 파이썬 3로 아두이노 우노 제어하기 – 시리얼 통신 LED 제어 기초