PR 記事には広告が含まれています
スポンサーリンク
Translate

ESP32 Arduinoで Ambientからデータを取得して得られたJSONをパースして値を抽出する方法

スポンサーリンク

スポンサーリンク

Ambientからデータを取得する

Ambientは、ネットワークにつながったセンサ端末からの情報を受けとり、グラフ化してくれるクラウドサービスです。

見守りをするため、M5StickCでベッドの重量を測定し、Ambientに送信するハードとソフトを作りました。

次のステップに進むために、逆にAmbientにあるデータを端末側から参照したくなったので、Arduinoでプログラムを作ってみました。

仕組み

ambientからデータを取得するには、次のURLをambientのサーバに送ります。するとデータがJSON形式で返ってきます。

http://ambidata.io/api/v2/channels/チャネルID/data?&readKey=リードキー&n=行数

「チャネルID」と「リードキー」はMyチャネルのページで確認できます。

行数は1以上の数字を指定します。1を指定すると直近のデータが1セット、nを指定すると直近から過去へn番目までデータ、nセット分が返ってきます。

ちなみに、上記のURLをブラウザで開くと、データが返ってくることが事前にわかります。

上記はn=1とした場合の結果です。直近のデータが1つ表示されます。

n=2にすると、以下のように2セットデータが返ってきます。

さて、仕組みがわかったところで、これをコードにします。

データを取得するプログラム

...
#include <HTTPClient.h>
const unsigned int channelId = xxxxx; // AmbientのチャネルID
const char* readKey = "xxxxxxxxxxxxx"; // リードキー
...

void setup() {
  ...
  Serial.begin(115200);
  ...
  // ...WiFiに接続する...

}

void loop() {
  ...
  String response = readFromAmbient( channelId, readKey, 1 );
  delay(10000);
  ...
}

//Ambientからデータを受信する
String readFromAmbient( unsigned int channelId, const char* readKey, int n )
{
  const String host ="ambidata.io";

  String url = "http://";
  url += host;
  url += "/api/v2/channels/";
  url += channelId;
  url += "/data?&readKey=";
  url += readKey;
  url += "&n=";
  url += n;
  Serial.print("Requesting URL ");
  Serial.println(url);

  HTTPClient httpClient;
  httpClient.begin(url);
  int httpCode = httpClient.GET();
  String httpResponse = httpClient.getString();
  httpClient.end();

  Serial.printf("httpCode:%d\n",httpCode);
  Serial.println(httpResponse);

  return httpResponse;
}

上記は、必要な部分を抜き出したコードです。これの他に、WiFiにつなぐコードが必要です。

Ambientのサーバからデータを受信するための、readFromAmbient()という関数を作りました。チャンネルIDとリードキー、行数nを指定すると、JSON形式のStringが得られます。

スポンサーリンク

M5StickCで受信してみる

サンプルプログラム

先ほどのコードを、M5SticCで動くようプログラムしました。こちら↓↓がそのプログラムです。

m5stick_readDataFromAmbient

//Wifi
const char* WifiSSID = "SSID"; //アクセスポイントのSSID
const char* WifiPassword = "POSSWORD"; //アクセスポイントのパスワード
WiFiClient client;

//Ambient
unsigned int channelId = CHANNEL_ID; // AmbientのチャネルID
const char* writeKey = "WRITE_KEY"; // ライトキー
const char* readKey = "READ_KEY"; // リードキー
Ambient ambient;

上記の部分の、WifiSSID、WifiPasswordに、ご自宅のWiFiのSSIDとパスワードを指定し、channelId、writeKey、readKeyはAmbientのそれぞれのID、キーを指定します。

コンパイルしてM5StickCに書き込むと、プログラムが実行されます。Aボタンを押すと、Ambientからデータを受信し、ボタンBを押すと、Ambientに予め設定されているValue1,2,3のデータが送信されるようになっています。

実行結果

WiFiに接続された後に、Aボタンを押すとシリアルモニタに結果が表示されます。

[{"d1":1,"d2":2,"d3":10,"created":"2019-10-09T04:52:08.689Z"}]

n=1としたので、1行分のデータが返ってきました。

M5Stickの画面にも、シリアルで出力したデータが表示されます。

スポンサーリンク

ArduinoJSONでパース

Ambientからデータを受信できるようになりました。この結果をArduinoJSONを使ってパースして、パラメータを取り出してみたいと思います。

ArduinoJSONは、ライブラリマネージャで検索すると出てきます。これをインストールしておきます。

私が使ったのは現時点で最新のバージョン6.12.0です。

先ほどのコードに、ArduinoJSONでパースして、値を取り出すコードを追加します。

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

void setup() {
  ...
}

void loop() {
  ...
  //Aボタンを押されたら
  ...
    String response = readFromAmbient( channelId, readKey, 1 );
  
    //jsonドキュメントの作成 make JSON document
    const size_t capacity = 500;
    DynamicJsonDocument doc(capacity);
    DeserializationError err = deserializeJson(doc, response);
    Serial.printf("DeserializationError:%s\n",err.c_str());
  
    //抽出
    int value[3] = { 0, 0 ,0 };
    value[0] = doc[0]["d1"];
    value[1] = doc[0]["d2"];
    value[2] = doc[0]["d3"];
  
    //結果を出力
    Serial.printf("Result:%d, %d, %d\n",value[0],value[1],value[2]);
    M5.Lcd.print("Value1:"); M5.Lcd.println(value[0]);
    M5.Lcd.print("Value2:"); M5.Lcd.println(value[1]);
    M5.Lcd.print("Value3:"); M5.Lcd.println(value[2]);    
  ...
}

JSONドキュメントを作るときのcapacityは、ArduinoJson Assistantに受信したJSONのデータ列をペーストして、計算された容量を使用します。

今回はn=2の受信結果で244だったので、さらに余裕をみて500にしてみました。

M5Stickで実行してみましょう。

Value1:1
Value2:2
Value10:10

と、JSONフォーマットから正しく値が抽出できています。

プログラムはこちらm5stick_readDataFromAmbient2にあります。

スポンサーリンク

まとめ

M5StickCでAmbientからデータを取得できるようになりました。取得したJSONフォーマットから、データを抽出できるようになりました。

これで、センサ端末からでもデータにアクセスできるようになりました。

つづく

2019.10.10 追加 つづきはこちらです↓↓

追加終わり