LoginSignup
5
4

More than 5 years have passed since last update.

ESP8266 (ESP-WROOM-02) で圧電ブザーを制御して電話をかける

Last updated at Posted at 2016-01-18

本記事は稼働テストが成功していません

概要

DTMF(トーン信号)を生成して、電話をかける。

はじめに

私は、電子工作でどうしても試してみたいことがありました。それがこのDTMFです。

映画『名探偵コナン 戦慄の楽譜』(2008年) では、コナンともう一人の生声によって、110番に電話をかけるシーンが出てきます。「音痴で有名なコナンが特定周波数の声を出せるのか!?」と疑問に思いましたが、「まぁ、映画だしね。」と流していました。そもそも、声でそんなこと出来ないだろうし。

ところが、その後、朝日放送『探偵!ナイトスクープ』(2009年) では、コナンを検証する形で、音大生二人の生声によって時報サービスに電話をかけることに成功しました。この瞬間、鳥肌が立ちましたね。もう、何年も前の話ですが、鮮明に覚えています。

「WROOM02 で、是非、やってやろう!」というのが今回の企画です。

「このご時世、Twilio 等、専用の電話APIがあるじゃない」は、言わないで。ただ、やってみたいだけですから。

仕様

DTMF
DTMF(英: Dual-Tone Multi-Frequency)は、0から9までの数字と、*、#、A、B、C、Dの記号の計16種類の符号を、低群・高群の2つの音声周波数帯域の合成信号音で送信する方法である。別名「トーン信号」「プッシュ信号」とも呼ばれ、その信号音は人間の可聴域にあるため日本語では「ピ、ポ、パ」とも擬音語表記される。

DTMFマトリックス

1209 1336 1477 1633
697 1 2 3 A
770 4 5 6 B
852 7 8 9 C
941 * 0 # D

回路図

スケッチで指定する、IO5 / IO4 番ピンに、圧電ブザーをつなげて下さい。
(ひとつにまとめても大丈夫だと思うのですが、なにぶん、実験が成功していないのでわかりません)

const int OUT_HIGH = 5;
const int OUT_LOW  = 4;

スケッチ

シングルスレッドで、周期的な二つの信号の HIGH / LOW を切り替える部分が面倒でした。

const int freqL[4] = { 697,  770,  852,  941};
const int freqH[4] = {1209, 1336, 1477, 1633};
int freq[] = {
  freqL[3], freqH[1], // 0
  freqL[0], freqH[0], // 1
  freqL[0], freqH[1], // 2
  freqL[0], freqH[2], // 3
  freqL[1], freqH[0], // 4
  freqL[1], freqH[1], // 5
  freqL[1], freqH[2], // 6
  freqL[2], freqH[0], // 7
  freqL[2], freqH[1], // 8
  freqL[2], freqH[2], // 9
  freqL[3], freqH[0], // *
  freqL[3], freqH[2], // #
  1, 2                // LED テスト用 (1Hz/2Hz)
};

const int OUT_HIGH = 5;
const int OUT_LOW  = 4;

struct Status {
  bool highlow;
  long delay;
};

const int Pin[2] = {OUT_LOW, OUT_HIGH};

Status x[2];

int tel[40] = {0};


void setup() {
  Serial.begin(115200);
  Serial.println();

  pinMode(Pin[0], OUTPUT);
  pinMode(Pin[1], OUTPUT);

  int N = sizeof(freq) / sizeof(freq[0]);
  for (int i = 0; i < N; i++) {
    freq[i] = 1000000 / freq[i] / 2; // micro sec
  }

  Serial.println("Input Telephone Number :");
}

void loop() {
//const int LP =  2; // 100 msec x  2回
const int LP = 40; // 100 msec x 40回 (LED)

  static int lp = 0;
  static int c = 0;

  static int telsize = 0;

  for (int i = 0; 0 < Serial.available(); ) {
    char ch = Serial.read();
    if (ch == '\n') {
      c = 0;
      break;
    } else if ('0' <= ch && ch <= '9') {
      tel[i++] = ch - '0';
      telsize = i;
    } else if ('X' == ch) {
      // LEDテスト用
      tel[i++] = 12;
      telsize = i;
    }
  }


  int telnum = tel[c];
  int* numfreq = freq + telnum * 2;

  // 初期化
  if (lp == 0) {
    for (int i = 0; i < 2; i++) {
      digitalWrite(Pin[i], LOW);
      x[i].highlow = false;
      x[i].delay = 0;
    }
    Serial.print(c);
    Serial.print(" ");
    Serial.println(telnum);
  }

  if (telsize <= c) {
    delay(400);
    return;
  }

    Serial.print("period : ");
    Serial.print(numfreq[0]);
    Serial.print(" ");
    Serial.print(numfreq[1]);
    Serial.println(" usec");

  if (LP < lp++) {
    lp = 0;
    c++;
  }

  // ループ1回は100msecにおさめる
  long start = millis();
  while ((millis() - start) < 100) {

    // 次に反転するのは何秒後かを求める
    long min = 10000;
    for (int i = 0; i < 2; i++) {
      long d = numfreq[i] - x[i].delay;
      if (d < min) {
        min = d;
      }
    }

    // 求めた秒数待つ
    delayMicroseconds(min);

    // 半周期に達していれば反転する
    for (int i = 0; i < 2; i++) {
      x[i].delay += min;
      if (x[i].delay == numfreq[i]) {
        digitalWrite(Pin[i], x[i].highlow ? HIGH : LOW);
        x[i].delay = 0;
        x[i].highlow = !x[i].highlow;
      }
    }

  }
}

稼働テスト

シリアルモニタから、電話番号を入力して下さい。1数字あたり 200msec の間、音が出ます。
電話の発話口に圧電ブザーを近づければ、電話がかかるはずです。(と思っている。)

1Hz / 2Hz で LED点灯 を試す場合は、スケッチの以下の部分を入れ替えて、シリアルモニタから「XXX」を入力して下さい。

  const int LP =  2; // 100 msec x  2回
//const int LP = 40; // 100 msec x 40回 (LED)

まとめ

実験が成功しなくて、とても、残念です。
自宅の電話が、外部からのトーン信号を受け付けないのかもしれません。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4