ArduinoJsonとaJsonをESP8266で使う際の比較

インターネットから情報を取ってきてESP8266で処理しようとすると、データ構造が比較的シンプルなJSON形式は便利です。
以前も、為替情報をJSONで取得して表示させてみました。

ESP8266版Arduinoでネットから情報を取ってきてLCDに表示する: 楽しくやろう。

ただ、比較的大きなデータになる場合もあり、マイコンで安定して扱えるわけではないようです。

オープンソースで公開されていてArduinoで利用実績があるJSONのパーサとしては、以前使用したArduinoJsonや、同様にArduinoで使えるJSONライブラリのaJsonがあります。

両方とも使ってみましたが、

・ArduinoJson 小さなデータに対しては割と安定している。APIも分かりやすい。
・aJson 大きなデータでも比較的安定しているが、イレギュラーなデータにはちょっと弱い。

という印象になりました。
その比較をメモ代わりに記事にしておきます。

なお最初にお断りしておきますが、これらのライブラリが動作しない場合でも、ライブラリ自体に問題があるのか、ライブラリが呼び出しているESP8266用Arduinoのライブラリ側に問題があるのかは分かりません。
Arduino IDEはデバッガが全く利用できないので、原因を追いかけられないのが歯がゆいところです。

テストとしては、4つのJSONデータを上記の2つのパーサで解析できるか試してみました。
その結果をまとめると、以下のような星取り表になります。

TEST1 TEST2 TEST3 TEST4
ArduinoJson OK OK NG NG
aJson OK NG OK OK

ArduinoJsonは今月最新版の5.0がリリースされたところですが、この記事では4.0を使っています。
aJsonのほうはバージョン1.0を使っています。

使ったテストデータは以下の通りです。
TEST3とTEST4は、JSONのページサンプルから取ってきています。

TEST1 {“obj1″:”abc”}
TEST2 {“obj1”:{}, “obj2”:[{}], “obj3”:null}
TEST3 {“glossary”: {“title”: “example glossary”,”GlossDiv”: {“title”: “S”,”GlossList”: {“GlossEntry”: {“ID”: “SGML”,”SortAs”: “SGML”,”GlossTerm”: “Standard Generalized Markup Language”,”Acronym”: “SGML”,”Abbrev”: “ISO 8879:1986″,”GlossDef”: {“para”: “A meta-markup language, used to create markup languages such as DocBook.”,”GlossSeeAlso”: [“GML”, “XML”]},”GlossSee”: “markup”}}}}}
TEST4 {“widget”: {“debug”: “on”,”window”: {“title”: “Sample Konfabulator Widget”,”name”: “main_window”,”width”: 500,”height”: 500 },”image”: {“src”: “Images/Sun.png”,”name”: “sun1″,”hOffset”: 250,”vOffset”: 250,”alignment”: “center” },”text”: {“data”: “Click Here”,”size”: 36,”style”: “bold”,”name”: “text1″,”hOffset”: 250,”vOffset”: 100,”alignment”: “center”,”onMouseUp”: “sun1.opacity = (sun1.opacity / 100) * 90;” }}}

JSONデータ自体が正しいフォーマットになっているかどうかは、以下のリンクのようなオンラインのJSONパーサで確認できます。

Json Parser Online

使用したスケッチファイルも一応掲載しておきます。
4つのテストの1つしか実行しないようになっていますので、

#define JSON_TEST_DATA TEST1

のところを適宜変更してください。
また、ArduinoJsonのテストが失敗してハングアップすると、aJsonのテストは実行されません。
これも、適宜コメントアウトするなどの対処が必要です。

#include <ArduinoJson.h>
#include <aJSON.h>

#define TEST1 "{\"obj1\":\"abc\"}"
#define TEST2 "{\"obj1\":{}, \"obj2\":[{}], \"obj3\":null}"
//TEST3, TEST4 derived from http://json.org/example.html
#define TEST3 "{\"glossary\": {\"title\": \"example glossary\",\"GlossDiv\": {\"title\": \"S\",\"GlossList\": {\"GlossEntry\": {\"ID\": \"SGML\",\"SortAs\": \"SGML\",\"GlossTerm\": \"Standard Generalized Markup Language\",\"Acronym\": \"SGML\",\"Abbrev\": \"ISO 8879:1986\",\"GlossDef\": {\"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\"GlossSeeAlso\": [\"GML\", \"XML\"]},\"GlossSee\": \"markup\"}}}}}"
#define TEST4 "{\"widget\": {\"debug\": \"on\",\"window\": {\"title\": \"Sample Konfabulator Widget\",\"name\": \"main_window\",\"width\": 500,\"height\": 500    },\"image\": {\"src\": \"Images/Sun.png\",\"name\": \"sun1\",\"hOffset\": 250,\"vOffset\": 250,\"alignment\": \"center\"    },\"text\": {\"data\": \"Click Here\",\"size\": 36,\"style\": \"bold\",\"name\": \"text1\",\"hOffset\": 250,\"vOffset\": 100,\"alignment\": \"center\",\"onMouseUp\": \"sun1.opacity = (sun1.opacity / 100) * 90;\"    }}} "

#define JSON_TEST_DATA TEST1

void test_arduinojson(){
 char json[] = JSON_TEST_DATA;
 StaticJsonBuffer<4000> jsonBuffer;

 JsonObject& root = jsonBuffer.parseObject(json);
 if (!root.success()) {
   Serial.println("parseObject() failed");
   return;
 }
 root.printTo(Serial);
}

void test_ajson() {
 char json[] = JSON_TEST_DATA;

 aJsonObject* root = aJson.parse(json);
 if (root == NULL) {
   Serial.println("aJson.parse() failed");
   return;
 }
 Serial.println(aJson.print(root));
}

void setup() {
 Serial.begin(115200);
 Serial.println("");
 Serial.println(String("Test data: ")+JSON_TEST_DATA);

 Serial.println("\n\ntesting ArduinoJson\n");
 test_arduinojson();

 Serial.println("\n\ntesting aJson\n");
 test_ajson();
}

void loop() {
 // put your main code here, to run repeatedly:
 delay(100);
}

実行にはArduinoJsonとaJsonの2つのライブラリが必要です。
ArduinoJsonは以下、

bblanchon/ArduinoJson

aJsonは以下

interactive-matter/aJson

からダウンロードできます。
また、aJsonの使い方の解説は以下にあります。

aJson – Handle JSON with Arduino — Interactive Matter Lab

なお、aJsonはコンパイル時にlibm.aのリンクエラーが発生しました。
これは現在のESP8266用Arduino環境の不具合のようで、以下に解決策が出ていました。

Stable version libm.a compilation error · Issue #612 · esp8266/Arduino

https://files.gitter.im/esp8266/Arduino/Abqa/libm.a.tbzをダウンロードして、解凍して得られるlibm.aを元のlibm.aと置き換えれば修復できます。

libm.aの入っているフォルダは、

%USERPROFILE%\AppData\Roaming\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9\xtensa-lx106-elf\lib

になります。

コメント