ピポパ音を解読するDTMFデコーダを作ってポケベル打ちに挑戦!



 「武蔵野電波のプロトタイパーズ」をご覧の皆様、初めまして。自称武蔵野電波見習いのゲヱセン上野と申します。「Arduinoスケッチが書ける」、「ポケベル打ち(ポケベル入力)ができる」という理由から、今回の記事を担当することになりました(とくに後者の理由が大きい(笑))。では、早速本題に入りましょう。

 今回製作するのは、DTMFレシーバ「CM8870PI」と「Arduino」を使った「ポケベル文字コード解読器」です。

 1968年にサービス開始し、2007年に終焉を迎えた「ポケットベル」(以下ポケベル)は、「端末に割り当てられた番号に電話がかかってくると、呼び出し音が鳴る」だけの、コンパクトな無線通信機器でした。呼び出された側が呼び出した相手と連絡を取り合うには、折り返し公衆電話等から電話をかける必要があります。ケータイが普及した今となっては、すさまじく原始的なモバイル端末といえましょう。

 ところが、ポケベルに液晶ディスプレイが搭載され、ショートメッセージを表示できるようになったことで、1990年代中盤女子高生を中心に大ブームを巻き起こします。ケータイがまだ高嶺の花だった時代、彼女らは公衆電話のテンキーを巧みに操り、電子メッセージを送信しまくっていたというわけです。

 ちなみに初期の液晶ディスプレイ搭載モデルは数字しか表示できず、「0840」(おはよう)、「14106」(あいしてる)のような語呂合わせを使ってメッセージを伝えていました。その後、アルファベット・カナ表示可能な端末が登場。「ポケベル入力」はそれと同時に誕生した入力方式です。

 さて、この「テンキーを叩いて文字を伝送する」仕組みを少し詳しく説明すると、「各文字に対応した2桁の数字を押す」→「DTMF音が送出される」→「センター側でDTMFをデコードし、データを端末に送信する」→「受信したデータに対応する文字を表示する」となります。ここで、2枚の資料を見てください。

ポケベル入力コード表。「1回目に押すボタン」「2回目に押すボタン」の順で2桁の数字を入力すると、該当する文字を送出できます。例えば「ム」を送出するなら、「7」「3」と押します
DTMFとはDual Tone Multi Frequencyの略。プッシュ式電話機のいわゆるピポパ音のことで、「周波数の異なる2種類の音」を合成したものなのです。A~Dにも割り当てがありますが、電話で用いられるのは「1~9」「*」「#」のみですね。チケット予約や宅配便再配達依頼などの自動電話応答サービスが利用できるようになったのも、DTMFのおかげです

 つまり、「テンキーを『1』『2』の順に押す」→「697Hzと1,209Hzの合成音、697Hzと1,336Hzの合成音が順に鳴る」→「イ」を送出、ということになります。

 「文字と数字の組み合わせを暗記するのは面倒くさい!」と思われそうですが、実はカナに限れば「子音」、「母音」の順にボタンを押しているに過ぎません。子音「アカサタナハマヤラワ」が「1234567890」に対応、母音「アイウエオ」が「12345」に対応していて、「リ」を打ちたいなら「9」(母音「ラ」)→「2」(子音「イ」)と押せばOK。アルファベットと数字を覚えるのがやや大変ですが、完璧にマスターすれば「カナ」モードと「英数」モードを切り替えることなく「カナ、数字、アルファベット」をすべて打てます。

 携帯電話には、入力方式を「2タッチ入力」(※1)にするとポケベル入力可能な機種が多いのですが、iPhoneやAndroid(※2)では利用できないんですよね。ぜひ、この便利な入力方式を、スマートフォンでも採用していただきたいものです。

