ArduinoとGrove Beginner KitでMachinechatのJEDIシリアルデータコレクタを使用する

概要

MachinechatのJEDI v3.0ソフトウェアリリースに伴い、シリアルデータコレクタが追加されました。シリアルデータコレクタは、JEDIが稼働しているマシンのシリアルインターフェースを介して、CSV(comma separated values)形式のデータをJEDIに送信することができます。このプロジェクトでは、ArduinoとSeeedのGrove Beginner Kitを使用し、シリアルデータコレクタを利用してJEDI Proにセンサデータを送信するデモを行います。シリアルデータコレクタのフォーマット要件、JEDIでのコレクタセットアップ、およびデバッグ機能について説明します。Ubuntuが動作するSeeedのミニPC Odyssey Blueに、MachinechatのIoTプラットフォームJEDI Proがインストールされています。

ハードウェア

ソフトウェア

  • JEDI Pro or JEDI Pro SSE
    IoTデータの収集、可視化、モニタリング、データストレージのための適応型ソフトウェアで、IoTソリューションに組み込むことができます。
       ・センサ、デバイス、マシンからのデータ収集
       ・直感的なリアルタイムおよび履歴データ、システムビューダッシュボードの構築
       ・データ状態を自動的に監視し対応するためのルール作成
       ・メールやSMSによるアラート通知の受信
    などの機能を備えています。
    JEDI Pro SSEは、JEDI ProにSeeedのSenseCAP LoRaWANセンサ用のData Collectorを追加したSeeed Studio Editionバージョンです。
  • Arduino
    Arduinoは、使いやすいハードウェアとソフトウェアをベースにしたオープンソースの電子機器プラットフォームです。

シリアルデータコレクタの詳細

シリアルデータコレクタは、繰り返し送信されるシリアルメッセージで最大15個のデータフィールドを受信することができます。各データフィールドはコンマで区切る必要があり、数値、文字列、ブール値、またはブランク(そのメッセージではヌルまたは「値なし」)を含むことができます。シリアルメッセージのレコードデリミタを設定する必要があり、「New Line」または「Carriage Return」に設定することができます。メッセージのデータフィールド数は、データコレクタで設定されたフィールド数と一致する必要があります。シリアルメッセージ内のデータの位置は、データコレクタの構成でフィールドに関連付けられた番号に対応します。
例えば、シリアルデータのメッセージには、「light(光)」、「sound(音)」、「temperature(温度)」の値が含まれることがあります。メッセージは以下のようなものになります。

124,33,72.1

値124を「光」、33を「音」、72.1を「温度」に関連付けるには、対応する3つのデータコレクタのフィールドを次の例のように設定する必要があります。

image

JEDIシリアルデータコレクタのセットアップは、5つのステップで構成されます。
1 - モニタするシリアルポートを選択します。
2 - データストリームの一意のTargetID名を選択します。
3 - シリアルポートのパラメータ(ボーレート、ストップビット、データビット、およびパリティ)を設定します。
4 - レコードデリミタを設定します。
5 - CSVフィールドを追加します。
オプションで、タイムスタンプが存在する場合はシリアルデータから抽出することができますが、デフォルトではデータが入力された時点でスタンプが押されます。

シリアルデータコレクタをデバッグします。
シリアルデータの取り込みや表示に問題がある場合、デバッガを有効にしてログファイルを作成することができます。シリアルデータコレクタの設定画面の左下に「Enable Debug」スライダがあります。有効にすると、コレクタが動作しているときに発生したアクティビティとエラーをキャプチャします。このキャプチャの出力は、JEDIがインストールされている「debug/datacollectors」サブディレクトリの「debug.log」ファイルで確認できます。

シリアルデータコレクタの詳しい情報は、Machinechatの記事Using the Serial Data Collectorに記載されています。

実装

Grove Beginner Kit上で動作するArduinoアプリケーションは、搭載された5つのセンサ(光、音、温度/湿度、圧力、加速度)を読み取り、センサデータをOLED(有機EL)ディスプレイに表示し、シリアルインターフェースを介してセンサデータをシリアルデータコレクタ専用のフォーマットでJEDIが動作するOdyssey Blue Mini-PCに送信します。Arduinoのコードは、Grove Beginner Kitのサンプルコードを修正したもので、10秒ごとに各センサをループして繰り返します。ハードウェアの実装は簡単で、Odyssey BlueとGrove Beginner Kitの間にUSBケーブルを接続するだけです。下図はその接続を示したものです(Scheme-itのOdysseyGrove Project and BOMを参照)。

