Hatena::ブログ(Diary)

Okiraku Programming このページをアンテナに追加 RSSフィード

2010-08-22 SoftModemインターフェースボードとJavaScriptで通信

SoftModemインターフェースボードとJavaScriptで通信

SoftModemインターフェースボードを購入したので、遊んでみました。

f:id:NeoCat:20100821212503j:image:w250


スイッチサイエンスさんでほぼ完成状態で販売されています(ピンヘッダ付けるだけ)。

スイッチサイエンス/商品詳細 SoftModemインターフェースボード--販売終了


SoftModemインターフェースボードが使っている通信方式(FSK)は作者のarmsさんのブログで説明されています。

なんでも作っちゃう、かも。 SoftModemインターフェースボード発売!

なんでも作っちゃう、かも。 Arduinoで遊ぼう - iPhoneのオーディオ端子を使って通信をする

iPhone用のソース ( FSKSerialGenerator.m )を眺めてみたところ、通信方式仕様

  • High(1)は7350Hz, Low(0)は4900Hzのsin波を送る。これを1225baudで切り替える。
  • 1文字(8bit)の前後にスタートビット(0)、ストップビット(1)を付けて、10bitで送る。
    • 要は送信したい文字をcとすると、(c<<1)|0x200 を送る感じ。
  • 一連の文字列の送信の前に、40msのHighをプリアンプルとして送る。(1225baudだと49bit分)
  • 一連の文字列の送信後には、5msのHighをプリアンプルとして送る。(1225baudだと6.125bit分)

という感じらしいと分かったので、自分でも実装してみたくなって作ってみました*1


Cでも何でも良いんですが、JavaScriptから音が鳴らせたらBookmarklet等と組み合わせて面白いことができないかなーなどと妄想したので、JavaScriptで。

# 本当はiPhone等のブラウザで動かしたかったのですが、後述の方法はMac/PCブラウザでは動くものの、iPhoneSafariでは動作しないことが後で判明。。ちょっと残念。

## あと受信はできません…。


作ったコードgithubにアップしてあります。

http://github.com/NeoCat/FSK-Serial-Generator-in-JavaScript/

.htmlファイルHTML5対応ブラウザで開いて、"Generate and Play"ボタンを押すと音が鳴ります。これをSoftModemインターフェースボードに3.5mmステレオ4極ケーブルで繋いで流せば、文字列を送信できます。

Jumpを押すと、生成したサウンドを直接ブラウザで開きます。ここでSaveすれば生成した.wavファイルとして保存できるはずです。


JavaScriptから音を鳴らす方法としては、Data URI Schemeを使った方法があります。Data URIを利用すると、画像などのバイナリJavaScriptで生成することができます。今回の場合は、WAV形式のサウンドデータを生成します。


WAVフォーマット情報としては下記が参考になります。

wav ファイルフォーマット


詳しくはスクリプトを見て頂くとして、まずは8bit/monoリニアオーディオ形式のヘッダを作ります。サンプリング周波数は生成するバイナリのサイズを小さくするため上記High/Lowがぎりぎり表現できる29400Hzを選びましたが、44100Hzでも大して変わらなかったかも。あとは、指定されたテキストASCIIコード表現するFSK変調したsin波を8bitのバイナリ(つまり0〜255)で表現していきます。

なお、テキストとしてnon-ASCIIな文字が指定された場合は、UTF-8エンコードしています。(こういう操作もJavaScriptでは関数一発ではできず、自前でバイナリとしてごりごり変換しています)


WAVデータができあがったら、それをbtoa関数MIMEエンコード & escapeし、前に

data:audio/wav;base64,

という文字列をくっつければ、Data URIのできあがりです。

あとはHTML5のAudioオブジェクトにこのData URIを指定して

	audio = new Audio(dataURI);
	audio.play();

再生できます。


生成した波形をwavとして保存してspwaveで開いてみたところ。2種類の周波数があるのが分かります。

f:id:NeoCat:20100822232103p:image:w332

そういえば、iPhoneアプリの「音響電文」とも通信できるみたいです(通信といっても一方向だけですが)。JavaScriptだけじゃ録音できない(多分)から受信は難しいだろうなあ。

*1:実際にはSoftModemインターフェースボードが届く前に書いたのですが、一発で動いてしまって自分でびっくり。FSKって簡単ですね〜。

micono2567micono2567 2011/10/13 09:29 miconoといいます
softmodem.hでいろいろなボーレートの設定ができるようになっていますが、fsk-gen.htmlの中の数値を変更させて、やってみたんですが、どこかが間違っているようです。1225bps以外の設定に変更したい場合、例えば315bpsにしたい場合、どう書き換えればいいのか教えて頂けますでしょうか?

NeoCatNeoCat 2011/10/13 23:07 var spb = sampleRate/baud という部分が整数になる必要があります。
baud = 315だと割り切れないため、
var spb = Math.ceil(sampleRate/baud)
にする等が必要です。

micono2567micono2567 2011/10/14 15:20 ありがとうございます。
いまiPhone4s受け取り待ちで、今晩やってみたいと思います。

micono2567micono2567 2011/10/17 23:51 やってみましたが、100,126,600,1225はうまくいきましたが、315,630,2450はうまくいきませんでした。他に変更しなくてはいけない部分があるんでしょうかね?

NeoCatNeoCat 2011/10/18 00:40 うーん、そうですか。他に考えられるのは、sampleRateを割り切れる周波数にしてみるとかでしょうか。(多少波形がきれいになるとは思いますが、関係ないかも(汗))
例えばbaud = 315なら、freqHigh = 3150, freqLow = 1575 かと思いますが、
3150の整数倍、例えば sampleRate = 12600 にしてみるなどです。外してるかもしれませんが…。

micono2567micono2567 2011/10/19 23:28 こんばんは。Hiの整数倍にすると上手くいくようになりました。ありがとうございました。
ところで、ひとつ疑問なんですが、600baudと1225baudのHi/Lowは何故hiの半分がlowになってないのでしょうか?

micono2567micono2567 2011/10/19 23:32 立て続けにもうしわけありません。よく考えたらbaudとHi/Lowとの関係も理解できていませんでした(汗)baudrateからHi/Lowの値は算出するための何らかの関係があるのでしょうか?

NeoCatNeoCat 2011/10/20 00:02 まあHi/Loは十分差があれば何でもよいと思います。なので315baud辺りでは単に切りの良い5倍/10倍にしていたのではないかと。
ただ周波数が上がってくると、オーディオ端子の特性やマイコンの性能などの問題で扱いづらくなってくるので、あまりに高い周波数にならないよう比率を少し下げて調整してあるのだと思います。

micono2567micono2567 2011/10/20 17:32 ありがとうございます。何となく理解できました。実際に600baudのHi=4000, Low=2666ですが、Lowを2000にした方が認識度が上がった感じでした。
話はちょと変わりますが、fsk-gen.htmlを参考にさせて頂いて、wavファイルを保存するアプリをREALstudioで作ったんですが、ネット上で公開しても問題ないでしょうか?

NeoCatNeoCat 2011/10/20 23:28 公開は全く問題ないです。ぜひ公開してください。

micono2567micono2567 2011/10/21 11:14 ありがとうございます。公開しました。
http://micono.cocolog-nifty.com/blog/softmodem
です。

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。

トラックバック - http://d.hatena.ne.jp/NeoCat/20100822/1282486171