※1:「2タッチ入力」では拗音、促音、読点、句点、小文字等が拡張されており、上記文字コード表とは文字割当が若干異なります。詳細は携帯電話のマニュアルを参照してください。
※2:Android用IME「Simeji」はポケベル入力に対応していますが、英数字や濁点、半濁点、読点、句読点等の文字コードが上記コード表や、携帯電話の2タッチ入力コードと異なります。

 では、ポケベル入力方式とDTMFについての理解が深まったところで、「ポケベル文字コード解読器」、つまり「ポケベル入力方式で送出されるDTMF音をデコードし、テキストに変換・表示する装置」の製作に取りかかります。まずは、ハードを組み上げていきましょう。

今回の主役その1「DTMFレシーバ CM8870PI」は、秋月電子通商で入手可能(2個300円)。OSC1-OSC2間に取りつけるセラミック発振子(3.58MHz)も付いています
CM8870周辺の回路構成はデータシートのとおりで、オーディオ出力を受け取る想定になっています。この回路図ではキャラクタLCDを省略しています。シールドを使わない場合は、過去の記事を参考にしてください
マイクアンプやスマートフォンなどをつなぎやすいよう、RCAジャックを用意しました。電源はArduinoから供給されます。CM8870は5Vで動作するので、Arduinoも標準的な5V仕様のもの(たとえばArduino Uno)が適しています。コンデンサは積層セラミック型を使用しました。5個のLEDは省略可能ですが、あると動作検証がしやすくなります
今回の主役その2。文字表示用のArduinoシールド「CLCD-PLUS」は、マイクロファンネットショップで入手可能です。16字×2行のLCDのほかに、4つのタクトスイッチやLED、コントラスト調整用の半固定ボリュームも見えます
CLCD-PLUSの基板裏面には圧電サウンダが実装されています。今回はここからBEEP音も鳴らしてみましょう
CLCD-PLUSにはArduino接続用端子の他に、ブレッドボード接続用の電源系・信号系端子が配置されています。電源系端子にピンソケットを取りつければ、Arduino側の5VとGNDを簡単に取り出すことが可能。今回はタクトスイッチに干渉しないようL型ピンソケット(6ピン)を使ってみました
DTMF音を拾うマイクには「2石マイクアンプキット」を使用しました。コンデンサーマイクもセットになっていて、6~12Vの電源さえ用意すればマイク入力をラインレベルに増幅できます。コンデンサーマイクの極性がわかりにくいときは、テスターでマイク外周-ピン間の導通をチェック。0Ωを示す端子がGNDです
「ポケベル入力コード解読器」ハードウェア完成図。CM8870PIのStDがArduino Digital3端子へ、CM8870PIのQ1~Q4がArduino Digital4~7端子へ接続されています

 ハードが完成したら次はArduinoスケッチの製作……ですが、下記のURLからダウンロードし、Arduino IDEにペーストすればOKです。

□Arduinoのスケッチ
http://www.musashinodenpa.com/arduino/lib/PB_CODE_decoder.pde

 なお、このスケッチを動作させるには、CLCD-PLUSを制御するためのライブラリが別途必要となります。マイクロファンネットショップCLCD-PLUS紹介ページで「ClcdPlus-0.95.zip」を入手し、展開したClcdPlusフォルダをそのままlibrariesフォルダの中へコピーしてください。librariesフォルダはスケッチが保存されているArduinoフォルダの中にありますが、ない場合は自分で作成する必要があります。

ダウンロードしたライブラリはlibrariesフォルダに保存します。Windowsの場合は「ユーザー名\マイ ドキュメント\Arduino\libraries」、Macintoshの場合は「ユーザー名/書類/Arduino/libraries」です。Arduino IDE起動後、メニューの「Sketch→Import Library」に「ClcdPlus」が追加されていれば、ClcdPlusライブラリを利用できる状態です

 本スケッチの主な動作ロジックをかいつまんで説明しておきましょう。

 CM8870PIのStD端子は、DTMF信号のデコード完了時にLからHへ変化し、デコードされたデータはQ1~Q4端子から読み出すことができます。

 そこで、本スケッチではStD出力(Arduino Digitel3に接続)の状態を監視し、L→Hへ変化したときの外部割り込み1を利用しました。割り込み発生時に実行される readDtmfData() の中では、Q1~Q4を読み出したあと……