SeeedのGrove Beginner Kitのセットアップ

1 - Grove Beginner Kit上で Arduino をセットアップします。Grove Beginner Kit for Arduinoのリンクを参照してください。 Arduino IDEで「Board」を選択する際に「Arduino Uno」を選択します。

2 - アプリケーションに必要なライブラリをインストールします。 Arduino のLibrary Managerを通じてこれらのライブラリを追加します。

3 - コードのウォークスルー(ファイル名:UNO_GroveBeginnerKitJediProSerialLoop.ino)

初期設定

//
// Seeed Grove Beginner Kit for Arduino - default code
// Modified to send CSV information over serial (USB) port
// For use as input to Machinechat JEDI software
// v0.1 DRM 07-04-2022
//
// CSV is as follows: "Light, Sound, Temoperature, Humidity, Air Pressure,
// Acceleration X, Acceleration Y, Acceleration Z"
//
// Only one parameter is sent at a time based on selection displayed on OLED
// Display
// SBR modification to remove selection capability and just loop thru the sensors send & display data on OLED
//
#include <U8g2lib.h>
#include <Wire.h>
//#include <MsTimer2.h>
#include "DHT.h" 
#include "Seeed_BMP280.h"
#include "LIS3DHTR.h"
#include "millisDelay.h" //part of SafeString library for non-blocking timer use
#define WIRE Wire
millisDelay loopDelay;
//20*20
const unsigned char sound_bmp[] U8X8_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x80, 0x3f, 0x0c, 0xc0, 0x3b, 0x0c, 0xfe, 0xb8, 0x0d, 0x7f, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0xff, 0xb8, 0x0d, 0xc0, 0x39, 0x0c, 0x80, 0x3f, 0x0c, 0x00, 0x3e, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00};
//20*30
const unsigned char temp_bmp[] U8X8_PROGMEM = {0x00, 0x06, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x80, 0x19, 0x00, 0x80, 0x19, 0x00, 0xc0, 0x39, 0x00, 0xc0, 0x39, 0x00, 0xc0, 0x39, 0x00, 0xc0, 0x39, 0x00, 0xc0, 0x3f, 0x00, 0x80, 0x1f, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x06, 0x00};
//20*20
const unsigned char hum_bmp[] U8X8_PROGMEM= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x40,0x20,0x00,0x20,0x40,0x00,0x20,0x40,0x00,0x10,0x80,0x00,0x10,0x80,0x00,0x08,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x01,0x10,0x80,0x00,0x00,0x00,0x00,0x40,0x20,0x00,0x80,0x10,0x00};
//20*20
const unsigned char pressure_bmp1[] U8X8_PROGMEM= {0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x80,0x96,0x01,0x80,0x1f,0x03,0x00,0x0f,0x06,0x18,0x06,0x04,0x1c,0x04,0x04,0x06,0x00,0x06,0xc6,0xff,0x03,0xc6,0xff,0x01,0x04,0x00,0x00,0xfc,0xff,0x03,0xf8,0xff,0x03,0x00,0x00,0x00,0xfe,0xff,0x07,0xfe,0xff,0x07,0x00,0x00,0x00};
//30*30
const unsigned char pressure_bmp[] U8X8_PROGMEM= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc8,0xc4,0x01,0x00,0xf8,0x87,0x07,0x00,0xf8,0x87,0x07,0x60,0xf0,0x03,0x04,0x60,0xf0,0x03,0x04,0xf0,0xc0,0x00,0x04,0xf0,0xc0,0x00,0x04,0x18,0x00,0x00,0x06,0x18,0x00,0x00,0x06,0x08,0xfc,0xff,0x03,0x08,0xfc,0xff,0x03,0x18,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0xf0,0xff,0xff,0x03,0xf0,0xff,0xff,0x03,0xe0,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x1f,0xfe,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
//30*30
const unsigned char light_tmp[] U8X8_PROGMEM = {0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x80, 0xc1, 0x60, 0x00, 0x80, 0xc3, 0x70, 0x00, 0x00, 0xc3, 0x30, 0x00, 0x00, 0xc7, 0x38, 0x00, 0x00, 0x06, 0x18, 0x00, 0x0c, 0xf0, 0x03, 0x0c, 0x3c, 0xfc, 0x0f, 0x0f, 0x78, 0x1e, 0x9e, 0x07, 0x60, 0x07, 0xb8, 0x01, 0x00, 0x03, 0x30, 0x00, 0x80, 0x03, 0x70, 0x00, 0x80, 0x01, 0x60, 0x00, 0xbf, 0x01, 0x60, 0x3f, 0xbf, 0x01, 0x60, 0x3f, 0x80, 0x01, 0x60, 0x00, 0x80, 0x03, 0x70, 0x00, 0x00, 0x03, 0x30, 0x00, 0x60, 0x07, 0xb8, 0x01, 0x78, 0x1e, 0x9e, 0x07, 0x3c, 0xfc, 0x0f, 0x0f, 0x0c, 0xf0, 0x03, 0x0c, 0x00, 0x06, 0x18, 0x00, 0x00, 0xc7, 0x38, 0x00, 0x00, 0xc3, 0x30, 0x00, 0x80, 0xc3, 0x70, 0x00, 0x80, 0xc1, 0x60, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00};
//30*30
const unsigned char sound_bmp1[] U8X8_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x60, 0x00, 0x00, 0x70, 0xc0, 0x00, 0x00, 0x48, 0x80, 0x01, 0x00, 0x4c, 0x18, 0x03, 0x00, 0x46, 0x30, 0x02, 0x00, 0x43, 0x60, 0x04, 0x80, 0x41, 0x43, 0x04, 0xfc, 0x40, 0x84, 0x08, 0x46, 0x40, 0x8c, 0x08, 0x46, 0x40, 0x88, 0x08, 0x46, 0x40, 0x10, 0x09, 0x06, 0x40, 0x10, 0x09, 0x06, 0x40, 0x10, 0x19, 0x06, 0x40, 0x10, 0x09, 0x06, 0x40, 0x10, 0x09, 0x46, 0x40, 0x18, 0x09, 0x46, 0x40, 0x88, 0x08, 0x46, 0x40, 0x8c, 0x08, 0xfc, 0x40, 0x86, 0x0c, 0x80, 0x41, 0x43, 0x04, 0x00, 0x43, 0x20, 0x04, 0x00, 0x42, 0x30, 0x02, 0x00, 0x44, 0x0c, 0x03, 0x00, 0x48, 0x80, 0x01, 0x00, 0x50, 0xc0, 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//30*30
const unsigned char acel_bmp[] U8X8_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x80, 0x01, 0x60, 0x00, 0x60, 0x00, 0x80, 0x00, 0x30, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x04, 0x04, 0x20, 0x01, 0x08, 0x04, 0x10, 0x02, 0x08, 0x02, 0xf8, 0x03, 0x08, 0x02, 0x0c, 0x0e, 0x10, 0x02, 0x0a, 0x10, 0x10, 0x02, 0x0a, 0x10, 0x10, 0x02, 0x02, 0x0a, 0x10, 0x02, 0x18, 0x06, 0x18, 0x06, 0x10, 0x02, 0x08, 0x04, 0x20, 0x01, 0x08, 0x04, 0xc0, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x04, 0x18, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x03, 0x60, 0x00, 0x80, 0x01, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//30*30
const unsigned char temp_bmp1[] U8X8_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x1f, 0x8f, 0xff, 0xff, 0x3f, 0x0f, 0x00, 0x00, 0x3e, 0x0f, 0x00, 0x00, 0x3e, 0x8f, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0xff, 0x07, 0xfc, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

