工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ArduinoだけでDTMFデコーダーを構築 – 外付けIC不要

必要な部品と材料

使用するアプリとオンラインサービス

プロジェクトの概要

学期のプロジェクト課題でDTMF制御のラジコンカーを見つけました。これはCM8870というDTMFデコーダーICを使用し、デコードされたバイナリデータをArduinoに渡して前後左右の制御を行うものでした。しかし、この外付けICの組み込みが難しく、ライブラリやコードでICを置き換えられる方法を探していました。そこで、ゲルツェルアルゴリズム(Goertzelアルゴリズム)をベースにしたGoertzel.hライブラリを見つけました。これは特定の周波数が信号に含まれているかどうかを、単位時間あたりのパルス数と振幅寄与から判定するものです。

このライブラリの基本サンプルコードをベースに、DTMFトーンに含まれる主要な周波数を検出し、電話の相手側で押された番号をデコードするコードを作成しました。

回路図

デジタルピン2〜12に10個のLEDを接続し、0〜9の数字に対応するトーンが検出されるとそれぞれ点灯します。ピン13にはパルス検出用LEDを接続し、信号検出時に短く点滅します。10以上の特殊文字(*、#、A〜D)はシリアルモニターに出力されます。オーディオジャックまたはAUXケーブルからの入力は、1μFのコンデンサを直列に挟んでアナログピンA0に接続し、低周波とDCオフセットを除去します。

ArduinoだけでDTMFデコーダーを構築 – 外付けIC不要

ソースコード

/* DTMFデコーダーの基本実装
 * アナログピンA0から16文字のDTMFコードを検出し、DTMFマトリクスの上段・下段トーンをチェックして
 * 対応する数字をデジタル出力(0-9)およびシリアル出力(A-D、*、#)で表示します。
 * Kevin Banks氏のコード(https://www.embedded.com/design/embedded/4024443/The-Goertzel-Algorithm)をベースにしています。
 * ゲルツェルアルゴリズムの詳細は https://en.wikipedia.org/wiki/Goertzel_algorithm を参照。
 * 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;  // サンプリング周波数(Arduino Uno 16MHzで最大8900Hz)

float x_frequencies[4];  // 高周波群(列)
float y_frequencies[4];  // 低周波群(行)

void setup() {
  pinMode(13, OUTPUT);  // 検出表示用LED
  for (int i = 2; i <= 12; i++) pinMode(i, OUTPUT);  // 数字表示用LED
  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;

  // 高周波群(列)を検出
  while (1) {
    if (detect_tone(x_frequencies[i])) { column = i; break; }
    i++; if (i == 4) i = 0;
  }
  // 低周波群(行)を検出
  i = 0;
  while (1) {
    if (detect_tone(y_frequencies[i])) { row = i; break; }
    i++; if (i == 4) i = 0;
  }
  print_number(row, column);
}

ライブラリのインストール

Goertzelライブラリが必要です。以下からダウンロードしてArduino IDEにインストールしてください。
https://github.com/jacobrosenthal/Goertzel

製造プロセス

  1. Arduinoで作るモニター用Ambilightシステム:没入感アップの自作ガイド
  2. Arduinoで超音波レベーション(浮遊)装置を自作:ステップバイステップガイド
  3. SERENA:Arduino Mega 2560とTFT LCDタッチスクリーン搭載カスタムアラームシステム
  4. Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
  5. ArduinoとMAX30100で作るリアルタイムIoT心拍数モニター
  6. レーザーモジュールでモールス信号通信 – Arduino二台で送受信
  7. Arduino UNO WiFi Webサーバー:ブラウザからLEDをON/OFF制御
  8. スマート駐車場カウンター:Arduino、Processing、PHPでリアルタイム車両管理
  9. Arduinoで自動化するChrome恐竜ゲーム – LDRとPythonで障害物を検知してジャンプ
  10. Python 3からArduino UNOを制御 – シリアル通信でLED点滅デモ
  11. Arduino NanoとRDA5807Mで作るコンパクトFMラジオ