超音波通信ライブラリsonicnet.jsを使ってみた


超音波通信ライブラリsonicnet.jsを読み解く

超音波通信では人間に聞こえない帯域の音(18000~20000Hz)を通信に使っている
スピーカーとマイクさえあれば通信できる手軽さから局所的な通信方法として昔から注目されている

今回はjavascriptで超音波通信をやってみたいと思って調べてみるとsonicnet.jsというライブラリを発見した
Ultrasonic networking on the web
sonicnet.js(GitHub)
YouTube Preview Image

動画では超音波でテキストの通信などを実現している
とりあえず使ってみよう

試してみるにはローカルでWebサーバーを立ててブラウザで確認してみれば良い。
今回適当にapacheを使ったので/var/www/html以下にファイルを展開した。
またこのライブラリはweb audio apiやマイク入力のためにwebrtcなどを使用するため対応するブラウザ
でないと基本的に動かないことに注意してほしい。

実際にテキスト通信などを触ってみたが.. う〜ん思っていたより厳しい..
文字列送信は確かにできているのだがその正確性はかなり低い。
スピーカーの音量やマイクの入力、端末同士の距離などをかなり調整してやっと使えるレベル。
1バイト送るだけでも上手く行かないときがままあるという感じだった。
なんとか精度を上げる方法はないものか..そしてこのライブラリはどのような手法で超音波通信しているのだろう?

ライブラリの仕組み

libフォルダに入っている4つのjavascriptファイルが基本的な構成ライブラリらしい
以下ファイル名と大雑把な役割

ファイル名 役割
ring-buffer.js 円環配列
sonic-coder.js  周波数ー文字列,文字列ー周波数の変換
sonic-server.js  受信(超音波入力をうけて周波数解析)
sonic-socket.js 送信(超音波出力)

ring-buffer.js

リングバッファとは最も古い内容を最新の内容で上書きし、常に一定の過去までのデータを蓄えるような用途に用いられるデータ構造のこと
ターミナル上で実際にring-buffer.jsを読み込ませて実行させてみるとよい

sonic-coder.js

音の周波数と文字列の変換を行っている

charToFreq関数(文字から周波数へ変換する関数)の実装を読んで見る。
この関数は引数に1バイトの文字を取る。引数に与えた文字が文字列alphabet中の何番目の文字なのかを
indexOfメソッドを使って調べ変数indexに格納している。

次に使える周波数の帯域幅を調べる。この場合最大周波数19500Hzから最小周波数18500Hzを引いた1000が帯域幅であり変数
freqRangeに格納される.freqRangeを文字列の長さ(this.alphabet.length)で割り変数indexをかけることで引数に与えた文字の
文字列alphabet中での位置による割合から適当な周波数を求めることができる。

説明が分かり辛いと思うので例を上げると文字列alphabet=”abcde”だったと仮定すると文字a=18500-18700[Hz]、文字b=18700-18900[Hz]、
文字c=18900-19100[Hz]、文字d=19100-19300[Hz]、文字e=19300-19500[Hz]という具合に周波数帯域を分割しているだけの話である。
freqToChar関数は逆のことをやってるだけなので割愛、超音波通信ってもっと高度なアルゴリズムなのかと身構えていたらとてもシンプル
な実装だったので驚いた。

sonic-server.js

いくつか見てみる。
onメソッドでは文字列受信時のイベントハンドラを定義している。
onStream_メソッドではマイク入力を得て周波数ピークの解析を開始する。
loopメソッドは繰り返し呼びだされ円環配列に解析した文字と検出した時間を加えていく。

説明が雑なのはいまいち理解出来ていないということを察してほしい。

sonic-socket.js

sendメソッドで引数に与えられた文字列を周波数に変換して音を出力している。
実際に音を出力しているのはscheduleToneAtメソッドでAudioContextインターフェースを使って
引数に指定した周波数で音を出力している。
一文字に対応する周波数音を出力する時間をcharDuration(0.2/s)、次の周波数を出力し始めるまでの間隔時間をrampDuration(0.001/s)
として定義していることに注意したい。これらのパラメータを変えることで送信にかかる時間を短くしたり送受信の正確さを高めることが
可能になる。

sonicnet.jsを使ってアプリを作ってみる

そのうち投稿する()

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です