obniz.jsのデバッグ手法

obniz.jsを使っていてエラーとなった場合、どのように対処するのかについて。

発生する可能性のある箇所

obnizをREST/WebSocket APIから使用している場合のエラーは比較的分かりやすいですが、SDKとなるとエラー箇所が分散するため非常にわかりにくくなります。
ここではどんな種類のエラーがあり、どう調べていけばよいのかを記載します。

まず、obniz.jsを使用している際に遭遇する主なエラーは以下となります。

  1. JavaScriptの構文エラー
  2. JavaScriptの実行時エラー
  3. WebSocket接続に関するエラー
  4. パーツライブラリ内のエラー
  5. ペリフェラルに関するエラー
  6. jsonフォーマットエラー
  7. obnizのハードウェア内でのエラー

それぞれについて見てみましょう。

1. 構文エラー

構文エラーとはobniz.jsとは関係なく、JavaScriptのプログラムの文章自体が間違っているときに起きます。
例えば

var obniz = new Obniz('OBNIZ_ID_HERE');
obniz.onconnect = async function(){

}

としたいときに、間違ってasynca syncのようにしてしまった場合が構文エラーです。

var obniz = new Obniz('OBNIZ_ID_HERE');
obniz.onconnect = a sync function(){

}

このようなエラーが起こると、例えばobnizのプログラム画面ではこのようなエラーとなります。

SyntaxErrorであるというエラーの種類と、どの行でエラーが起きているのか(line:21のところです)が表示されています。

ブラウザのインスペクタやNode.jsのコンソールでも全く同じ内容のエラーを確認できます。

このエラーの内容と何行目なのかという情報を使えば、間違ってる場所を見つけて直していくことができます。
プログラム画面の場合は左側に行番号がありますので、そちらが参考になります。

実行時エラー

実行時エラーとは「プログラムとしては一見間違ってないけど、実行できないもの」というエラーです。
プログラムとして合っていれば、動きそうですよね。
でも、「右手で北海道を持ち上げる」というのが日本語として間違ってなくても、実行不可能なのと同じように、プログラムも文章としてあっていても、いざ実行するときに「それ無理でしょ」と問題となることがあります。

この種類のエラーはプログラムを動かしてもすぐに発生しないことがあります。
いざ、それをやろうとしたときに初めてエラーとなるからです。

例えば、以下のように存在しない関数obniz.FlyMeToTheMoon()をobnizとつながった1秒後に呼び出すようにします。

var obniz = new Obniz('OBNIZ_ID_HERE');
obniz.onconnect = async function(){
  setTimeout(function(){
    obniz.FlyMeToTheMoon();
  }, 1000);
}

obnizにこの関数があるのかどうかはいざ実行するまでわかりません。なので普通に動作して、obnizとの接続までは問題なく進みます。
しかし1秒後にいざ呼び出したときにそんな関数ないよというエラーが発生します。

こちらも行番号がわかることが多いので、それを元に修正していきます。

WebSocket接続に関するエラー

obniz.jsではWebSocketを使ってobnizクラウドと接続してobnizを操作します。
その際にインターネットが存在しないなどでエラーとなることがあります。
またはobniz idを間違えていて、接続できない場合。
または、obniz idは合っているけれども、アクセストークンが設定されているobnizで、そのトークンが間違っている場合。

これらはまず接続が行えないためエラーとなります。
Node.jsのコンソールやブラウザのインスペクタでは分かりやすいエラーが表示されますが、
プログラム画面のコンソール部分には何もでないことがあります。

本当にそのobnizがオンラインなのか、アクセストークンは合っているのかなどの確認が必要となります。

パーツライブラリ内のエラー

obniz.jsの提供するパーツライブラリの中でエラーとなることがあります。

例えば、ArduCamというカメラモジュールの関数にsetMode()というのがあります。

setMode(mode) {
  const modes = {
    MCU2LCD: 0x00,
    CAM2LCD: 0x01,
    LCD2MCU: 0x02,
  };
  if (typeof modes[mode] !== 'number') {
    throw new Error('unknown mode. options are ' + modes);
  }
  this.spi_write_reg(this.regs.ARDUCHIP_MODE, modes[mode]);
}

3種類以外の指定できないものが来た場合にエラーとなるようになっています。

setMode("MCU2LCD")はOKですが、setMode("MMM2UUU")などは存在しないのでエラーです。

このエラーは実行時エラーですが、自分が書いたプログラムじゃない場所で起きたエラーなのでどこで起きたのかが少しわかりにくくなります。

実際に、わざと間違えてみますと

var obniz = new Obniz('OBNIZ_ID_HERE');
obniz.onconnect = async function(){
  var cam = obniz.wired("ArduCAMMini", { cs:0, mosi:1, miso:2, sclk:3, gnd:4, vcc:5, sda:6, scl:7 });
  cam.setMode('MMM2UUU');
}

このようなエラーとなります、

obniz.jsの18518行でエラーが起きたことが分かります。
obniz.jsのブラウザ版は1つのobniz.jsというJavaScriptファイルにまとめられるようになっているので、かなり長いプログラムです。

その中身はここから確認できます。
バージョンによって違いますが、これはv1.10.0のobniz.jsです。

https://github.com/obniz/obniz/blob/v1.10.0/obniz.js

この中から18518行を探して何がいけなかったのかを調べることになります。