【1回目のボタン入力時】
入力された値を記録→外字定義したカーソル(「_」)を表示→短いBEEP音を発生
【2回目のボタン入力時】
1回目、2回目に入力された値から、その値に該当する文字を表示→短いBEEP音を発生

 という処理を行ないます。ちなみに、2回目のボタン入力時の「ポケベルコードからLCDキャラクタコードへの変換」は、計算とテーブル参照を併用しています。LCDキャラクタコードの詳細を知りたい方は、SD1602HUOB(-XA-G-G)の参考資料を参照するとよいでしょう。

 ポケベル用絵文字(時計、電話、カップ、ハート)と、1回目のボタン入力時に表示するカーソル(「_」)は、初期化時にカスタムキャラクタ定義しています。今回は、CLCD-PLUSで使用できるカスタムキャラクタ0x00~0x0fのうち、0x01~0x05を使用しました。

 なぜ、0x00から定義しないのか……。0x00に定義したキャラクタを lcd.print(“文字列”) の中で使うと、0x00が文字列終端を意味するNULLと解釈され、以降の文字が表示されなくなるからです。lcd.print(0x00, BYTE) とすれば表示させることは可能ですが、このキャラクタのためだけに例外処理をするのも面倒なので0x01から定義した、というわけです。

 さあ、スケッチをコンパイルし、Arduinoへの書き込みが完了したら、動作確認を始めましょう!

DTMF音を発生させるトーンダイヤラ「SONY RM-A60」を用意しました。表面にテンキー、裏面にスピーカーが付いていて、テンキーをプッシュするとスピーカーからDTMF音が出ます。あらかじめ十数桁のボタンを押したあと「SEND」キーを押し、一気に送出することもできます
RM-A60の裏側です。受話器にフィットするスピーカが見えます

 トーンダイヤラを見たことがない、という人もいるかもしれませんね。これはありていに言えば、電話をかけるためのツールです。よくかける電話番号をメモリ登録しておき、固定電話や公衆電話の送話口にスピーカーを当ててDTMF音を送出すれば、その番号へ電話をかけることができるのです。もちろんテンキーを押してDTMF音を発生させることも可能。DTMF音が出せないダイヤル式電話機から、チケット電話予約をするときによく使ったものです。

  もっともこれも時代の産物。ダイヤル式電話機が姿を消し、携帯電話を1人1台(以上)持つようになった今、トーンダイヤラを見かけることはなくなりました。入手はかなり困難でしょう。……となると、読者の皆さんは動作確認できないことになりますが、心配ご無用。スマートフォン向けにリリースされているトーンダイヤラを使えばよいのです。iPhoneなら「DTMF Pad」、Androidなら「Phone Dialer Free」などが無償公開されているので、AppStore、Androidマーケットで検索してみてください。

Android用トーンダイヤラの一例「Phone Dialer Free」。スマートフォン版トーンダイヤラを使う場合、音量が小さすぎても、大きすぎてもうまく反応しないことがあります。また、端末とアプリの相性によってはDTMF音が不安定になることもあります。この場合、他のトーンダイヤラアプリを試してみるとよいでしょう。
【動画】2桁のポケベルコードを入力し、その値に対応する文字がLCDに表示されれば成功です。完成後はブレッドボード上の動作確認用LEDを外して問題ありませんが、点滅するさまが美しいので残しておいても構いません。ちなみに、ポケベル打ちに慣れた人は、ケータイで2タッチ入力をする際、両手親指を交互に使って高速にボタンを叩くのだそうです。私は頑張っても2文字/秒くらいが限界です
動画には登場していませんが、カスタムキャラクタ登録した絵文字もしっかり表示されます。右から時計、電話、カップ、ハートなのですが、カップがなぜポケベル絵文字に採用されたのか当時も今も疑問です。誰がどんなシチュエーションで使用したのでしょうか

 うまく動作しましたか? もしポケベル打ちのできる知人がいれば、電話越しにボタンを叩いてもらい、受話器から聞こえるDTMF音をデコードできるか試してみるのも一興ですよ。