2015年10月12日

ESP8266でJPEG画像をTFT LCDに表示する

esp826609.jpg

前回はSPIFFSの中に格納したBMPファイルを表示させましたが、JPEG、GIF、PNGなどのファイルも表示させたくなりますね。
調べてみたところ、これらの画像形式の中でESP8266で比較的扱いやすいのはJPEGのようです。

JPEG、GIF、PNGはいずれも圧縮アルゴリズムを使っていますが、GIFとPNGは辞書形式の圧縮符号化方式(GIFはLZW、PNGはZlib)を使っています。
このタイプの圧縮アルゴリズムは、辞書をRAM上に展開すると、比較的大きなワーキングメモリが必要になります。
一方、JPEGは計算量はGIFやPNGよりも大きい代わりに、ワーキングメモリはそれほど大きくないようです。
picojpegというメモリ消費の少ないデコーダ実装があり、これをArduino上で利用した例も見つかりました。

Arduino用JPEGデコーダ | 遊舎工房

今回は、上記のデコーダを使って前回同様にSPIFFS上に置いたJPEGファイルをLCDに表示させてみました。


まず、デコーダライブラリを下記からダウンロードしてArduino IDEに追加(スケッチ→Include Library→Add .ZIP Library...)します。

MakotoKurauchi/JPEGDecoder

このライブラリはSDカードでの利用が想定されていますので、SPIFFSで使うために、以下の部分をちょこっと変更します。
変更するファイルは「マイドキュメント\Arduino\Libraries\JPEGDecoder-master\JPEGDecoder.cpp」です。

修正前: #include <SD.h>
修正後: #include <FS.h>

修正前: g_pInFile = SD.open(pFilename, FILE_READ);
修正後: g_pInFile = SPIFFS.open(pFilename, "r");


スケッチ本体は以下のようになります。
もともとのライブラリに、デコード結果をシリアルポートに表示する分かりやすいサンプルがありましたので、シリアルポート出力の代わりにLCDに点を打つだけで動作させることができました。

SPIFFSの中に"test1.jpg"というファイルを入れておくと、それをST7735ベースのLCDに表示します。
ESP8266のSPIFFSへのファイル転送のやり方は以前の記事を参照してください。


#include <arduino.h>
#include <SPI.h>
#include <FS.h>
#include <JPEGDecoder.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library

#define TFT_CS     15
#define TFT_RST    5
#define TFT_DC     4

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);

void setup() {
 Serial.begin(115200);
 Serial.println("");
 delay(10);

 tft.initR(INITR_BLUETAB);
 tft.fillScreen(ST7735_BLACK);

 SPIFFS.begin();
 jpegDraw("/test1.jpg");
}

void jpegDraw(char* filename) {
 char str[100];
 uint8 *pImg;
 int x,y,bx,by;
 
 // Decoding start
 JpegDec.decode(filename,0);

 // Image Information
 Serial.print("Width     :");
 Serial.println(JpegDec.width);
 Serial.print("Height    :");
 Serial.println(JpegDec.height);
 Serial.print("Components:");
 Serial.println(JpegDec.comps);
 Serial.print("MCU / row :");
 Serial.println(JpegDec.MCUSPerRow);
 Serial.print("MCU / col :");
 Serial.println(JpegDec.MCUSPerCol);
 Serial.print("Scan type :");
 Serial.println(JpegDec.scanType);
 Serial.print("MCU width :");
 Serial.println(JpegDec.MCUWidth);
 Serial.print("MCU height:");
 Serial.println(JpegDec.MCUHeight);
 Serial.println("");
 
 sprintf(str,"#SIZE,%d,%d",JpegDec.width,JpegDec.height);
 Serial.println(str);

 // Raw Image Data
 while(JpegDec.read()){
   pImg = JpegDec.pImage ;

   for(by=0; by<JpegDec.MCUHeight; by++){
     for(bx=0; bx<JpegDec.MCUWidth; bx++){
       
       x = JpegDec.MCUx * JpegDec.MCUWidth + bx;
       y = JpegDec.MCUy * JpegDec.MCUHeight + by;
       
       if(x<JpegDec.width && y<JpegDec.height){
         if(JpegDec.comps == 1){ // Grayscale          
           tft.drawPixel(x, y, tft.Color565(pImg[0], pImg[0], pImg[0]));
         }else{ // RGB
           tft.drawPixel(x, y, tft.Color565(pImg[0], pImg[1], pImg[2]));
         }
       }
       
       pImg += JpegDec.comps ;
     }
   }
 }
}
   
void loop() {
}

posted by boochow at 11:32| Comment(0) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする

2015年10月10日

ESP8266のフラッシュメモリをファイルシステムとして使用する(2)

esp826607.jpg

前回の続きです。