ただ、もしあなたがPCのブラウザもしくはNode.jsで使っている場合はもっと分かりやすいエラーとなります。

ブラウザのインスペクタの場合は(Node.jsもほぼ同じです)このようなエラーとなります。

同じようにobniz.jsの18518でエラーとなったと出ています。
しかし、そこに行くためにprogram.htmlの23行から移動したということが分かりますし、18518行というのが、関数名がsetMode()という関数の中にあるということまで分かります。

このようにどこで関数が呼ばれて、その中から次にどこに行ってというのが追えるようになっています。
ちなみにprogram.htmlの23行目は

cam.setMode('MMM2UUU');

ですので、これが悪い可能性が高いとわかります。

これはArduCamライブラリですので、このライブラリのドキュメントをもう一度確認したり

https://github.com/obniz/obniz/tree/v1.10.0/parts/Camera/ArduCAMMini

ライブラリのプログラムを実際に確認して問題を解決する必要があります。
もちろんこのプログラムがまとめられて1つのobniz.jsになっているので、obniz.jsだけ見ればいいのですが、何しろ長いのでパーツの中で問題になっていることがわかったなら、パーツだけ確認するのが良いです。

https://github.com/obniz/obniz/blob/v1.10.0/parts/Camera/ArduCAMMini/index.js

ペリフェラルに関するエラー

上記とほぼ同じですが、obnizのioやspiなどで発生するエラーがあります。
例えばobnizのioは0~11ですが、存在しないio200を指定してi2cを開始しようとするとエラーとなります。

obniz.i2c0.start({mode:"master", sda:200, scl:3, clock:400000}); 

この場合もライブラリのときと同じくobniz.jsの10960行目で問題が起きたというエラーが出ます。
追跡方法もライブラリの場合と同じです。

自分で意図的にioやspiを使っていなくても、ライブラリの中で使っているspiなどがエラーとなることがありますが、その場合も同じように追跡していくことで直すことができます。

jsonフォーマットエラー

obniz.jsはjsonをWebSocketでやりとりすることでobnizを操作します。
なので、内部で呼ばれた関数を元にjsonを生成しています。
たとえばio0をONにするために呼ぶこれは

obniz.io0.output(true)

内部でこういうjsonを作りWebSocketで送信します。

{"io0": true}

obniz.jsでは可能な限りjsonにする前に「それはできない」というものをエラーとして出力しますが、全てカバーできているわけではありません。obniz.jsとしてjsonを作ったもののいざそれを送信したらエラーとなった。ということが起こりえます。

例えば、現在obnizはSPIでの一回の送信は1024byteまでしか受け付けません。
それ以上となるとエラーになりますが、これはjsonのフォーマットエラーになります。

obniz.spi0.start({mode:"master", clk:0, mosi:1, miso:2, frequency:1000000}); 
let array = [];
for (let i=0; i<1025; i++) {
  array.push(0);
}
var ret = await obniz.spi0.writeWait(array);

これを実行するとこのようなエラーとなります。

このようなエラーが出た場合プログラム画面ですとエラーの内容はわかっても行番号を取得することができません。
Node.jsのコンソールやブラウザのインスペクタであれば以下のように何行目が悪かったのかを知ることができます。
ただし、場合によっては行番号が表示されないこともあります。その場合はエラーの内容から追跡する必要があります。

そして何がエラーだったのかはこのようなメッセージになっています。これはプログラム画面のコンソールでも確認できます。

[spi0.data] Array is too long(1025), maximum 1024

とエラーにあります。
これは、「spi0のdataがエラーで原因は最大1024までなのに1025送ってますよ」という内容のエラーです。

自分でobnizのspiを使っている場合はどこが悪かったのか探しやすいですが、パーツライブラリを使っていて、その中で実はspiを使っていた場合などは気づきにくくなります。
可能な限りこのタイプのエラーが出ないようobniz.jsを開発しておりますが、遭遇された場合はエラーの内容とパーツライブラリなどのソースコードの中身を元に追跡する必要があります。

obnizのハードウェア内でのエラー

プログラムが正しくjsonとしても正しく、obnizのハードウェアまで届いたのにエラーとなることがあります。
よくあるのはこのような例です

  • 過電流検知された
  • 電源電圧が下がりすぎた
  • I2Cの通信先が見つからない。

このような場合、プログラム自体に問題はないことが多く、回路に問題があることが多いです。

原因の調べ方は今までより難しくなります。過電流検知のように、プログラムの行と関係なくエラーが起きるものがあるので、エラーの中身を読んでそれを元に調べていく必要があります。

例えば、以下のエラーはio0が過電流検知してoutputが停止されたというエラーなので、io0の接続が疑わしいです。どこかでショートしていないか、間違えて配線していないかなど調べる必要があります。

このようにほとんど場合、英語ですが理解できる文章のエラーとなります。
しかし、場合によっては、このような文章化されていないエラーがobnizから届くことがあります。

本来文章化されたエラーが出るべきなのですが、未対応なエラーが発生するとこのように数字のみのエラーが届きます。
そのような場合は迷わずフォーラムのTechnical Supportにご連絡ください。

https://forum.obniz.io/category/8/question-and-troubles





You will Get in Few Days

Circuit for Starter “obniz Board” is available on Amazon and other online stores.
You can get it at below

Our products and resellers

Forum

Visit our developer’s forum to discuss and discover technologies.

Forum

Contact

Feel free to contact out support and technical team.

Contact us