マイコン工作実験日記

Microcontroller を用いての工作、実験記録

DTMFを拾ってみる

2015-12-27 19:39:47 | SLIC
DACを使ってのダイアルトーンやモデム信号の生成はできるたので、今度はADCの番です。音声受信の前段階として、まずは電話機からのDTMF信号を拾ってみます。Ag1171sのVout出力はSTM32L476のPA3につなげているので、ADC2_IN8でこれを受けます。ADCにはオーバサンプリング機能が用意されているようなので、これを使ってみようということで次の設定を用意。



8倍のクロックでサンプリングしたものを8で割って平均を取った値をサンプル値とします。クロックはTIM6を使って64KHzを生成してこれをトリガとしてADCに変換を開始させます。結果として8KHzでのサンプリング値が得られます。



変換結果はDMAを使ってメモリに転送。DACと同じくサーキュラーモードを使って、バッファの半分の転送が終わったところで割り込みをかけてDTMF検出処理を動かします。

DTMF検出については、Keilのサイトにとても良いサンプルコードがあったので、これをそのまま流用することにしました。Keilのツールとともに使うことが使用許諾条件になっているので、これには違反しているんですが。。。このコード、STM32用と題してあり8KHzサンプリングされたADCデータ(12ビット右詰め)を処理することが前提となっていますが、信号処理部分は大きくハードに依存しているわけでもないので、異なるMCUを使う場合でも簡単に移植できるでしょう。



何の問題もなくあっさりとDTMF検出が動きました。

ナンバーディスプレイ信号を生成する -- モデム信号編

2015-12-19 10:48:59 | SLIC
シーケンス全体の制御は容易でしたので、肝心かなめのモデム信号部分の生成です。モデム信号はV.23 1200bpsに準拠していますが、発信者番号情報を電話機に対して送信すれば良いだけであり、受信処理はありません。また変調方式はV.23 1200bpsの固定となっていますので、ネゴの手順も必要ありません。FSK(周波数変調)と言ってもデジタル信号の変調ですので、送信するデータの内容に応じて bit 0を2100Hz, bit 1を1300Hzの周波数で送出すれば良いだけということになります。

送信すべきデータの内容はNTTが公開している技術参考資料で説明されています。以下のフォーマットはその資料からの引用です。



60ms以上のマークビットに続いて、定められたフォーマットで発信者番号を送出してやる必要があります。この図ではビット送出順序も表現されており、情報データ部分の各オクテットは最下位のb1から送出することになっていますが、最後の2オクテット(16bit)のCRC部分については最上位ビットから送出することになっています。また、bpはパリティビットを示していますので、データ部分については偶数パリティを付けて、最下位ビットから送出してやる必要があります。



データ部分ならびにCRCの各オクテットは上図のようにスタートビットとストップビットをつける必要が有ります。つまりはUARTで送信するのと同じように送信せよということですね。UARTの出力を使って変調をかけることを意識しての設計になっているのでしょうか。しかし、今回はDACでの出力が必要ですので、ソフトウェアでデータビットに対応した周波数の相当のDACに出力すべきデータ列を生成してやります。

CRC部分についてはSTM32L476にCRC演算機能が備わっているので、これを使ってみることにしました。STM32CubeMXでの設定は次のとおり。生成多項式の係数を指定できるようになっています。X16の項はお約束の部分なので省略して指定するようです。



生成するモデム信号は1200bpsですので、24KHzでサンプリングした場合には1ビット分に相当するサンプル数は24000/1200 = 20サンプルとなります。スタート/ストップを含めると元データの1バイトの送出には10ビットが必要ですので、 200サンプル(400バイト)分のDAC出力信号に展開してやり出力すればいいことになります。マークビットの長さも、これに合わせて10ビットの倍数である80ビットを選択。これで66ms相当の信号となり、NTTの定める仕様(60ms以上)を満足することができます。




こうして生成した出力サンプルデータをDMAを使ってDACへ送信してやると、Ag1171sを介して電話機にモデム信号が出力されて、めでたく電話機に数字を表示することができました。




上図に実際のシーケンス全体の信号の様子を示します。試験プログラムでは、呼び出し信号に応答(オフフック)後にダイアルトーンを送出しています。モデム信号が送出される前にはオフフックしていますので、ナンバーディスプレイに対応していない電話機(あるいは設定でナンバーディスプレイ機能を無効に設定した電話機)を接続すれば、実際に流れるモデム信号を耳で聞くこともできます。




モデム信号部分を拡大してみました。左1/3くらいはマークビットの部分です。ビット1が連続しているので、1300Hzの波形が続いています。その後ろがDLEから始まる実際の信号部分の頭の部分です。頑張れば目視によるデコードもできるかも?

低くなった壁

2015-12-16 12:02:44 | Weblog
いつの間にかMouserの送料無料が、6000円以上の注文になっています。これもMouser Japanができたおかげでしょうか。でも、いまはすぐに欲しいものはないんだよなぁ。現在進行中のプロジェクトをもう少しちゃんと進めないと。