SPIFFS(SPI Flash File System)をArduinoからファイルシステムとして使えるようになりましたので、BMPファイルを格納して、そのファイルを以前も使用したTFTカラーLCDに表示させてみます。

このLCDのドライバとしてはAdafruit ST7735 Libraryを使用していますが、スケッチ例として「spitftbitmap」という、SDカードからBMPファイルを読み出して表示するスケッチが付属しています。

このスケッチに含まれるBMP画像描画用の関数は、ちょっと改変するだけで、SPIFFSで利用することが可能です。

スケッチのメイン部分は以下のようになります。

#include <FS.h>
#include <SPI.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library

#define TFT_CS     15
#define TFT_RST    5
#define TFT_DC     4

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);

void setup() {
 // put your setup code here, to run once:
 Serial.begin(115200);
 Serial.println("");
 delay(10);
 
 tft.initR(INITR_BLUETAB);
 tft.fillScreen(ST7735_BLACK);

 SPIFFS.begin();
 bmpDraw("/test1.bmp", 0,0);
}

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

}



TFT液晶関連の結線やソースコードの修正は、以前の記事で書いたとおりですので説明は省略します。
  SPIFFS.begin();
 bmpDraw("/test1.bmp", 0,0);

でSPIFFS上の「test1.bmp」をLCDに表示させています。

