インターネットから情報を取ってきて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パーサで確認できます。
使用したスケッチファイルも一応掲載しておきます。
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は以下、
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
になります。
コメント