さて、作業中のナンバーディスプレイはすでに動いてはいるのですが、写真をとって記事にまとめる時間がとれないでいます。次の週末にでもアップするつもりでいます。

ナンバーディスプレイ信号を生成する -- シーケンス編

2015-12-09 21:31:04 | SLIC
Ag1171sを使っての電話機接続も、フック検出から始まって、着信音とダイアルトーンの生成までできました。ここで、ちょっと寄り道して、ナンバーディスプレイ信号を生成する実験をすることにします。生成できるトーンの周波数を2つ追加して、これまで組んできた処理を組み合わせてやれば、ナンバーディスプレイに必要な信号を生成できるからです。



まずはNTTの技術参考資料から上図に示したナンバーディスプレイのシーケンスを確認しておきましょう。ぎょうぎょうしいNTT用語が並んでいますが、情報受信端末信号は普通の着信鳴動と長さが違う呼び出し信号にすぎませんし、応答信号と受信完了信号は、それぞれオフフックとオンフックのことを示しているにすぎません。これらをAg1171sの信号名とその変化に読み替えてやれば、下図のようになります。



呼び出し信号のケーデンスを変更してやるだけで情報受信端末起動信号は生成できますので、追加でMODEM信号を生成して発信者番号情報を送ってやれば、ナンバーディスプレイ対応の電話機に表示ができることになります。ナンバーディスプレイで使われるモデム信号はV23の1200bpsと定められています。V23はFSK変調で送信データを変調して送信しますが、デジタル信号の変調ですので送信データのビット0に対して2100Hz, ビット1に対応して1300Hzのトーンを必要な長さだけ生成してやれば良いだけということになります。したがって、STM32のDACを使って簡単に生成することができます。

ダイアルトーンの生成

2015-12-06 11:27:53 | SLIC
Ag1171sを使った電話機とのインタフェース。着信音生成の次はダイアルトーンの生成です。オフフックしたら、400Hzのダイアルトーンを送出することにします。今後幾つかの周波数の信号を生成することを考えているので、sinのテーブルを用意しておき、それを参照して必要な周波数の信号を生成してDACに送ることにします。sinテーブルなんて自分で作ってもいいんですが、CMSIS-DSPに含まれているだろうと思い確認したところsinTable_q15があったので、これを使うことにしました。

サンプリングは24KHzで行うこととし、STM32L476のTIM7を使ってタイミング生成。DAC1のトリガーソースとしてTIM7のトリガーイベントを選択して、DMAで送信することにしました。400サンプル分のバッファを用意しておき、これをダブルバッファリングで使用。半分のデータを送信している間に、残りの半分のバッファに次に送信すべきデータを準備してやります。基本的なドライバのコードはSTM32CubeMXを使って生成しています。





DMAにCircular modeというのがあることを知ったので、これを使うことにしました。一度、DMAを開始すると繰り返し同じバッファからのDMA送信をおこなってくれます。バッファの半分まで送信が終わった時点と全ての送信が終わった時点で割り込みがかかってコールバックが呼ばれるので、そのタイミングで送信が終了したバッファに次の送信データを用意してやることで、繰り返し400Hzの波形を出力してやります。

sinTable_q15のデータは符号付の16bitデータです。そのため、このデータを直接DACに出力しても正しい波形にはなりません。0x8000~0xffffの値は負の値ですが、このままDACに送ってしまうと、逆に出力電圧が高くなってしまいます。そこで、0x8000とXORをとって符号を反転しておきます。STM32のDACは12bitなので16bitデータを4bitシフトしてやる必要がありますが、DACへの書き込み時に左詰め/右詰めしてくれる機能があるので、この機能を使えばソフトでは4bitのシフト処理は不要となります。CubeMXの設定を探しても左詰め/右詰め指定の設定をする箇所がないので戸惑いましたが、この指定はHALのAPIを呼び出す際に指定する仕様になっています。今回は左詰めを指定。符号を反転させた波形データはフルスイングした信号となっていますので、音声として再生すると音が大きすぎます。2bit右シフトして出力してやると丁度加減が良いようです。


ダイアルトーンの生成が確認できたので、次は異なる周波数も生成する実験をやってみるべく作業中です。

巻けないことはない

2015-12-02 14:26:43 | Weblog


SilabsのBlogを見ていたら、Thunderboard Wearなるスマートウオッチの参照デザインのようなボードがありました。この間のARM TechConでデモしていたらしい。裏に心拍測定用のセンサーもついていて、もちろんBLEも載っています。ちょっと苦しいけど、腕に巻けないことはないという大きさでしょうか。値段も手頃そうです。少しでも自分で半田付けできる組み立てキットだったら最高なんですが。そこそこのデモが動いていると、自分でそれ以上のものを作ろうという意欲が萎えてしまい3日遊んでお蔵入りになるのが想像できるので、勢いでポチるのは止めておきます。