bmpDraw関数は、上で書いたST7735 Libraryのサンプルスケッチに含まれる関数です。
サンプルスケッチ「spitftbitmap.ino」からloop{}よりも後の部分(「#define BUFFPIXEL 20」という行以降)をコピーして、さきほどのスケッチの後に貼り付けます。

そして、以下の2箇所を修正します。

修正前: if ((bmpFile = SD.open(filename)) == NULL) {
修正後: if (!(bmpFile = SPIFFS.open(filename,"r"))) {

修正前: bmpFile.seek(pos);
修正後: bmpFile.seek(pos,SeekSet);


以上で、SPIFFS上のビットマップファイルをLCDに表示できました。
posted by boochow at 16:18| Comment(0) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする

2015年10月04日

ESP8266のフラッシュメモリをファイルシステムとして使用する

ESP8266はSPI経由でフラッシュメモリが接続されています。
容量は、国内で使用可能なWROOM-02の場合は4MBです。

フラッシュメモリの空きスペースは、ストレージとして、プログラムで使用するデータを置いておくことができます。
通常のAVRベースのArduinoでは、外部ストレージとしてSDカードを使用するのが常道ですが、ESP8266の場合は外付けハードウェアを使わなくても、モジュール単体で3MB程度のデータを保持できます。

ESP8266用のArduino環境では、SPIFFS(SPI Flash File System)を利用して、フラッシュメモリ上でファイルシステムを使うことができます。

公式の解説は以下にあります。

Arduino/reference.md at esp8266 ・ esp8266/Arduino

今回はこの機能を使って、フラッシュ上に置いたBMPファイルをTFT LCDに表示させてみます。

そのためには、以下の準備が必要になります。

(1)Arduino IDE for ESP8266をstable版からstaging版へ移行
SPIFFSは現時点(2015/10/4)ではstable版に組み込まれておらず、利用するにはstaging版を使う必要があります。

(2)データアップロードツールのインストール
Windows上のファイルをESP8266のフラッシュメモリへ転送するためのArduino IDE用ツールが必要です。


それでは、まず(1)のstaging版への移行です。
これは、手順は以前にも紹介した以下の記事の通りです。

技適済み格安高性能Wi-FiモジュールESP8266をArduinoIDEを使ってIoT開発する為の環境準備を10分でやる方法 - Qiita

ただし、IDEの環境設定では「Staging version」のURLを入力します。
そして、「ツール」→「ボード」→「Boards Manager...」から「esp8266 by ESP8266 Community」を選択し、Installボタンを押してインストールします。

なお、Stable版とStaging版は共存せず、上記の操作でStable版はStaging版で上書きされるようです。

インストールが終わると、ボード選択情報がリセットされてしまいますので、下図のように再度ボードの情報を指定し直します。

esp826606-02a.png


上記では「Flash Size:」で「1M(128K SPIFFS)」を選択しています。
ESP8266は4MBのフラッシュを積んでいるので最大で「4M(3M SPIFFS)」まで利用できますが、このあと説明するアップロードツールでは、実際のファイルサイズとは関係なく、ここで指定したサイズを転送することになります。
3MBをシリアルポートで送信すると数分間はかかりますので、必要最低限のサイズを指定しておくほうが待ち時間が少なくて済みます。

次に(2)データアップロードツールのインストールです。
ツールのURLは、冒頭に挙げた公式の解説ページに記載されています。現時点では

http://arduino.esp8266.com/ESP8266FS-1.6.5-1105-g98d2458.zip

になっています。

まず、ドキュメントフォルダ内のArduinoフォルダに、新しく「tools」というフォルダを作って下さい。

esp826606-01.png


次に、上記のURLからダウンロードしたzipファイルを解凍し、解凍してできたフォルダをtoolsフォルダの中へコピーします。

これで、Arduino IDEを再起動すると、ツールメニューの中に「ESP8266 Sketch Data Upload」という項目が新しく追加されているはずです。

esp826606-02b.png


これで準備が整いましたので、まずは動作確認してみます。

以下のようなスケッチを用意します。
プログラムの中身は、SPIFFSのルートディレクトリにあるファイルのファイル名とファイルサイズを出力するものです。


#include <FS.h>

void setup() {
 // put your setup code here, to run once:
 Serial.begin(115200);
 Serial.println("");
 
 SPIFFS.begin();
 Dir dir = SPIFFS.openDir("/");
 while (dir.next()) {
   Serial.print(dir.fileName());
   File f = dir.openFile("r");
   Serial.println(String(" ") + f.size());
 }
}

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

}



これを通常の手順に従ってESP8266へ書き込みます。

次に、SPIFFSに書き込むファイルを用意します。

まず、上記のスケッチのフォルダ(IDEのメニューの「スケッチ」→「スケッチのフォルダを表示」で表示されるフォルダ)に「data」というフォルダを作成します。

esp826606-03.png


そして、dataフォルダの中に、SPIFFSに入れたいファイルをコピーします。
ESP8266を書き込みモードにしてから、IDEの「ツール」→「ESP8266 Sketch Data Upload」を選択すると、dataフォルダの中身がESP8266のフラッシュへ転送されます。

このとき、シリアルモニタは閉じてください。シリアルモニタが動いているとアップロードツールは動作しません。
また、アップロードツールは、ESP8266のブートローダがStaging版IDEのものになっていないと動作しませんので、Staging版IDEでコンパイルしたスケッチを少なくとも1度書き込んだ後で使用してください。

正常に転送できれば、dataフォルダに入れたファイルのファイル名とファイルサイズがシリアルポートへ出力されるはずです。
posted by boochow at 11:44| Comment(4) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする

2015年09月13日

ESP8266 SDKのJSON APIを使ってみた

前回はオープンソースのJSONライブラリについて紹介しましたが、本家のESP8266 SDKにも、JSONライブラリが入っています。

今回は前回の続きということでこのライブラリを紹介しますが、最初に結論を書いておくと、このライブラリは空のオブジェクト({})をうまく扱えないバグがあります。
また、使いやすさという意味ではArduinoJsonやaJsonにやや劣ります。
その代わり、解析したいJSONデータに合わせてプログラムコードをチューニングすることも可能です。
実際に使用する場合は、SDKのライブラリをリンクするよりも、大元のソースコードをダウンロードしたほうがデバッグしやすいと思います。

前回と同じテストデータを使った場合の星取表は下のようになります。

TEST1TEST2TEST3TEST4
ArduinoJsonOKOKNGNG
aJsonOKNGOKOK
ESP8266 SDK APIOKNGOKOK


このライブラリのAPIの解説はSDKに付属しているプログラミングガイドの中にあります。
現時点でのファイル名は「2C-ESP8266__SDK__Programming Guide__EN_v1.3.0.pdf」となっています。
このガイドの5.2節がJSON関連APIの解説になっています。
ただ、ガイドではAPIそのものが簡単に解説されているだけで、あまり親切ではありません。

このSDKのライブラリとインクルードファイルはArduino IDEの中にも含まれています。
JSON関連のインクルードファイルが入っているフォルダは

%USERPROFILE%\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\tools\sdk\include\json

です。
ヘッダファイルのコメントを見ると、最後のほうに
This file is part of the Contiki operating system.

とあります。
つまり、このライブラリは「Contiki」という別のプロジェクトから持ってきたものらしいことが分かります。

探してみると、このライブラリのオリジナルは

contiki/apps/json at master ・ contiki-os/contiki

であるようです。ソースコードも公開されています。


SDKのプログラミングガイドの解説だけでは、どうも内容が分かりにくかったのですが、このソースコードを眺めるとライブラリの使い方が分かってきました。
APIにはJSONの解析と生成の両方が含まれていますが、関心は解析のほうにありますので、解析側のAPIのみ使ってみます。


まず、先にソースコードを掲載しておきます。

#include <limits.h>
#include <errno.h>
#define JSONPARSE_CONF_MAX_DEPTH 50
#ifdef ESP8266
extern "C" {
#include "json/jsonparse.h"
}
#endif
#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_sdk_json() {
 char json[] = JSON_TEST_DATA;
 jsonparse_state state;
 int c;
 int valueType;

 jsonparse_setup(&state, json, strlen(json));
 while((c = jsonparse_next(&state)) != JSON_TYPE_ERROR) {
   char token[256];
   long value;
   
   switch(c) {
     case JSON_TYPE_ARRAY:
     case JSON_TYPE_OBJECT:
     case JSON_TYPE_PAIR:
       Serial.print(char(c));
       break;
     case JSON_TYPE_PAIR_NAME:
     case JSON_TYPE_STRING:
       valueType = jsonparse_copy_value(&state, token, 255);
       Serial.print(String('"') + token + '"');
       break;
     case JSON_TYPE_INT:
     case JSON_TYPE_NUMBER:
       value = jsonparse_get_value_as_long(&state);
       Serial.print(value, DEC);
       break;
     case JSON_TYPE_NULL:
       Serial.print("null");
       break;
     case JSON_TYPE_TRUE:
       Serial.print("true");
       break;
     case JSON_TYPE_FALSE:
       Serial.print("false");
       break;
     default:
       Serial.print(char(c));
   }
 }
 if (c == JSON_TYPE_ERROR) {
   String errStr;

   Serial.println();
   switch(state.error) {
     case JSON_ERROR_OK: errStr="OK"; break;
     case JSON_ERROR_SYNTAX: errStr="Syntax Error"; break;
     case JSON_ERROR_UNEXPECTED_ARRAY: errStr="Unexpected array"; break;
     case JSON_ERROR_UNEXPECTED_END_OF_ARRAY: errStr="Unexpected end of array"; break;
     case JSON_ERROR_UNEXPECTED_OBJECT: errStr="Unexpected object"; break;
     case JSON_ERROR_UNEXPECTED_STRING: errStr="Unexpected string"; break;
   }
   Serial.println(errStr);

   if (state.depth < JSONPARSE_MAX_DEPTH) {
     // dump json stack
     int i;
     for(i = 0; i < state.depth; i++) {
       Serial.print(state.stack[i]);
     }
     Serial.println();
  } else {
     Serial.println("JSON too deep");
   }
 }
}

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

 Serial.println("\n\ntesting SdK json API\n");
 test_sdk_json();
}

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