#define BoardVersion 2

#if BoardVersion == 1
char led = 5;
char buzzer = 6;
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R2, /* reset=*/U8X8_PIN_NONE);
char button = 2;
char rotary = A1;
char light = A2;
char sound = A0;
DHT dht(4,DHT11);
BMP280 bmp280; 
// LIS3DHTR<TwoWire> accelemeter(I2C_MODE);
LIS3DHTR<TwoWire> accelemeter; //IIC

#elif BoardVersion == 2
char led = 4;
char buzzer = 5;
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R2, /* reset=*/U8X8_PIN_NONE);
char button = 6;
char rotary = A0;
char light = A6;
char sound = A2;
DHT dht(3,DHT11);
BMP280 bmp280; 
//LIS3DHTR<TwoWire> accelemeter(I2C_MODE);
LIS3DHTR<TwoWire> accelemeter; //IIC
#endif

#define CLICKS 100
int BuzzerFrequency = 300;
char MODE = 1;
char LongPress = false;
int x = 50, y = 13;
char PressCounter = 0;
char BlinkEnable = true;
#define BLINK 10
#define SQueueLEN 10
int SQueue[SQueueLEN] = {0};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  if(!bmp280.init()){
    Serial.println("bmp280 init error!");
  }
  //accelemeter.begin(Wire);
  accelemeter.begin(WIRE, LIS3DHTR_ADDRESS_UPDATED); //IIC init
  delay(100);
  //accelemeter.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
  accelemeter.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);

  if (!accelemeter) {
      Serial.println("LIS3DHTR didn't connect.");
  }
  for (int Index = 0 ; Index < SQueueLEN ; Index ++)
  {
    SQueue[Index] = analogRead(sound);
  }
  u8g2.begin();

  //SBR mod
  MODE = 1;
  loopDelay.start(10000);  // start a 10sec delay
}

メインループ - センササブルーチンを呼び出し、センサの読み取り、OLEDへのセンサデータの表示、およびシリアルインターフェースでのデータ送信を行います。

void loop() {
  if (loopDelay.justFinished()) {
    MODE = MODE + 1; // increment mode
    loopDelay.start(10000);  // start a 10sec delay
  }

  //reset mode loop
  if (MODE == 6) {
    MODE = 1;
  }

   if (MODE == 1) {
    Light_show();
  } else if (MODE == 2) {
    Sound_show();
  } else if (MODE == 3) {
    Temp_show();
  } else if (MODE == 4) {
    Pressure_show();
  } else if (MODE == 5) {
    Acele_show();
  }
}

光、音、温湿度、圧力、および加速度の各センサ用のセンササブルーチン(センサの読み込み、センサデータをシリアルメッセージで特定の位置に送信、およびキットのオンボードOLEDディスプレイにセンサデータを表示)

void Light_show()
{
  int l = analogRead(light);
  Serial.println(String(l) + ",,,,,,,");
  Serial.flush();
  delay(500);
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_t0_16b_mr);
    u8g2.drawCircle(8, 8, 8, U8G2_DRAW_ALL);
    if (l >= 50 && l < 100) {
      u8g2.drawDisc(8, 8, 8, U8G2_DRAW_UPPER_LEFT);
    }
    if (l >= 100 & l < 200) {
      u8g2.drawDisc(8, 8, 8,  U8G2_DRAW_UPPER_RIGHT | U8G2_DRAW_UPPER_LEFT);
    }
    if (l >= 200 && l < 350) {
      u8g2.drawDisc(8, 8, 8,  U8G2_DRAW_LOWER_LEFT | U8G2_DRAW_UPPER_RIGHT | U8G2_DRAW_UPPER_LEFT);
    }
    if (l >= 350) {
      u8g2.drawDisc(8, 8, 8,  U8G2_DRAW_ALL);
    }
    u8g2.setCursor(26, 32);
    u8g2.print(F("Light:"));
    u8g2.setCursor(80, 32);
    u8g2.print(l);
     //SBR mod
    u8g2.setCursor(0, 64);
    u8g2.print(F("JEDI Serial data"));

    
  } while (u8g2.nextPage());
}

int filter1(int NEW_DATA,int QUEUE[],char n)
{
    int max;
    int min;
    int sum;
    char i;
    QUEUE[0]=NEW_DATA;
    if (QUEUE[0] < 0)
    QUEUE[0] = 0;
    max=QUEUE[0];
    min=QUEUE[0];
    sum=QUEUE[0];
    for(i=n-1;i!=0;i--){
        if(QUEUE[i]>max)max=QUEUE[i];                  
        else if (QUEUE[i]<min)min=QUEUE[i];             
        sum=sum+QUEUE[i];                              
        QUEUE[i]=QUEUE[i-1];                            
    }

    i=n-2;
    sum=sum-max-min+i/2;
    sum=sum/i;                                     
                                                    
    return ((int)sum);
}       
void Sound_show()
{
  int s = analogRead(sound);
  s = filter1(s,SQueue,SQueueLEN);
  delay(500);
  Serial.println("," + String(s) + ",,,,,,");
  Serial.flush();
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_t0_16b_mr);
    u8g2.setCursor(28, 32);
    u8g2.print(F("Sound:"));
    u8g2.setCursor(76, 32);
    u8g2.drawXBMP(0, 0, 20, 20, sound_bmp);
    u8g2.print(s);
    //SBR mods
    u8g2.setCursor(0, 64);
    u8g2.print(F("JEDI Serial data"));
    
  } while (u8g2.nextPage());
}