aJsonやArduinoJsonでは、最初にJSON文字列を渡して一気に全体をパースしていました。
一方、このSDKのライブラリでは、文字列を少しずつ読み進めていくループを自分で書く必要があります。

最初の
jsonparse_setup(&state, json, strlen(json));

は変数の初期値を設定するだけで、そのあと
c = jsonparse_next(&state)

を呼ぶたびに、新しいデータを読み込みます。

このとき、空白はまとめて読み飛ばされ、文字列や数値など文字に分解できない「アトム」はまとめて読み込まれます。
自分のプログラムで行いたい処理は、このwhileループの中で行うことになります。

"{"と"}"のような対応する入れ子構造はパーサがチェックし、文法ミスがあればエラーを返します。

また、このライブラリで扱えるデータの入れ子構造の最大値は、デフォルトでは10段です。
TEST3で使うデータはもう少し階層が深いので、
#define JSONPARSE_CONF_MAX_DEPTH 50

で最大を50にしています。


なお、これはESP8266用Arduinoの不備だと思われますが、上記のスケッチをコンパイルすると「strtoulが無い」というエラーが出ます。
これについては、以下のやり取りが参考になります。

cstdlib function strtoul not supported ・ Issue #608 ・ esp8266/Arduino

要は、ESP8266用Arduinoのlibcにstrtoulが入ってなかったということのようです。
今回は、とりあえず以下からstrtoul()関数を丸ごとコピーしてスケッチの末尾へ貼り付けました。

Arduino/libc_replacements.c at f73457de0d6b703b96a809e48b2163f16aa367e8 ・ kzyapkov/Arduino

また、strtoulを正しくコンパイルするために、

#include <limits.h>
#include <errno.h>
の2つのファイルをインクルードしています。


さらに、ESP8266用Arduinoの標準ではSDKのJSONライブラリをリンクしてくれませんので、これについても修正が必要です。

修正は、
%USERPROFILE%\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0

のフォルダの中の
platform.txt

の中の下記の部分を追記しました。(上に掲載したスケッチからは省略しています。)
compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig -lwps -lcrypto -ljson

(これが正しいやり方なのかどうかは分かりません。)
この修正を有効にするにはIDEの再起動が必要です。
posted by boochow at 22:34| Comment(0) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする

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つのパーサで解析できるか試してみました。
その結果をまとめると、以下のような星取り表になります。

TEST1TEST2TEST3TEST4
ArduinoJsonOKOKNGNG
aJsonOKNGOKOK


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

になります。
posted by boochow at 17:12| Comment(0) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする
人気記事