void Temp_show()
{
  int tempC = 0, humid = 0;
  float tempF = 0.0;
  do{
  humid = dht.readHumidity();
  tempC = dht.readTemperature();
  tempF = (float(tempC) * 1.8) + 32.0F;
  } while ((humid == 0) && (tempC == 0)); 
  delay(500);
  Serial.println(",," + String(int(tempF)) + ",,,,,");
  Serial.flush();
  Serial.println(",,," + String(humid) + ",,,,");
  Serial.flush();
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_t0_16b_mr);
    u8g2.setCursor(32, 16);
    u8g2.print(F("Temp:"));
    u8g2.setCursor(72, 16);
    u8g2.print(int(tempF));
    u8g2.setCursor(88, 16);
    u8g2.print("F");
    u8g2.setCursor(32, 40);
    u8g2.print(F("Humid:"));
    u8g2.setCursor(80, 40);
    u8g2.print(humid);
    u8g2.drawXBMP(0, 0, 20, 30, temp_bmp);
    u8g2.setCursor(0, 64);
    u8g2.print(F("JEDI Serial data")); 
  } while (u8g2.nextPage());
}

void Pressure_show()
{
  float pressure = (bmp280.getPressure() * 0.000295300586F);
  delay(500);
  Serial.println(",,,," + String(pressure, 2) + ",,,");
  Serial.flush();
  u8g2.setFont(u8g2_font_t0_16b_mr);
  u8g2.firstPage();
  do {
      u8g2.setCursor(76, 32);
      u8g2.drawXBMP(0, 0, 20, 20, pressure_bmp1);
      u8g2.setCursor(30, 25);
      u8g2.print("Pressure:"); 
      u8g2.setCursor(30, 40);
      u8g2.print(pressure);
      u8g2.print("inHg");
      u8g2.setCursor(0, 64);
      u8g2.print(F("JEDI Serial data"));       
    } while (u8g2.nextPage());
}

void Acele_show()
{
  float ax, ay, az;
  ax = accelemeter.getAccelerationX();
  ay = -accelemeter.getAccelerationY();
  az = accelemeter.getAccelerationZ();
  delay(500);
  Serial.println(",,,,," + String(ax, 2) + ",,");
  Serial.flush();
  Serial.println(",,,,,," + String(ay, 2) + ",");
  Serial.flush();
  Serial.println(",,,,,,," + String(az, 2));
  Serial.flush();
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_t0_16b_mr);
    u8g2.setCursor(0, 16);
    u8g2.print(F("Accel:")); 
    u8g2.setFont(u8g2_font_t0_12b_mr);   
    u8g2.setCursor(55, 16);
    u8g2.print(F("X:"));
    u8g2.setCursor(71, 16);
    u8g2.print(ax);
    u8g2.setCursor(55, 32);
    u8g2.print(F("Y:"));
    u8g2.setCursor(71, 32);
    u8g2.print(ay);
    u8g2.setCursor(55, 48);
    u8g2.print(F("Z:"));
    u8g2.setCursor(71, 48);
    u8g2.print(az);
    u8g2.setFont(u8g2_font_t0_16b_mr);
    u8g2.setCursor(0, 64);
    u8g2.print(F("JEDI Serial data"));        
  } while (u8g2.nextPage());
}

UNO_GroveBeginnerKitJediProSerialLoop.inoアプリケーションの最新のソースコードは、以下のリンク先のgithubにあります。

JEDIシリアルデータコレクタとデータダッシュボードのセットアップ

JEDIで「Settings(設定)」タブを選択し、「Data Collectors(データコレクタ)」を選択し、「Add Collector(コレクタを追加)」を選択します。

Collectorを以下のように設定します。データコレクタの名前を「SerialGroveBeginner」(またはお好みのもの)、コレクタのタイプを「Serial」、シリアルポートをGrove Beginner Kitのシリアルポート(私の設定では/dev/ttyUSB0でした)、ターゲットIDを「GroveKit」(またはお好みのもの)、データ速度を「115200」、データビットを「8 Bit」、パリティは「No Parity」、レコードデリミタを「New Line」に選択します。以下の8つのセンサパラメータフィールド(Light、 Sound、Temperature、Humidity、Pressure、 AccelX、AccelY、AccelZ)のData Fieldsを追加します。

JEDI Proで「Data Dashboards」を選択し、「+」を選択して新しいチャートを追加します。

データチャートを設定し、「Add」を選択すると、データダッシュボードに表示されます(以下の例を参照)。

image

まとめ

MachinechatのJEDI IoTアプリケーションソフトウェア用シリアルデータコレクタは、開発ボード、プラットフォーム、またはCSV形式でシリアルデータを送信できるあらゆるデバイスから、センサやその他のタイプのデータを迅速かつ簡単に取り込む手段を提供します。JEDIソフトウェアが動作するハードウェアに接続されたUSB、RS-232、RS-485、その他のシリアルインターフェース機器から、CSV形式で送信されるデータであれば、どのようなものでも構いません。

参考資料




オリジナル・ソース(English)